diff options
Diffstat (limited to 'ecs/src/system.rs')
-rw-r--r-- | ecs/src/system.rs | 64 |
1 files changed, 64 insertions, 0 deletions
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); |