Redraw map as separate system instead of in many places
This commit is contained in:
parent
a38cafc7b8
commit
ec5011a443
8 changed files with 108 additions and 158 deletions
|
@ -1,11 +1,7 @@
|
|||
#[cfg(feature = "render")]
|
||||
use {
|
||||
crate::{BiomeStats, TerrainCell, WorldOverlay, WorldRenderSettings, WorldView},
|
||||
bevy::{
|
||||
asset::Assets,
|
||||
render::render_resource::Extent3d,
|
||||
render::{color::Color, texture::Image},
|
||||
},
|
||||
bevy::render::color::Color,
|
||||
};
|
||||
use {
|
||||
crate::{World, WorldGenError},
|
||||
|
@ -124,12 +120,7 @@ impl WorldManager {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_world<P: AsRef<Path>>(
|
||||
&mut self,
|
||||
path: P,
|
||||
#[cfg(feature = "render")] render_settings: &WorldRenderSettings,
|
||||
#[cfg(feature = "render")] images: &mut Assets<Image>,
|
||||
) -> Result<(), LoadError> {
|
||||
pub fn load_world<P: AsRef<Path>>(&mut self, path: P) -> Result<(), LoadError> {
|
||||
let mut file = match File::open(path) {
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
|
@ -145,25 +136,7 @@ impl WorldManager {
|
|||
};
|
||||
match ron::from_str(buf.as_str()) {
|
||||
Ok(world) => {
|
||||
#[cfg(feature = "render")]
|
||||
let World { height, width, .. } = world;
|
||||
self.world = Some(world);
|
||||
#[cfg(feature = "render")]
|
||||
{
|
||||
let image_handle = &images.get_handle(
|
||||
render_settings
|
||||
.map_image_handle_id
|
||||
.expect("Missing image handle, even though world is present"),
|
||||
);
|
||||
images
|
||||
.get_mut(image_handle)
|
||||
.expect("Handle for missing image")
|
||||
.resize(Extent3d {
|
||||
width,
|
||||
height,
|
||||
depth_or_array_layers: 0,
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
Err(err) => Err(LoadError::InvalidSave(err)),
|
||||
|
|
|
@ -6,34 +6,4 @@ pub(crate) use window::*;
|
|||
pub(crate) mod widgets;
|
||||
pub(crate) mod windows;
|
||||
|
||||
use {
|
||||
crate::gui::{open_window, WidgetId, WidgetSystem},
|
||||
bevy::{
|
||||
asset::Assets,
|
||||
log::debug,
|
||||
render::{render_resource::Extent3d, texture::Image},
|
||||
},
|
||||
planet::{WorldManager, WorldRenderSettings},
|
||||
};
|
||||
|
||||
pub(crate) fn update_textures(
|
||||
world_manager: &WorldManager,
|
||||
render_settings: &WorldRenderSettings,
|
||||
images: &mut Assets<Image>,
|
||||
) {
|
||||
debug!("refreshing world texture");
|
||||
let map_image_handle = images.get_handle(
|
||||
render_settings
|
||||
.map_image_handle_id
|
||||
.expect("No map image handle"),
|
||||
);
|
||||
let map_image = images
|
||||
.get_mut(&map_image_handle)
|
||||
.expect("Map image handle pointing to non-existing image");
|
||||
map_image.resize(Extent3d {
|
||||
width: world_manager.world().width,
|
||||
height: world_manager.world().height,
|
||||
depth_or_array_layers: 1,
|
||||
});
|
||||
map_image.data = world_manager.map_color_bytes(render_settings);
|
||||
}
|
||||
use crate::gui::{open_window, WidgetId, WidgetSystem};
|
||||
|
|
|
@ -2,16 +2,14 @@ use {
|
|||
crate::{
|
||||
gui::{
|
||||
open_window,
|
||||
update_textures,
|
||||
windows::{SaveLoad, WorldOverlaySelection, WorldViewSelection},
|
||||
WidgetId,
|
||||
WidgetSystem,
|
||||
},
|
||||
macros::iterable_enum,
|
||||
resources::OpenedWindows,
|
||||
resources::{OpenedWindows, ShouldRedraw},
|
||||
},
|
||||
bevy::{
|
||||
asset::Assets,
|
||||
ecs::{
|
||||
change_detection::Mut,
|
||||
component::Component,
|
||||
|
@ -19,10 +17,9 @@ use {
|
|||
world::World,
|
||||
},
|
||||
log::debug,
|
||||
render::texture::Image,
|
||||
},
|
||||
bevy_egui::egui::{Layout, Ui},
|
||||
planet::{WorldManager, WorldRenderSettings},
|
||||
planet::WorldManager,
|
||||
std::marker::PhantomData,
|
||||
};
|
||||
|
||||
|
@ -36,26 +33,19 @@ iterable_enum!(ToolbarButton {
|
|||
impl ToolbarButton {
|
||||
fn clicked(self, world: &mut World) {
|
||||
world.resource_scope(|world, mut world_manager: Mut<'_, WorldManager>| {
|
||||
world.resource_scope(|world, render_settings: Mut<'_, WorldRenderSettings>| {
|
||||
match self {
|
||||
ToolbarButton::GenerateWorld => {
|
||||
if let Err(err) = world_manager.new_world() {
|
||||
eprintln!("Failed to generate world: {}", err);
|
||||
} else {
|
||||
update_textures(
|
||||
&world_manager,
|
||||
&render_settings,
|
||||
&mut world.resource_mut::<Assets<Image>>(),
|
||||
);
|
||||
world.resource_mut::<ShouldRedraw>().0 = true;
|
||||
}
|
||||
},
|
||||
ToolbarButton::SaveLoad => {
|
||||
open_window::<SaveLoad>(&mut world.resource_mut::<OpenedWindows>());
|
||||
},
|
||||
ToolbarButton::Views => {
|
||||
open_window::<WorldViewSelection>(
|
||||
&mut world.resource_mut::<OpenedWindows>(),
|
||||
);
|
||||
open_window::<WorldViewSelection>(&mut world.resource_mut::<OpenedWindows>());
|
||||
},
|
||||
ToolbarButton::Overlays => {
|
||||
open_window::<WorldOverlaySelection>(
|
||||
|
@ -64,7 +54,6 @@ impl ToolbarButton {
|
|||
},
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use {
|
||||
crate::gui::WindowSystem,
|
||||
crate::{gui::WindowSystem, resources::ShouldRedraw},
|
||||
bevy::{
|
||||
ecs::{
|
||||
change_detection::Mut,
|
||||
|
@ -7,10 +7,9 @@ use {
|
|||
world::World,
|
||||
},
|
||||
log::error,
|
||||
prelude::{Assets, Image},
|
||||
},
|
||||
bevy_egui::egui::Ui,
|
||||
planet::{WorldManager, WorldRenderSettings},
|
||||
planet::WorldManager,
|
||||
std::marker::PhantomData,
|
||||
};
|
||||
|
||||
|
@ -24,13 +23,13 @@ pub(crate) struct SaveLoad<'w, 's> {
|
|||
impl WindowSystem for SaveLoad<'_, '_> {
|
||||
fn draw_contents(world: &mut World, state: &mut SystemState<Self>, ui: &mut Ui) {
|
||||
world.resource_scope(|world, mut world_manager: Mut<WorldManager>| {
|
||||
world.resource_scope(|world, mut images: Mut<Assets<Image>>| {
|
||||
world.resource_scope(|world, render_settings: Mut<WorldRenderSettings>| {
|
||||
world.resource_scope(|world, mut should_redraw: Mut<ShouldRedraw>| {
|
||||
let mut state = state.get_mut(world);
|
||||
|
||||
// TODO: File selection dialog.
|
||||
// TODO: Real file selection dialog.
|
||||
ui.text_edit_singleline(&mut *state.file_name);
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
if ui.button("Save").clicked() {
|
||||
if let Err(err) = world_manager.save_world(&*state.file_name) {
|
||||
// TODO: Error popup
|
||||
|
@ -38,13 +37,11 @@ impl WindowSystem for SaveLoad<'_, '_> {
|
|||
}
|
||||
}
|
||||
if ui.button("Load").clicked() {
|
||||
if let Err(err) = world_manager.load_world(
|
||||
&*state.file_name,
|
||||
&render_settings,
|
||||
&mut images,
|
||||
) {
|
||||
if let Err(err) = world_manager.load_world(&*state.file_name) {
|
||||
// TODO: Error popup
|
||||
error!("Failed to load: {err:#?}");
|
||||
}
|
||||
should_redraw.0 = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
use {
|
||||
crate::gui::{update_textures, WindowSystem},
|
||||
bevy::{
|
||||
asset::Assets,
|
||||
ecs::{
|
||||
crate::{gui::WindowSystem, resources::ShouldRedraw},
|
||||
bevy::ecs::{
|
||||
change_detection::Mut,
|
||||
system::{SystemParam, SystemState},
|
||||
world::World,
|
||||
},
|
||||
render::texture::Image,
|
||||
},
|
||||
bevy_egui::egui::Ui,
|
||||
planet::{WorldManager, WorldOverlay, WorldRenderSettings},
|
||||
planet::{WorldOverlay, WorldRenderSettings},
|
||||
std::marker::PhantomData,
|
||||
};
|
||||
|
||||
|
@ -32,13 +28,7 @@ impl WindowSystem for WorldOverlaySelection<'_, '_> {
|
|||
.clicked()
|
||||
{
|
||||
render_settings.toggle_overlay(overlay);
|
||||
world.resource_scope(|world, mut images: Mut<Assets<Image>>| {
|
||||
update_textures(
|
||||
world.resource::<WorldManager>(),
|
||||
&render_settings,
|
||||
&mut images,
|
||||
);
|
||||
});
|
||||
world.resource_mut::<ShouldRedraw>().0 = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
use {
|
||||
crate::gui::{update_textures, WindowSystem},
|
||||
bevy::{
|
||||
asset::Assets,
|
||||
ecs::{
|
||||
crate::{gui::WindowSystem, resources::ShouldRedraw},
|
||||
bevy::ecs::{
|
||||
change_detection::Mut,
|
||||
system::{SystemParam, SystemState},
|
||||
world::World,
|
||||
},
|
||||
render::texture::Image,
|
||||
},
|
||||
bevy_egui::egui::Ui,
|
||||
planet::{WorldManager, WorldRenderSettings, WorldView},
|
||||
planet::{WorldRenderSettings, WorldView},
|
||||
std::marker::PhantomData,
|
||||
};
|
||||
|
||||
|
@ -32,13 +28,7 @@ impl WindowSystem for WorldViewSelection<'_, '_> {
|
|||
&& render_settings.view != view
|
||||
{
|
||||
render_settings.view = view;
|
||||
world.resource_scope(|world, mut images: Mut<Assets<Image>>| {
|
||||
update_textures(
|
||||
world.resource::<WorldManager>(),
|
||||
&render_settings,
|
||||
&mut images,
|
||||
);
|
||||
});
|
||||
world.resource_mut::<ShouldRedraw>().0 = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
70
src/main.rs
70
src/main.rs
|
@ -8,11 +8,6 @@ pub(crate) mod plugins;
|
|||
#[cfg(feature = "render")]
|
||||
pub(crate) mod resources;
|
||||
|
||||
#[cfg(all(feature = "render", feature = "logging"))]
|
||||
use {
|
||||
bevy::diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin},
|
||||
bevy_egui::egui::Frame,
|
||||
};
|
||||
use {
|
||||
bevy::{
|
||||
app::App,
|
||||
|
@ -37,7 +32,13 @@ use {
|
|||
prelude::Vec2,
|
||||
render::{
|
||||
camera::{Camera, RenderTarget},
|
||||
render_resource::{TextureDescriptor, TextureDimension, TextureFormat, TextureUsages},
|
||||
render_resource::{
|
||||
Extent3d,
|
||||
TextureDescriptor,
|
||||
TextureDimension,
|
||||
TextureFormat,
|
||||
TextureUsages,
|
||||
},
|
||||
texture::{Image, ImageSettings},
|
||||
},
|
||||
sprite::{Sprite, SpriteBundle},
|
||||
|
@ -50,16 +51,17 @@ use {
|
|||
EguiContext,
|
||||
},
|
||||
components::panning::Pan2d,
|
||||
gui::{
|
||||
render_windows,
|
||||
update_textures,
|
||||
widget,
|
||||
widgets::ToolbarWidget,
|
||||
window::open_window,
|
||||
windows::TileInfo,
|
||||
},
|
||||
gui::{render_windows, widget, widgets::ToolbarWidget, window::open_window, windows::TileInfo},
|
||||
planet::WorldRenderSettings,
|
||||
resources::{CursorMapPosition, OpenedWindows},
|
||||
resources::{CursorMapPosition, OpenedWindows, ShouldRedraw},
|
||||
};
|
||||
#[cfg(all(feature = "render", feature = "logging"))]
|
||||
use {
|
||||
bevy::{
|
||||
diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin},
|
||||
log::debug,
|
||||
},
|
||||
bevy_egui::egui::Frame,
|
||||
};
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
|
@ -159,8 +161,6 @@ fn generate_graphics(
|
|||
..default()
|
||||
});
|
||||
}
|
||||
|
||||
update_textures(&world_manager, &render_settings, &mut images);
|
||||
}
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
|
@ -203,6 +203,38 @@ fn update_gui(world: &mut World) {
|
|||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
fn redraw_map(
|
||||
mut should_redraw: ResMut<ShouldRedraw>,
|
||||
world_manager: Res<WorldManager>,
|
||||
render_settings: Res<'_, WorldRenderSettings>,
|
||||
mut images: ResMut<Assets<Image>>,
|
||||
) {
|
||||
if should_redraw.0 {
|
||||
let world_manager: &WorldManager = &world_manager;
|
||||
let render_settings: &WorldRenderSettings = &render_settings;
|
||||
let images: &mut Assets<Image> = &mut images;
|
||||
#[cfg(feature = "logging")]
|
||||
debug!("refreshing world texture");
|
||||
let map_image_handle = images.get_handle(
|
||||
render_settings
|
||||
.map_image_handle_id
|
||||
.expect("No map image handle"),
|
||||
);
|
||||
let map_image = images
|
||||
.get_mut(&map_image_handle)
|
||||
.expect("Map image handle pointing to non-existing image");
|
||||
map_image.resize(Extent3d {
|
||||
width: world_manager.world().width,
|
||||
height: world_manager.world().height,
|
||||
depth_or_array_layers: 1,
|
||||
});
|
||||
map_image.data = world_manager.map_color_bytes(render_settings);
|
||||
|
||||
should_redraw.0 = false;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "render")]
|
||||
const WORLD_SCALE: i32 = 4;
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
@ -225,10 +257,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
.insert_resource(CursorMapPosition::default())
|
||||
.insert_resource(OpenedWindows::default())
|
||||
.insert_resource(WorldRenderSettings::default())
|
||||
.insert_resource(ShouldRedraw::default())
|
||||
.add_startup_system(generate_graphics)
|
||||
.add_system(update_gui.exclusive_system())
|
||||
.add_system(update_cursor_map_position)
|
||||
.add_system(open_tile_info);
|
||||
.add_system(open_tile_info)
|
||||
.add_system(redraw_map);
|
||||
}
|
||||
#[cfg(not(feature = "render"))]
|
||||
{
|
||||
|
|
|
@ -11,6 +11,13 @@ impl Display for CursorMapPosition {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ShouldRedraw(pub(crate) bool);
|
||||
impl Default for ShouldRedraw {
|
||||
fn default() -> Self {
|
||||
Self(true)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct OpenedWindows(HashSet<WindowId>);
|
||||
|
||||
|
|
Loading…
Reference in a new issue