From 6038a5b701ee9ea3bd3b5da50d7d06930cd9a270 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sat, 6 Apr 2024 15:35:51 +0200 Subject: refactor(ecs): make stopping into a action --- ecs/examples/event_loop.rs | 6 ++--- ecs/src/actions.rs | 15 +++++++++++ ecs/src/flags.rs | 66 ---------------------------------------------- ecs/src/lib.rs | 29 +++++--------------- 4 files changed, 24 insertions(+), 92 deletions(-) delete mode 100644 ecs/src/flags.rs diff --git a/ecs/examples/event_loop.rs b/ecs/examples/event_loop.rs index f9fd85f..b6a10e3 100644 --- a/ecs/examples/event_loop.rs +++ b/ecs/examples/event_loop.rs @@ -1,5 +1,5 @@ +use ecs::actions::Actions; use ecs::event::{Event, Id as EventId}; -use ecs::flags::Flags; use ecs::{Component, Query, World}; #[derive(Component)] @@ -45,7 +45,7 @@ fn feed(query: Query<(Health, Name)>) } } -fn age(query: Query<(Health, Name)>, mut flags: Flags) +fn age(query: Query<(Health, Name)>, mut actions: Actions) { for (mut health, name) in &query { if health.health <= 2 { @@ -53,7 +53,7 @@ fn age(query: Query<(Health, Name)>, mut flags: Flags) println!("{} passed away", name.name); - flags.stop(); + actions.stop(); continue; } diff --git a/ecs/src/actions.rs b/ecs/src/actions.rs index ea4837a..a5aaf0c 100644 --- a/ecs/src/actions.rs +++ b/ecs/src/actions.rs @@ -26,6 +26,20 @@ impl<'world> Actions<'world> .expect("Failed to aquire read-write action queue lock") .push(Action::Spawn(components.into_vec())); } + + /// Adds stopping the loop in [`Engine::event_loop`] at the next oppertune time to the + /// action queue. + /// + /// # Panics + /// Will panic if a mutable internal lock cannot be acquired. + pub fn stop(&mut self) + { + self.world_data + .action_queue + .write_nonblock() + .expect("Failed to aquire read-write action queue lock") + .push(Action::Stop); + } } unsafe impl<'world> SystemParam<'world> for Actions<'world> @@ -66,6 +80,7 @@ unsafe impl<'world> SystemParam<'world> for Actions<'world> pub(crate) enum Action { Spawn(Vec>), + Stop, } struct Comparable; diff --git a/ecs/src/flags.rs b/ecs/src/flags.rs deleted file mode 100644 index ad10a0f..0000000 --- a/ecs/src/flags.rs +++ /dev/null @@ -1,66 +0,0 @@ -use std::any::Any; - -use crate::lock::WriteGuard; -use crate::system::{ - NoInitParamFlag as NoInitSystemParamFlag, - Param as SystemParam, - System, -}; -use crate::tuple::FilterExclude as TupleFilterExclude; -use crate::{WorldData, WorldFlags}; - -#[derive(Debug)] -pub struct Flags<'world> -{ - world_flags: WriteGuard<'world, WorldFlags>, -} - -impl<'world> Flags<'world> -{ - /// Calling this function makes the loop in [`Engine::event_loop`] stop at the next - /// opportune time. - pub fn stop(&mut self) - { - self.world_flags.stop = true; - } -} - -unsafe impl<'world> SystemParam<'world> for Flags<'world> -{ - type Flags = NoInitSystemParamFlag; - type Input = TupleFilterExclude; - - fn initialize( - _system: &mut impl System<'world, SystemImpl>, - _input: Self::Input, - ) - { - } - - fn new( - _system: &'world impl System<'world, SystemImpl>, - world_data: &'world WorldData, - ) -> Self - { - Self { - world_flags: world_data - .flags - .write_nonblock() - .expect("Failed to acquire read-write world flags lock"), - } - } - - fn is_compatible>() -> bool - { - let other_comparable = Other::get_comparable(); - - other_comparable.downcast_ref::().is_none() - } - - fn get_comparable() -> Box - { - Box::new(Comparable) - } -} - -struct Comparable; diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 5273b67..1c4e44f 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -7,6 +7,7 @@ use std::marker::PhantomData; use std::mem::ManuallyDrop; use std::ops::RangeBounds; use std::slice::Iter as SliceIter; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Weak}; use std::vec::Drain; @@ -26,7 +27,6 @@ use crate::type_name::TypeName; pub mod actions; pub mod component; pub mod event; -pub mod flags; pub mod lock; pub mod system; pub mod tuple; @@ -53,6 +53,7 @@ pub struct World { systems: Vec, data: WorldData, + stop: AtomicBool, } impl World @@ -160,6 +161,9 @@ impl World .collect(), }); } + Action::Stop => { + self.stop.store(true, Ordering::Relaxed); + } } } } @@ -179,13 +183,7 @@ impl World self.perform_queued_actions(); - let flags = self - .data - .flags - .read_nonblock() - .expect("Failed to aquire lock to flags"); - - if flags.stop { + if self.stop.load(Ordering::Relaxed) { break; } } @@ -208,27 +206,12 @@ impl World } } -#[derive(Debug, Default)] -struct WorldFlags -{ - stop: bool, -} - -impl TypeName for WorldFlags -{ - fn type_name(&self) -> &'static str - { - type_name::() - } -} - #[derive(Debug, Default)] pub struct WorldData { events: HashMap>, component_storage: Arc>, action_queue: Lock, - flags: Lock, } #[derive(Debug, Default)] -- cgit v1.2.3-18-g5258