From 77407f7a90373eebd6ceccf5e545e691440c78c4 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Mon, 6 Jan 2025 11:30:00 +0200 Subject: [PATCH] refactor(maze): remove triggers and observers --- src/dev_tools/ui/maze_controls.rs | 7 ++-- src/floor/systems/spawn.rs | 6 +-- src/maze/commands.rs | 49 +++++++++++++++++++++++ src/maze/events.rs | 28 ------------- src/maze/mod.rs | 16 +++----- src/maze/{triggers => systems}/common.rs | 0 src/maze/{triggers => systems}/despawn.rs | 7 ++-- src/maze/systems/mod.rs | 5 ++- src/maze/{triggers => systems}/respawn.rs | 17 ++++---- src/maze/systems/setup.rs | 6 --- src/maze/{triggers => systems}/spawn.rs | 22 +++++----- src/maze/triggers/mod.rs | 15 ------- 12 files changed, 86 insertions(+), 92 deletions(-) create mode 100644 src/maze/commands.rs delete mode 100644 src/maze/events.rs rename src/maze/{triggers => systems}/common.rs (100%) rename src/maze/{triggers => systems}/despawn.rs (71%) rename src/maze/{triggers => systems}/respawn.rs (82%) delete mode 100644 src/maze/systems/setup.rs rename src/maze/{triggers => systems}/spawn.rs (92%) delete mode 100644 src/maze/triggers/mod.rs diff --git a/src/dev_tools/ui/maze_controls.rs b/src/dev_tools/ui/maze_controls.rs index 4c64dfc..2040541 100644 --- a/src/dev_tools/ui/maze_controls.rs +++ b/src/dev_tools/ui/maze_controls.rs @@ -1,6 +1,6 @@ use crate::{ floor::components::{CurrentFloor, Floor}, - maze::{components::MazeConfig, events::RespawnMaze, GlobalMazeConfig}, + maze::{commands::RespawnMaze, components::MazeConfig, GlobalMazeConfig}, player::events::RespawnPlayer, screens::Screen, }; @@ -72,10 +72,11 @@ pub fn maze_controls_ui(world: &mut World) { // Handle updates if changed { maze_config.update(&global_config); - world.trigger(RespawnMaze { + RespawnMaze { floor: floor_value, config: maze_config, - }); + } + .apply(world); world.trigger(RespawnPlayer); } } diff --git a/src/floor/systems/spawn.rs b/src/floor/systems/spawn.rs index 9cd6c42..d27c00f 100644 --- a/src/floor/systems/spawn.rs +++ b/src/floor/systems/spawn.rs @@ -6,7 +6,7 @@ use crate::{ events::TransitionFloor, resources::HighestFloor, }, - maze::{components::MazeConfig, events::SpawnMaze}, + maze::{commands::SpawnMaze, components::MazeConfig}, }; pub(super) fn spawn_floor( @@ -21,7 +21,7 @@ pub(super) fn spawn_floor( for event in event_reader.read() { if current_floor.0 == 1 && *event == TransitionFloor::Descend { - warn!("Cannot descend below floor 1"); + info!("Cannot descend below floor 1"); return; } @@ -30,7 +30,7 @@ pub(super) fn spawn_floor( info!("Creating level for floor {}", target_floor); - commands.trigger(SpawnMaze { + commands.queue(SpawnMaze { floor: target_floor, config: MazeConfig { start_pos: config.end_pos, diff --git a/src/maze/commands.rs b/src/maze/commands.rs new file mode 100644 index 0000000..c1ea38f --- /dev/null +++ b/src/maze/commands.rs @@ -0,0 +1,49 @@ +use super::{ + components::MazeConfig, + systems::{despawn::despawn_maze, respawn::respawn_maze, spawn::spawn_maze}, +}; +use bevy::{ecs::system::RunSystemOnce, prelude::*}; + +#[derive(Debug, Reflect)] +pub struct SpawnMaze { + pub floor: u8, + pub config: MazeConfig, +} + +#[derive(Debug, Reflect)] +pub struct RespawnMaze { + pub floor: u8, + pub config: MazeConfig, +} + +#[derive(Debug, Reflect)] +pub struct DespawnMaze { + pub floor: u8, +} + +impl Default for SpawnMaze { + fn default() -> Self { + Self { + floor: 1, + config: MazeConfig::default(), + } + } +} + +impl Command for SpawnMaze { + fn apply(self, world: &mut World) { + let _ = world.run_system_once_with(self, spawn_maze); + } +} + +impl Command for RespawnMaze { + fn apply(self, world: &mut World) { + let _ = world.run_system_once_with(self, respawn_maze); + } +} + +impl Command for DespawnMaze { + fn apply(self, world: &mut World) { + let _ = world.run_system_once_with(self, despawn_maze); + } +} diff --git a/src/maze/events.rs b/src/maze/events.rs deleted file mode 100644 index ead86a9..0000000 --- a/src/maze/events.rs +++ /dev/null @@ -1,28 +0,0 @@ -use super::components::MazeConfig; -use bevy::prelude::*; - -#[derive(Debug, Reflect, Event)] -pub struct SpawnMaze { - pub floor: u8, - pub config: MazeConfig, -} - -#[derive(Debug, Reflect, Event)] -pub struct RespawnMaze { - pub floor: u8, - pub config: MazeConfig, -} - -#[derive(Debug, Reflect, Event)] -pub struct DespawnMaze { - pub floor: u8, -} - -impl Default for SpawnMaze { - fn default() -> Self { - Self { - floor: 1, - config: MazeConfig::default(), - } - } -} diff --git a/src/maze/mod.rs b/src/maze/mod.rs index 5f2abc1..648f171 100644 --- a/src/maze/mod.rs +++ b/src/maze/mod.rs @@ -1,25 +1,19 @@ mod assets; +pub mod commands; pub mod components; pub mod errors; -pub mod events; pub mod resources; mod systems; -mod triggers; -use bevy::{ecs::system::RunSystemOnce, prelude::*}; -use components::HexMaze; -use events::{DespawnMaze, RespawnMaze, SpawnMaze}; +use bevy::prelude::*; +use commands::SpawnMaze; pub use resources::GlobalMazeConfig; pub(super) fn plugin(app: &mut App) { app.init_resource::() - .add_event::() - .add_event::() - .add_event::() - .register_type::() - .add_plugins((systems::plugin, triggers::plugin)); + .add_plugins(systems::plugin); } pub fn spawn_level_command(world: &mut World) { - let _ = world.run_system_once(systems::setup::setup); + SpawnMaze::default().apply(world); } diff --git a/src/maze/triggers/common.rs b/src/maze/systems/common.rs similarity index 100% rename from src/maze/triggers/common.rs rename to src/maze/systems/common.rs diff --git a/src/maze/triggers/despawn.rs b/src/maze/systems/despawn.rs similarity index 71% rename from src/maze/triggers/despawn.rs rename to src/maze/systems/despawn.rs index 15f8700..06e12df 100644 --- a/src/maze/triggers/despawn.rs +++ b/src/maze/systems/despawn.rs @@ -2,18 +2,17 @@ //! //! Module handles the cleanup of maze entities when they need to be removed, //! ensuring proper cleanup of both the maze and all its child entities. -use crate::{floor::components::Floor, maze::events::DespawnMaze}; +use crate::{floor::components::Floor, maze::commands::DespawnMaze}; use bevy::prelude::*; /// Despawns a maze and all its associated entities for a given floor. pub fn despawn_maze( - trigger: Trigger, + In(DespawnMaze { floor }): In, mut commands: Commands, query: Query<(Entity, &Floor)>, ) { - let DespawnMaze { floor } = trigger.event(); - match query.iter().find(|(_, f)| f.0 == *floor) { + match query.iter().find(|(_, f)| f.0 == floor) { Some((entity, _)) => commands.entity(entity).despawn_recursive(), _ => warn!("Floor {} not found for removal", floor), } diff --git a/src/maze/systems/mod.rs b/src/maze/systems/mod.rs index 554515c..8def9f0 100644 --- a/src/maze/systems/mod.rs +++ b/src/maze/systems/mod.rs @@ -1,4 +1,7 @@ -pub mod setup; +pub mod common; +pub mod despawn; +pub mod respawn; +pub mod spawn; use bevy::prelude::*; diff --git a/src/maze/triggers/respawn.rs b/src/maze/systems/respawn.rs similarity index 82% rename from src/maze/triggers/respawn.rs rename to src/maze/systems/respawn.rs index ac9bc47..58db5fc 100644 --- a/src/maze/triggers/respawn.rs +++ b/src/maze/systems/respawn.rs @@ -3,14 +3,15 @@ //! Module provides the ability to regenerate mazes for existing floors, //! maintaining the same floor entity but replacing its internal maze structure. -use super::{common::generate_maze, spawn::spawn_maze_tiles}; use crate::{ floor::components::Floor, - maze::{assets::MazeAssets, errors::MazeError, events::RespawnMaze, GlobalMazeConfig}, + maze::{assets::MazeAssets, commands::RespawnMaze, errors::MazeError, GlobalMazeConfig}, }; use bevy::prelude::*; use hexlab::Maze; +use super::{common::generate_maze, spawn::spawn_maze_tiles}; + /// Respawns a maze for an existing floor with a new configuration. /// /// # Behavior: @@ -20,19 +21,17 @@ use hexlab::Maze; /// - Spawns new maze tiles /// - Updates the floor's configuration pub fn respawn_maze( - trigger: Trigger, + In(RespawnMaze { floor, config }): In, mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, mut maze_query: Query<(Entity, &Floor, &mut Maze)>, global_config: Res, ) { - let RespawnMaze { floor, config } = trigger.event(); - let (entity, _, mut maze) = match maze_query .iter_mut() - .find(|(_, f, _)| f.0 == *floor) - .ok_or(MazeError::FloorNotFound(*floor)) + .find(|(_, f, _)| f.0 == floor) + .ok_or(MazeError::FloorNotFound(floor)) { Ok((entity, floor, maze)) => (entity, floor, maze), Err(e) => { @@ -41,7 +40,7 @@ pub fn respawn_maze( } }; - *maze = match generate_maze(config) { + *maze = match generate_maze(&config) { Ok(generated_maze) => generated_maze, Err(e) => { warn!("Failed to update floor ({floor}). {e}"); @@ -56,7 +55,7 @@ pub fn respawn_maze( entity, &maze, &assets, - config, + &config, &global_config, ); diff --git a/src/maze/systems/setup.rs b/src/maze/systems/setup.rs deleted file mode 100644 index 42fe9fe..0000000 --- a/src/maze/systems/setup.rs +++ /dev/null @@ -1,6 +0,0 @@ -use crate::maze::events::SpawnMaze; -use bevy::prelude::*; - -pub fn setup(mut commands: Commands) { - commands.trigger(SpawnMaze::default()); -} diff --git a/src/maze/triggers/spawn.rs b/src/maze/systems/spawn.rs similarity index 92% rename from src/maze/triggers/spawn.rs rename to src/maze/systems/spawn.rs index 63e1c68..b33f932 100644 --- a/src/maze/triggers/spawn.rs +++ b/src/maze/systems/spawn.rs @@ -11,8 +11,8 @@ use crate::{ }, maze::{ assets::MazeAssets, + commands::SpawnMaze, components::{HexMaze, MazeConfig, Tile, Wall}, - events::SpawnMaze, resources::GlobalMazeConfig, }, screens::Screen, @@ -26,7 +26,7 @@ use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6}; /// Spawns a new maze for the specified floor on [`SpawnMaze`] event. pub fn spawn_maze( - trigger: Trigger, + In(SpawnMaze { floor, config }): In, mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, @@ -34,14 +34,12 @@ pub fn spawn_maze( global_config: Res, mut event_writer: EventWriter, ) { - let SpawnMaze { floor, config } = trigger.event(); - - if maze_query.iter().any(|(_, f, _)| f.0 == *floor) { - warn!("Floor {} already exists, skipping creation", floor); + if maze_query.iter().any(|(_, f, _)| f.0 == floor) { + info!("Floor {} already exists, skipping creation", floor); return; } - let maze = match generate_maze(config) { + let maze = match generate_maze(&config) { Ok(m) => m, Err(e) => { error!("Failed to generate maze for floor {floor}: {:?}", e); @@ -50,7 +48,7 @@ pub fn spawn_maze( }; // Calculate vertical offset based on floor number - let y_offset = match *floor { + let y_offset = match floor { 1 => 0, // Ground/Initial floor (floor 1) is at y=0 _ => FLOOR_Y_OFFSET, // Other floors are offset vertically } as f32; @@ -60,13 +58,13 @@ pub fn spawn_maze( Name::new(format!("Floor {}", floor)), HexMaze, maze.clone(), - Floor(*floor), + Floor(floor), config.clone(), Transform::from_translation(Vec3::ZERO.with_y(y_offset)), Visibility::Visible, StateScoped(Screen::Gameplay), )) - .insert_if(CurrentFloor, || *floor == 1) // Only floor 1 gets CurrentFloor + .insert_if(CurrentFloor, || floor == 1) // Only floor 1 gets CurrentFloor .id(); let assets = MazeAssets::new(&mut meshes, &mut materials, &global_config); @@ -75,12 +73,12 @@ pub fn spawn_maze( entity, &maze, &assets, - config, + &config, &global_config, ); // TODO: find a better way to handle double event indirection - if *floor != 1 { + if floor != 1 { event_writer.send(TransitionFloor::Ascend); } } diff --git a/src/maze/triggers/mod.rs b/src/maze/triggers/mod.rs deleted file mode 100644 index 657f989..0000000 --- a/src/maze/triggers/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -pub mod common; -mod despawn; -mod respawn; -mod spawn; - -use bevy::prelude::*; -use despawn::despawn_maze; -use respawn::respawn_maze; -use spawn::spawn_maze; - -pub(super) fn plugin(app: &mut App) { - app.add_observer(spawn_maze) - .add_observer(respawn_maze) - .add_observer(despawn_maze); -}