diff options
| author | HampusM <hampus@hampusmat.com> | 2024-02-20 23:02:57 +0100 | 
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2024-02-21 23:18:56 +0100 | 
| commit | b0ef7f2cf8787c5732e0eb5554161ad75179a4b3 (patch) | |
| tree | 726721a222509f532c02e8e4bbc543edc85f5cb5 /ecs/src | |
| parent | 3e18fb061538265610041d45c45642ee2686efd9 (diff) | |
refactor(ecs): add system trait
Diffstat (limited to 'ecs/src')
| -rw-r--r-- | ecs/src/lib.rs | 37 | ||||
| -rw-r--r-- | ecs/src/system.rs | 64 | 
2 files changed, 71 insertions, 30 deletions
| 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<Event>  { -    systems: Vec<Box<dyn AnySystem>>, +    systems: Vec<TypeErasedSystem>,      events: HashMap<Event, Vec<usize>>,      component_storage: ComponentStorage,  } @@ -46,12 +48,12 @@ impl<Event> World<Event>              .push(Entity { components: components.into_vec() });      } -    pub fn register_system<Comps>(&mut self, event: Event, system: System<Comps>) +    pub fn register_system<TSystem, SystemImpl>(&mut self, event: Event, system: TSystem)      where          Event: Hash + PartialEq + Eq, -        Comps: ComponentSequence + 'static, +        TSystem: System<SystemImpl>,      { -        self.systems.push(Box::new(system)); +        self.systems.push(system.into_type_erased());          self.events              .entry(event) @@ -75,7 +77,7 @@ impl<Event> World<Event>          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<Event> Default for World<Event>      }  } -pub type System<Comps> = fn(Query<Comps>); - -trait AnySystem -{ -    fn call(&self, component_storage: &mut ComponentStorage); -} - -impl<Comps> AnySystem for System<Comps> -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<Impl>: 'static +{ +    type Query<'a>; + +    fn run(&self, component_storage: &mut ComponentStorage); + +    fn into_type_erased(self) -> TypeErased; +} + +impl<Func, Comps> System<fn(Query<Comps>)> for Func +where +    Func: Fn(Query<Comps>) + '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::<Func>().unwrap(); + +                me.run(component_storage); +            }), +        } +    } +} + +pub struct TypeErased +{ +    data: Box<dyn Any>, +    func: Box<TypeErasedFunc>, +} + +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); | 
