diff options
Diffstat (limited to 'ecs/src')
| -rw-r--r-- | ecs/src/event/component.rs | 126 | ||||
| -rw-r--r-- | ecs/src/system/observer.rs | 4 |
2 files changed, 81 insertions, 49 deletions
diff --git a/ecs/src/event/component.rs b/ecs/src/event/component.rs index ed6b7cf..70ea3e5 100644 --- a/ecs/src/event/component.rs +++ b/ecs/src/event/component.rs @@ -2,12 +2,14 @@ use std::convert::Infallible; +use crate::Component; use crate::component::{Handle as ComponentHandle, HandleMut as ComponentHandleMut}; use crate::entity::Handle as EntityHandle; use crate::pair::Pair; -use crate::system::observer::EventMatch; -use crate::util::impl_multiple; -use crate::Component; +use crate::system::observer::{EventMatch, Observed}; + +/// Implemented by the relations of component event pairs +pub trait EventRelation: Component {} /// Pair relation for events emitted when: /// a) A entity with the target component is spawned. @@ -15,57 +17,87 @@ use crate::Component; #[derive(Debug, Component)] pub struct Added(Infallible); +impl EventRelation for Added {} + /// Pair relation for events emitted **before**: /// a) The target component is removed from a entity. /// b) A entity with the target component is despawned. #[derive(Debug, Component)] pub struct Removed(Infallible); +impl EventRelation for Removed {} + #[derive(Debug, Component)] pub struct Changed(Infallible); -impl_multiple!( - EventMatch, - ( - impl<Target: Component> _<'_><Pair<Removed, Target>> (removed), - impl<Target: Component> _<'_><Pair<Added, Target>> (added), - impl<Target: Component> _<'_><Pair<Changed, Target>> (changed) - ) - cb=(type_params=(observable_type), event_name) => { - paste::paste! { - #[must_use] - pub fn [<get_ $event_name _comp>](&self) -> ComponentHandle<'_, Target> - { - let ent = self.get_ent_infallible(); - - let Some(comp) = ent.get::<Target>() else { - unreachable!(); - }; - - comp - } - - #[must_use] - pub fn [<get_ $event_name _comp_mut>](&self) -> ComponentHandleMut<'_, Target> - { - let ent = self.get_ent_infallible(); - - let Some(comp) = ent.get_mut::<Target>() else { - unreachable!(); - }; - - comp - } - } - - #[must_use] - pub fn get_ent_infallible(&self) -> EntityHandle<'_> - { - let Some(ent) = self.get_entity() else { - unreachable!(); - }; - - ent - } +impl EventRelation for Changed {} + +/// [`EventMatch`] extension trait for component event matches. +pub trait EventMatchExt<Target>: sealed::Sealed +{ + #[must_use] + fn get_entity(&self) -> EntityHandle<'_>; + + #[must_use] + fn get_ent_target_comp(&self) -> ComponentHandle<'_, Target> + where + Target: Component; + + #[must_use] + fn get_ent_target_comp_mut(&self) -> ComponentHandleMut<'_, Target> + where + Target: Component; +} + +impl<ComponentEventRelation: EventRelation, Target> EventMatchExt<Target> + for EventMatch<'_, Pair<ComponentEventRelation, Target>> +where + Pair<ComponentEventRelation, Target>: Observed, +{ + fn get_entity(&self) -> EntityHandle<'_> + { + let Some(ent) = self.try_get_entity() else { + unreachable!(); + }; + + ent } -); + + fn get_ent_target_comp(&self) -> ComponentHandle<'_, Target> + where + Target: Component, + { + let ent = self.get_entity(); + + let Some(comp) = ent.get::<Target>() else { + unreachable!(); + }; + + comp + } + + fn get_ent_target_comp_mut(&self) -> ComponentHandleMut<'_, Target> + where + Target: Component, + { + let ent = self.get_entity(); + + let Some(comp) = ent.get_mut::<Target>() else { + unreachable!(); + }; + + comp + } +} + +impl<ComponentEventRelation: EventRelation, Target> sealed::Sealed + for EventMatch<'_, Pair<ComponentEventRelation, Target>> +where + Pair<ComponentEventRelation, Target>: Observed, +{ +} + +mod sealed +{ + pub trait Sealed {} +} diff --git a/ecs/src/system/observer.rs b/ecs/src/system/observer.rs index 236420c..0472614 100644 --- a/ecs/src/system/observer.rs +++ b/ecs/src/system/observer.rs @@ -138,14 +138,14 @@ pub struct EventMatch<'world, ObservedT: Observed> impl<'world, ObservedT: Observed> EventMatch<'world, ObservedT> { #[must_use] - pub fn id(&self) -> Uid + pub fn entity_id(&self) -> Uid { self.id } /// Attempts to get the entity with the id of this match. #[must_use] - pub fn get_entity(&self) -> Option<EntityHandle<'world>> + pub fn try_get_entity(&self) -> Option<EntityHandle<'world>> { self.world.get_entity(self.id) } |
