diff options
Diffstat (limited to 'engine-ecs/src/component.rs')
| -rw-r--r-- | engine-ecs/src/component.rs | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/engine-ecs/src/component.rs b/engine-ecs/src/component.rs index 400b12c..d424e16 100644 --- a/engine-ecs/src/component.rs +++ b/engine-ecs/src/component.rs @@ -3,6 +3,7 @@ use std::fmt::Debug; use std::ops::{Deref, DerefMut}; use engine_ecs_macros::Component; +use seq_macro::seq; use crate::event::component::Changed; use crate::event::Submitter as EventSubmitter; @@ -23,13 +24,9 @@ pub mod local; pub(crate) mod storage; -pub trait Component: SystemInput + Any + IntoParts +/// A component that is not a pair and is not a sole. +pub trait Component: WithAssociatedId + SystemInput + Any + IntoParts { - /// Returns the ID of this component. - fn id() -> Uid - where - Self: Sized; - fn type_reflection() -> Option<&'static TypeReflection> where Self: Sized; @@ -38,32 +35,50 @@ pub trait Component: SystemInput + Any + IntoParts fn name(&self) -> &'static str; } -impl dyn Component +pub trait WithAssociatedId { - pub fn downcast_mut<Real: 'static>(&mut self) -> Option<&mut Real> - { - (self as &mut dyn Any).downcast_mut() - } + /// Returns the ID of this component. + fn id() -> Uid; +} - pub fn downcast_ref<Real: 'static>(&self) -> Option<&Real> - { - (self as &dyn Any).downcast_ref() - } +/// A component that is removable from it's entity. +/// +/// This trait is implemented for [`crate::pair::Pair`] so it does not have [`Component`] +/// as supertrait. +pub trait Removable: WithAssociatedId {} - pub fn is<Other: 'static>(&self) -> bool - { - (self as &dyn Any).is::<Other>() - } -} +impl<ComponentT: Component> Removable for ComponentT {} -impl Debug for dyn Component +/// Implemented by tuples of types implementing [`Removable`]. +/// +/// This trait is sealed so it cannot be implemented by types outside of this module. +pub trait RemovableTuple: sealed::Sealed { - fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result - { - formatter.debug_struct("Component").finish_non_exhaustive() - } + fn ids() -> impl IntoIterator<Item = Uid>; +} + +macro_rules! gen_removable_tuple_impl { + ($c: tt) => { + seq!(I in 0..=$c { + impl<#(RemovableT~I: Removable,)*> RemovableTuple for (#(RemovableT~I,)*) + { + fn ids() -> impl IntoIterator<Item = Uid> + { + [#(RemovableT~I::id(),)*] + } + } + + impl<#(RemovableT~I: Removable,)*> sealed::Sealed for (#(RemovableT~I,)*) + { + } + }); + }; } +seq!(C in 0..=16 { + gen_removable_tuple_impl!(C); +}); + #[derive(Debug)] pub struct Handle<'a, DataT: ?Sized + 'static> { @@ -394,3 +409,8 @@ pub struct Info pub name: &'static str, pub is_sole: bool, } + +mod sealed +{ + pub trait Sealed {} +} |
