From ec5011a443a6477bdd55c15614328e56f8980786 Mon Sep 17 00:00:00 2001 From: Tobias Berger Date: Tue, 8 Nov 2022 22:18:51 +0100 Subject: [PATCH] Redraw map as separate system instead of in many places --- planet/src/world_manager.rs | 31 +--------- src/gui/mod.rs | 32 +--------- src/gui/widgets/toolbar.rs | 55 +++++++---------- src/gui/windows/save_load.rs | 23 ++++--- src/gui/windows/world_overlay_selection.rs | 24 +++----- src/gui/windows/world_view_selection.rs | 24 +++----- src/main.rs | 70 ++++++++++++++++------ src/resources/mod.rs | 7 +++ 8 files changed, 108 insertions(+), 158 deletions(-) diff --git a/planet/src/world_manager.rs b/planet/src/world_manager.rs index 89a7f8c..dc51840 100644 --- a/planet/src/world_manager.rs +++ b/planet/src/world_manager.rs @@ -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>( - &mut self, - path: P, - #[cfg(feature = "render")] render_settings: &WorldRenderSettings, - #[cfg(feature = "render")] images: &mut Assets, - ) -> Result<(), LoadError> { + pub fn load_world>(&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)), diff --git a/src/gui/mod.rs b/src/gui/mod.rs index ba52cd3..73ba016 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -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, -) { - 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}; diff --git a/src/gui/widgets/toolbar.rs b/src/gui/widgets/toolbar.rs index 9174767..2ecf3e4 100644 --- a/src/gui/widgets/toolbar.rs +++ b/src/gui/widgets/toolbar.rs @@ -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,34 +33,26 @@ 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::>(), - ); - } - }, - ToolbarButton::SaveLoad => { - open_window::(&mut world.resource_mut::()); - }, - ToolbarButton::Views => { - open_window::( - &mut world.resource_mut::(), - ); - }, - ToolbarButton::Overlays => { - open_window::( - &mut world.resource_mut::(), - ); - }, - }; - }); + match self { + ToolbarButton::GenerateWorld => { + if let Err(err) = world_manager.new_world() { + eprintln!("Failed to generate world: {}", err); + } else { + world.resource_mut::().0 = true; + } + }, + ToolbarButton::SaveLoad => { + open_window::(&mut world.resource_mut::()); + }, + ToolbarButton::Views => { + open_window::(&mut world.resource_mut::()); + }, + ToolbarButton::Overlays => { + open_window::( + &mut world.resource_mut::(), + ); + }, + }; }); } } diff --git a/src/gui/windows/save_load.rs b/src/gui/windows/save_load.rs index 145f1c9..7f898e9 100644 --- a/src/gui/windows/save_load.rs +++ b/src/gui/windows/save_load.rs @@ -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, ui: &mut Ui) { world.resource_scope(|world, mut world_manager: Mut| { - world.resource_scope(|world, mut images: Mut>| { - world.resource_scope(|world, render_settings: Mut| { - let mut state = state.get_mut(world); + world.resource_scope(|world, mut should_redraw: Mut| { + let mut state = state.get_mut(world); - // TODO: File selection dialog. - ui.text_edit_singleline(&mut *state.file_name); + // 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; } }); }); diff --git a/src/gui/windows/world_overlay_selection.rs b/src/gui/windows/world_overlay_selection.rs index 001622a..cf8e98c 100644 --- a/src/gui/windows/world_overlay_selection.rs +++ b/src/gui/windows/world_overlay_selection.rs @@ -1,16 +1,12 @@ use { - crate::gui::{update_textures, WindowSystem}, - bevy::{ - asset::Assets, - ecs::{ - change_detection::Mut, - system::{SystemParam, SystemState}, - world::World, - }, - render::texture::Image, + crate::{gui::WindowSystem, resources::ShouldRedraw}, + bevy::ecs::{ + change_detection::Mut, + system::{SystemParam, SystemState}, + world::World, }, 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>| { - update_textures( - world.resource::(), - &render_settings, - &mut images, - ); - }); + world.resource_mut::().0 = true; } } }); diff --git a/src/gui/windows/world_view_selection.rs b/src/gui/windows/world_view_selection.rs index 7c9e6df..f99ebb9 100644 --- a/src/gui/windows/world_view_selection.rs +++ b/src/gui/windows/world_view_selection.rs @@ -1,16 +1,12 @@ use { - crate::gui::{update_textures, WindowSystem}, - bevy::{ - asset::Assets, - ecs::{ - change_detection::Mut, - system::{SystemParam, SystemState}, - world::World, - }, - render::texture::Image, + crate::{gui::WindowSystem, resources::ShouldRedraw}, + bevy::ecs::{ + change_detection::Mut, + system::{SystemParam, SystemState}, + world::World, }, 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>| { - update_textures( - world.resource::(), - &render_settings, - &mut images, - ); - }); + world.resource_mut::().0 = true; } } }); diff --git a/src/main.rs b/src/main.rs index 9fd48c4..0ed583a 100644 --- a/src/main.rs +++ b/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, + world_manager: Res, + render_settings: Res<'_, WorldRenderSettings>, + mut images: ResMut>, +) { + if should_redraw.0 { + let world_manager: &WorldManager = &world_manager; + let render_settings: &WorldRenderSettings = &render_settings; + let images: &mut Assets = &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> { @@ -225,10 +257,12 @@ fn main() -> Result<(), Box> { .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"))] { diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 79d650c..aa214a7 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -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);