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