1use crate::ecs::{resources::Resources, system_param::SystemParam};
2
3pub struct Trigger<'a, E> {
6 event: &'a E,
7}
8
9impl<'a, E> std::ops::Deref for Trigger<'a, E> {
10 type Target = E;
11
12 fn deref(&self) -> &E {
13 self.event
14 }
15}
16
17pub trait ObserverSystem<E>: 'static {
19 fn run(&mut self, event: &E, world: &hecs::World, resources: &Resources);
20}
21
22pub struct FunctionObserver<F, E, Marker, State = ()> {
24 func: F,
25 state: State,
26 _marker: std::marker::PhantomData<(E, Marker)>,
27}
28
29pub trait IntoObserverSystem<E, Marker> {
32 type System: ObserverSystem<E>;
33
34 fn into_observer_system(self) -> Self::System;
35}
36
37macro_rules! impl_observer_system {
38 ($($param:ident),*) => {
39 impl<T, Evt: 'static, $($param),*> IntoObserverSystem<Evt, ($($param,)*)> for T
40 where
41 T: FnMut(Trigger<Evt>, $($param),*) + for<'a> FnMut(Trigger<'a, Evt>, $($param::Item<'a>),*) + 'static,
42 $($param: SystemParam + 'static),*
43 {
44 type System = FunctionObserver<T, Evt, ($($param,)*), ($($param::State,)*)>;
45 fn into_observer_system(self) -> Self::System {
46 FunctionObserver {
47 func: self,
48 state: Default::default(),
49 _marker: std::marker::PhantomData,
50 }
51 }
52 }
53 impl<T, Evt: 'static, $($param),*> ObserverSystem<Evt> for FunctionObserver<T, Evt, ($($param,)*), ($($param::State,)*)>
54 where
55 T: FnMut(Trigger<Evt>, $($param),*) + for<'a> FnMut(Trigger<'a, Evt>, $($param::Item<'a>),*) + 'static,
56 $($param: SystemParam + 'static),*
57 {
58 fn run(&mut self, _event: &Evt, _world: &hecs::World, _resources: &Resources) {
59 let trigger = Trigger { event: _event };
60 #[allow(non_snake_case)]
61 let ($($param,)*) = &mut self.state;
62 (self.func)(trigger, $($param::fetch(_world, _resources, $param)),*);
63 }
64 }
65 };
66}
67
68impl_observer_system!();
69impl_observer_system!(A);
70impl_observer_system!(A, B);
71impl_observer_system!(A, B, C);
72impl_observer_system!(A, B, C, D);
73impl_observer_system!(A, B, C, D, E);
74impl_observer_system!(A, B, C, D, E, F);
75impl_observer_system!(A, B, C, D, E, F, G);
76impl_observer_system!(A, B, C, D, E, F, G, H);
77impl_observer_system!(A, B, C, D, E, F, G, H, I);
78impl_observer_system!(A, B, C, D, E, F, G, H, I, J);
79impl_observer_system!(A, B, C, D, E, F, G, H, I, J, K);
80impl_observer_system!(A, B, C, D, E, F, G, H, I, J, K, L);
81
82pub(crate) struct Observers<E>(pub(crate) Vec<Box<dyn ObserverSystem<E>>>);
83
84impl<E> Default for Observers<E> {
85 fn default() -> Self {
86 Self(Vec::new())
87 }
88}