diff options
-rw-r--r-- | ecs/examples/component_changed_event.rs | 8 | ||||
-rw-r--r-- | ecs/examples/component_events.rs | 8 | ||||
-rw-r--r-- | ecs/examples/component_removed_event.rs | 4 | ||||
-rw-r--r-- | ecs/src/event/component.rs | 51 | ||||
-rw-r--r-- | ecs/src/pair.rs | 18 | ||||
-rw-r--r-- | ecs/src/system/observer.rs | 23 | ||||
-rw-r--r-- | ecs/src/util.rs | 33 |
7 files changed, 106 insertions, 39 deletions
diff --git a/ecs/examples/component_changed_event.rs b/ecs/examples/component_changed_event.rs index 6dde384..1a53a88 100644 --- a/ecs/examples/component_changed_event.rs +++ b/ecs/examples/component_changed_event.rs @@ -33,13 +33,7 @@ fn print_changed_greetings(observe: Observe<'_, Pair<Changed, Greeting>>) println!("\nChanged greetings:"); for evt_match in &observe { - let Some(changed_ent) = evt_match.get_entity() else { - continue; - }; - - let Some(greeting) = changed_ent.get::<Greeting>() else { - unreachable!(); - }; + let greeting = evt_match.get_changed_comp(); println!("A greeting changed to {}", greeting.greeting); } diff --git a/ecs/examples/component_events.rs b/ecs/examples/component_events.rs index 4e7335f..af09ff9 100644 --- a/ecs/examples/component_events.rs +++ b/ecs/examples/component_events.rs @@ -33,9 +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 ent = evt_match.get_entity().unwrap(); - - let cheese = ent.get::<Cheese>().unwrap(); + let cheese = evt_match.get_removed_comp(); println!("{} cheese was eaten", cheese.name); } @@ -44,9 +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 ent = evt_match.get_entity().unwrap(); - - let cheese_crumbs = ent.get::<CheeseCrumbs>().unwrap(); + let cheese_crumbs = evt_match.get_changed_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 f984092..776aa48 100644 --- a/ecs/examples/component_removed_event.rs +++ b/ecs/examples/component_removed_event.rs @@ -24,9 +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 ent = evt_match.get_entity().unwrap(); - - let cheese = ent.get::<Cheese>().unwrap(); + let cheese = evt_match.get_removed_comp(); println!("{} cheese was eaten", cheese.name); } diff --git a/ecs/src/event/component.rs b/ecs/src/event/component.rs index 96761a6..ed6b7cf 100644 --- a/ecs/src/event/component.rs +++ b/ecs/src/event/component.rs @@ -2,6 +2,11 @@ use std::convert::Infallible; +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; /// Pair relation for events emitted when: @@ -18,3 +23,49 @@ pub struct Removed(Infallible); #[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 + } + } +); diff --git a/ecs/src/pair.rs b/ecs/src/pair.rs index f9f76e7..b4bfa57 100644 --- a/ecs/src/pair.rs +++ b/ecs/src/pair.rs @@ -61,8 +61,8 @@ impl<Relation, Target> Builder<Relation, Target> impl_multiple!( Builder, - (impl<Target> _<Uid, Target>, impl<Target> _<(), Target>) - (ty_param_1, ty_param_2) => { + (impl<Target> _<><Uid, Target>, impl<Target> _<><(), Target>) + cb=(type_params=(ty_param_1, ty_param_2)) => { pub fn target_as_data<NewTarget: Component>( self, data: NewTarget, @@ -78,8 +78,8 @@ impl_multiple!( impl_multiple!( Builder, - (impl<Relation> _<Relation, Uid>, impl<Relation> _<Relation, ()>) - (ty_param_1, ty_param_2) => { + (impl<Relation> _<><Relation, Uid>, impl<Relation> _<><Relation, ()>) + cb=(type_params=(ty_param_1, ty_param_2)) => { pub fn relation_as_data<NewRelation: Component>( self, data: NewRelation, @@ -96,12 +96,12 @@ impl_multiple!( impl_multiple!( Builder, ( - impl _<Uid, Uid>, - impl<Relation: Component> _<Relation, Uid>, - impl<Target: Component> _<Uid, Target>, - impl<Relation: Component, Target: Component> _<Relation, Target> + impl _<><Uid, Uid>, + impl<Relation: Component> _<><Relation, Uid>, + impl<Target: Component> _<><Uid, Target>, + impl<Relation: Component, Target: Component> _<><Relation, Target> ) - (ty_param_1, ty_param_2) => { + cb=(type_params=(ty_param_1, ty_param_2)) => { #[must_use] pub fn build(self) -> Pair<$ty_param_1, $ty_param_2> { diff --git a/ecs/src/system/observer.rs b/ecs/src/system/observer.rs index b7d84be..236420c 100644 --- a/ecs/src/system/observer.rs +++ b/ecs/src/system/observer.rs @@ -82,18 +82,19 @@ impl<'world, ObservedT: Observed> Observe<'world, ObservedT> impl<ObservedT: Observed> Observe<'_, ObservedT> { #[must_use] - pub fn iter(&self) -> ObserveIter<'_> + pub fn iter(&self) -> ObserveIter<'_, ObservedT> { ObserveIter { world: self.world, inner: self.emitted_event.match_ids.iter(), + _pd: PhantomData, } } } impl<'a, ObservedT: Observed> IntoIterator for &'a Observe<'_, ObservedT> { - type IntoIter = ObserveIter<'a>; + type IntoIter = ObserveIter<'a, ObservedT>; type Item = <Self::IntoIter as Iterator>::Item; fn into_iter(self) -> Self::IntoIter @@ -102,33 +103,39 @@ impl<'a, ObservedT: Observed> IntoIterator for &'a Observe<'_, ObservedT> } } -pub struct ObserveIter<'observe> +pub struct ObserveIter<'observe, ObservedT: Observed> { world: &'observe World, inner: SliceIter<'observe, Uid>, + _pd: PhantomData<ObservedT>, } -impl<'observe> Iterator for ObserveIter<'observe> +impl<'observe, ObservedT: Observed> Iterator for ObserveIter<'observe, ObservedT> { - type Item = EventMatch<'observe>; + type Item = EventMatch<'observe, ObservedT>; fn next(&mut self) -> Option<Self::Item> { let match_id = *self.inner.next()?; - Some(EventMatch { world: self.world, id: match_id }) + Some(EventMatch { + world: self.world, + id: match_id, + _pd: PhantomData, + }) } } /// A event match. #[derive(Debug)] -pub struct EventMatch<'world> +pub struct EventMatch<'world, ObservedT: Observed> { world: &'world World, id: Uid, + _pd: PhantomData<ObservedT>, } -impl<'world> EventMatch<'world> +impl<'world, ObservedT: Observed> EventMatch<'world, ObservedT> { #[must_use] pub fn id(&self) -> Uid diff --git a/ecs/src/util.rs b/ecs/src/util.rs index c18fd49..27e9748 100644 --- a/ecs/src/util.rs +++ b/ecs/src/util.rs @@ -303,8 +303,15 @@ pub(crate) use gen_mask_64; macro_rules! impl_multiple { ( $type: ident, - ($(impl$(<$($generic: tt$(: $bound: ident)?),*>)? _<$($type_param: ty),*>),*) - ($($ty_param_matcher: ident),*) => { + ($( + impl$(<$($generic: tt$(: $bound: ident)?),*>)? + _<$($lt_param: lifetime),*><$($type_param: ty),*> + $(($($extra_cb_arg: expr),*))? + ),*) + cb=( + type_params=($($ty_param_matcher: ident),*) + $(, $($extra_matcher: ident),+)? + ) => { $($item_tt: tt)* } ) => { @@ -313,13 +320,17 @@ macro_rules! impl_multiple { @(make_gen_item_macro) _gen_multiple_impl_item, ($($ty_param_matcher),*), + ($($($extra_matcher),+)?), ($($item_tt)*) ); $( - impl $(<$($generic$(: $bound)?,)*>)? $type<$($type_param),*> + impl $(<$($generic$(: $bound)?,)*>)? $type<$($lt_param,)* $($type_param),*> { - _gen_multiple_impl_item!($($type_param),*); + _gen_multiple_impl_item!( + type_params=($($type_param),*), + $($($extra_cb_arg),*)? + ); } )* }; @@ -329,11 +340,16 @@ macro_rules! impl_multiple { @(make_gen_item_macro) $name: ident, ($($ty_param_matcher: ident),*), + ($($extra_matcher: ident),*), ($($transcriber: tt)*) ) => { $crate::util::impl_multiple!( @(make_gen_item_macro) - ($), $name, ($($ty_param_matcher),*), ($($transcriber)*) + ($), + $name, + ($($ty_param_matcher),*), + ($($extra_matcher),*), + ($($transcriber)*) ); }; @@ -342,11 +358,16 @@ macro_rules! impl_multiple { ($dollar: tt), $name: ident, ($($ty_param_matcher: ident),*), + ($($extra_matcher: ident),*), ($($transcriber: tt)*) ) => { $crate::util::impl_multiple!( @(make_gen_item_macro) - $name, ($($dollar$ty_param_matcher: ty),*) => { + $name, + ( + type_params=($($dollar$ty_param_matcher: ty),*), + $($dollar$extra_matcher: expr),* + ) => { $($transcriber)* } ); |