diff options
Diffstat (limited to 'engine-ecs/src/event/component.rs')
| -rw-r--r-- | engine-ecs/src/event/component.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/engine-ecs/src/event/component.rs b/engine-ecs/src/event/component.rs new file mode 100644 index 0000000..70ea3e5 --- /dev/null +++ b/engine-ecs/src/event/component.rs @@ -0,0 +1,103 @@ +//! Component events. + +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, 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. +/// b) The target component is added to a entity. +#[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 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 {} +} |
