From de5c3ff1320ea0f0452afde4c1f42676d9eeab52 Mon Sep 17 00:00:00 2001 From: HampusM Date: Fri, 16 Feb 2024 19:58:53 +0100 Subject: feat: add entity component system library --- ecs/src/component.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 ecs/src/component.rs (limited to 'ecs/src/component.rs') 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 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(&mut self) -> Option<&mut Real> + { + self.as_any_mut().downcast_mut() + } + + pub fn is(&self) -> bool + { + self.as_any().is::() + } +} + +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>; + + fn type_ids() -> Vec; + + fn from_components<'components>( + components: &'components mut [Box], + ) -> 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> { + Vec::from_iter([#(Box::new(self.I) as Box,)*]) + } + + fn type_ids() -> Vec { + vec![ + #( + TypeId::of::(), + )* + ] + } + + fn from_components<'components>( + components: &'components mut [Box], + ) -> Self::MutRefs<'components> + { + #( + let mut comp_~I = None; + )* + + for comp in components.iter_mut() { + #( + if comp.is::() { + comp_~I = Some(comp); + continue; + } + + )* + } + + + (#( + comp_~I.unwrap().downcast_mut::().unwrap(), + )*) + } + } + }); + }; +} + +seq!(C in 0..=64 { + inner!(C); +}); -- cgit v1.2.3-18-g5258