summaryrefslogtreecommitdiff
path: root/ecs/src/system.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/system.rs')
-rw-r--r--ecs/src/system.rs64
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);