bevy_ecs/system/
observer_system.rs

1use crate::{
2    prelude::{Bundle, Trigger},
3    system::System,
4};
5
6use super::IntoSystem;
7
8/// Implemented for [`System`]s that have a [`Trigger`] as the first argument.
9pub trait ObserverSystem<E: 'static, B: Bundle, Out = ()>:
10    System<In = Trigger<'static, E, B>, Out = Out> + Send + 'static
11{
12}
13
14impl<
15        E: 'static,
16        B: Bundle,
17        Out,
18        T: System<In = Trigger<'static, E, B>, Out = Out> + Send + 'static,
19    > ObserverSystem<E, B, Out> for T
20{
21}
22
23/// Implemented for systems that convert into [`ObserverSystem`].
24#[diagnostic::on_unimplemented(
25    message = "`{Self}` cannot become an `ObserverSystem`",
26    label = "the trait `IntoObserverSystem` is not implemented",
27    note = "for function `ObserverSystem`s, ensure the first argument is a `Trigger<T>` and any subsequent ones are `SystemParam`"
28)]
29pub trait IntoObserverSystem<E: 'static, B: Bundle, M, Out = ()>: Send + 'static {
30    /// The type of [`System`] that this instance converts into.
31    type System: ObserverSystem<E, B, Out>;
32
33    /// Turns this value into its corresponding [`System`].
34    fn into_system(this: Self) -> Self::System;
35}
36
37impl<
38        S: IntoSystem<Trigger<'static, E, B>, Out, M> + Send + 'static,
39        M,
40        Out,
41        E: 'static,
42        B: Bundle,
43    > IntoObserverSystem<E, B, M, Out> for S
44where
45    S::System: ObserverSystem<E, B, Out>,
46{
47    type System = <S as IntoSystem<Trigger<'static, E, B>, Out, M>>::System;
48
49    fn into_system(this: Self) -> Self::System {
50        IntoSystem::into_system(this)
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use crate::{
57        self as bevy_ecs,
58        event::Event,
59        observer::Trigger,
60        system::{In, IntoSystem},
61        world::World,
62    };
63
64    #[derive(Event)]
65    struct TriggerEvent;
66
67    #[test]
68    fn test_piped_observer_systems_no_input() {
69        fn a(_: Trigger<TriggerEvent>) {}
70        fn b() {}
71
72        let mut world = World::new();
73        world.add_observer(a.pipe(b));
74    }
75
76    #[test]
77    fn test_piped_observer_systems_with_inputs() {
78        fn a(_: Trigger<TriggerEvent>) -> u32 {
79            3
80        }
81        fn b(_: In<u32>) {}
82
83        let mut world = World::new();
84        world.add_observer(a.pipe(b));
85    }
86}