summaryrefslogtreecommitdiff
path: root/engine-ecs/src/component.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine-ecs/src/component.rs')
-rw-r--r--engine-ecs/src/component.rs70
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 {}
+}