diff options
| author | HampusM <hampus@hampusmat.com> | 2026-04-29 17:19:34 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-04-30 16:53:56 +0200 |
| commit | bf86fdb20c1b983ec12352f51087b65baf196147 (patch) | |
| tree | bfa53d79ed577c109ae846fcd22f8229da980111 | |
| parent | 6c80b750e09f1996c56b45769937ca5a5d736bd8 (diff) | |
refactor(ecs): add ext trait for component event EventMatch fns
| -rw-r--r-- | ecs/examples/component_changed_event.rs | 4 | ||||
| -rw-r--r-- | ecs/examples/component_events.rs | 6 | ||||
| -rw-r--r-- | ecs/examples/component_removed_event.rs | 4 | ||||
| -rw-r--r-- | ecs/src/event/component.rs | 126 | ||||
| -rw-r--r-- | ecs/src/system/observer.rs | 4 |
5 files changed, 88 insertions, 56 deletions
diff --git a/ecs/examples/component_changed_event.rs b/ecs/examples/component_changed_event.rs index 1a53a88..2168df0 100644 --- a/ecs/examples/component_changed_event.rs +++ b/ecs/examples/component_changed_event.rs @@ -1,4 +1,4 @@ -use ecs::event::component::Changed; +use ecs::event::component::{Changed, EventMatchExt}; use ecs::pair::Pair; use ecs::phase::UPDATE as UPDATE_PHASE; use ecs::system::observer::Observe; @@ -33,7 +33,7 @@ fn print_changed_greetings(observe: Observe<'_, Pair<Changed, Greeting>>) println!("\nChanged greetings:"); for evt_match in &observe { - let greeting = evt_match.get_changed_comp(); + let greeting = evt_match.get_ent_target_comp(); println!("A greeting changed to {}", greeting.greeting); } diff --git a/ecs/examples/component_events.rs b/ecs/examples/component_events.rs index af09ff9..06e7fab 100644 --- a/ecs/examples/component_events.rs +++ b/ecs/examples/component_events.rs @@ -1,6 +1,6 @@ use ecs::actions::Actions; use ecs::component::Component; -use ecs::event::component::{Changed, Removed}; +use ecs::event::component::{Changed, EventMatchExt, Removed}; use ecs::pair::Pair; use ecs::phase::UPDATE; use ecs::system::observer::Observe; @@ -33,7 +33,7 @@ fn eat_cheese(query: Query<(&Cheese, &mut CheeseCrumbs)>, mut actions: Actions) fn on_cheese_removed(observe: Observe<Pair<Removed, Cheese>>) { for evt_match in &observe { - let cheese = evt_match.get_removed_comp(); + let cheese = evt_match.get_ent_target_comp(); println!("{} cheese was eaten", cheese.name); } @@ -42,7 +42,7 @@ fn on_cheese_removed(observe: Observe<Pair<Removed, Cheese>>) fn on_cheese_crumbs_changed(observe: Observe<Pair<Changed, CheeseCrumbs>>) { for evt_match in &observe { - let cheese_crumbs = evt_match.get_changed_comp(); + let cheese_crumbs = evt_match.get_ent_target_comp(); println!("Cheese crumbs count changed to {}", cheese_crumbs.cnt); } diff --git a/ecs/examples/component_removed_event.rs b/ecs/examples/component_removed_event.rs index 776aa48..9b73b1a 100644 --- a/ecs/examples/component_removed_event.rs +++ b/ecs/examples/component_removed_event.rs @@ -1,6 +1,6 @@ use ecs::actions::Actions; use ecs::component::Component; -use ecs::event::component::Removed; +use ecs::event::component::{EventMatchExt, Removed}; use ecs::pair::Pair; use ecs::phase::UPDATE; use ecs::system::observer::Observe; @@ -24,7 +24,7 @@ fn eat_cheese(query: Query<(&Cheese,)>, mut actions: Actions) fn on_cheese_removed(observe: Observe<Pair<Removed, Cheese>>) { for evt_match in &observe { - let cheese = evt_match.get_removed_comp(); + let cheese = evt_match.get_ent_target_comp(); println!("{} cheese was eaten", cheese.name); } 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) } |
