From b0ef7f2cf8787c5732e0eb5554161ad75179a4b3 Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 20 Feb 2024 23:02:57 +0100 Subject: refactor(ecs): add system trait --- ecs/src/lib.rs | 37 ++++++-------------------------- ecs/src/system.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 30 deletions(-) create mode 100644 ecs/src/system.rs (limited to 'ecs/src') diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index f824ebc..6106862 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -8,8 +8,10 @@ use std::marker::PhantomData; use std::slice::IterMut as SliceIterMut; use crate::component::{Component, Sequence as ComponentSequence}; +use crate::system::{System, TypeErased as TypeErasedSystem}; pub mod component; +pub mod system; #[derive(Debug)] struct Entity @@ -20,7 +22,7 @@ struct Entity #[derive(Debug)] pub struct World { - systems: Vec>, + systems: Vec, events: HashMap>, component_storage: ComponentStorage, } @@ -46,12 +48,12 @@ impl World .push(Entity { components: components.into_vec() }); } - pub fn register_system(&mut self, event: Event, system: System) + pub fn register_system(&mut self, event: Event, system: TSystem) where Event: Hash + PartialEq + Eq, - Comps: ComponentSequence + 'static, + TSystem: System, { - self.systems.push(Box::new(system)); + self.systems.push(system.into_type_erased()); self.events .entry(event) @@ -75,7 +77,7 @@ impl World for system_index in system_indices { let system = self.systems.get_mut(system_index).unwrap(); - system.call(&mut self.component_storage); + system.run(&mut self.component_storage); } } @@ -95,31 +97,6 @@ impl Default for World } } -pub type System = fn(Query); - -trait AnySystem -{ - fn call(&self, component_storage: &mut ComponentStorage); -} - -impl AnySystem for System -where - Comps: ComponentSequence, -{ - fn call(&self, component_storage: &mut ComponentStorage) - { - self(Query::new(component_storage)); - } -} - -impl Debug for dyn AnySystem -{ - fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result - { - formatter.debug_struct("AnySystem").finish_non_exhaustive() - } -} - #[derive(Debug)] pub struct Query<'world, Comps> { diff --git a/ecs/src/system.rs b/ecs/src/system.rs new file mode 100644 index 0000000..ecf1885 --- /dev/null +++ b/ecs/src/system.rs @@ -0,0 +1,64 @@ +use std::any::Any; +use std::fmt::Debug; + +use crate::component::Sequence as ComponentSequence; +use crate::{ComponentStorage, Query}; + +pub trait System: 'static +{ + type Query<'a>; + + fn run(&self, component_storage: &mut ComponentStorage); + + fn into_type_erased(self) -> TypeErased; +} + +impl System)> for Func +where + Func: Fn(Query) + 'static, + Comps: ComponentSequence, +{ + type Query<'a> = Query<'a, Comps>; + + fn run(&self, component_storage: &mut ComponentStorage) + { + self(Query::new(component_storage)); + } + + fn into_type_erased(self) -> TypeErased + { + TypeErased { + data: Box::new(self), + func: Box::new(|data, component_storage| { + let me = data.downcast_mut::().unwrap(); + + me.run(component_storage); + }), + } + } +} + +pub struct TypeErased +{ + data: Box, + func: Box, +} + +impl TypeErased +{ + pub fn run(&mut self, component_storage: &mut ComponentStorage) + { + (self.func)(self.data.as_mut(), component_storage); + } +} + +impl Debug for TypeErased +{ + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result + { + formatter.debug_struct("TypeErased").finish_non_exhaustive() + } +} + +/// Function in [`TypeErased`] used to run the system. +type TypeErasedFunc = dyn Fn(&mut dyn Any, &mut ComponentStorage); -- cgit v1.2.3-18-g5258