summaryrefslogtreecommitdiff
path: root/ecs/src/component.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-02-16 19:58:53 +0100
committerHampusM <hampus@hampusmat.com>2024-02-18 18:23:03 +0100
commitde5c3ff1320ea0f0452afde4c1f42676d9eeab52 (patch)
tree5394c42d76301f68526816552689a0beeb2ffdfb /ecs/src/component.rs
parent12f73be1bf0a7dd7d67bab2eb44d0f0629d37028 (diff)
feat: add entity component system library
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r--ecs/src/component.rs114
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);
+});