diff options
Diffstat (limited to 'ecs/src/event/component.rs')
| -rw-r--r-- | ecs/src/event/component.rs | 126 |
1 files changed, 79 insertions, 47 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 {} +} |
