diff options
author | HampusM <hampus@hampusmat.com> | 2024-02-16 19:58:53 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-02-18 18:23:03 +0100 |
commit | de5c3ff1320ea0f0452afde4c1f42676d9eeab52 (patch) | |
tree | 5394c42d76301f68526816552689a0beeb2ffdfb /ecs/src/component.rs | |
parent | 12f73be1bf0a7dd7d67bab2eb44d0f0629d37028 (diff) |
feat: add entity component system library
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r-- | ecs/src/component.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs new file mode 100644 index 0000000..4829050 --- /dev/null +++ b/ecs/src/component.rs @@ -0,0 +1,114 @@ +use std::any::{Any, TypeId}; +use std::fmt::Debug; + +use seq_macro::seq; + +pub trait Component: Any +{ + #[doc(hidden)] + fn as_any_mut(&mut self) -> &mut dyn Any; + + #[doc(hidden)] + fn as_any(&self) -> &dyn Any; +} + +impl<Value: Any> Component for Value +{ + fn as_any_mut(&mut self) -> &mut dyn Any + { + self + } + + fn as_any(&self) -> &dyn Any + { + self + } +} + +impl dyn Component +{ + pub fn downcast_mut<Real: 'static>(&mut self) -> Option<&mut Real> + { + self.as_any_mut().downcast_mut() + } + + pub fn is<Other: 'static>(&self) -> bool + { + self.as_any().is::<Other>() + } +} + +impl Debug for dyn Component +{ + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result + { + formatter.debug_struct("Component").finish_non_exhaustive() + } +} + +/// A sequence of components. +pub trait Sequence +{ + type MutRefs<'component> + where + Self: 'component; + + fn into_vec(self) -> Vec<Box<dyn Component>>; + + fn type_ids() -> Vec<TypeId>; + + fn from_components<'components>( + components: &'components mut [Box<dyn Component>], + ) -> Self::MutRefs<'components>; +} + +macro_rules! inner { + ($c: tt) => { + seq!(I in 0..=$c { + impl<#(Comp~I: Component,)*> Sequence for (#(Comp~I,)*) { + type MutRefs<'component> = (#(&'component mut Comp~I,)*) + where Self: 'component; + + fn into_vec(self) -> Vec<Box<dyn Component>> { + Vec::from_iter([#(Box::new(self.I) as Box<dyn Component>,)*]) + } + + fn type_ids() -> Vec<TypeId> { + vec![ + #( + TypeId::of::<Comp~I>(), + )* + ] + } + + fn from_components<'components>( + components: &'components mut [Box<dyn Component>], + ) -> Self::MutRefs<'components> + { + #( + let mut comp_~I = None; + )* + + for comp in components.iter_mut() { + #( + if comp.is::<Comp~I>() { + comp_~I = Some(comp); + continue; + } + + )* + } + + + (#( + comp_~I.unwrap().downcast_mut::<Comp~I>().unwrap(), + )*) + } + } + }); + }; +} + +seq!(C in 0..=64 { + inner!(C); +}); |