use crate::{ prelude::{Bundle, Trigger}, system::System, }; use super::IntoSystem; /// Implemented for systems that have an [`Observer`] as the first argument. /// /// [`Observer`]: crate::observer::Observer pub trait ObserverSystem: System, Out = Out> + Send + 'static { } impl< E: 'static, B: Bundle, Out, T: System, Out = Out> + Send + 'static, > ObserverSystem for T { } /// Implemented for systems that convert into [`ObserverSystem`]. #[diagnostic::on_unimplemented( message = "`{Self}` cannot become an `ObserverSystem`", label = "the trait `IntoObserverSystem` is not implemented", note = "for function `ObserverSystem`s, ensure the first argument is a `Trigger` and any subsequent ones are `SystemParam`" )] pub trait IntoObserverSystem: Send + 'static { /// The type of [`System`] that this instance converts into. type System: ObserverSystem; /// Turns this value into its corresponding [`System`]. fn into_system(this: Self) -> Self::System; } impl< S: IntoSystem, Out, M> + Send + 'static, M, Out, E: 'static, B: Bundle, > IntoObserverSystem for S where S::System: ObserverSystem, { type System = , Out, M>>::System; fn into_system(this: Self) -> Self::System { IntoSystem::into_system(this) } } #[cfg(test)] mod tests { use crate::{ self as bevy_ecs, event::Event, observer::Trigger, system::{In, IntoSystem}, world::World, }; #[derive(Event)] struct TriggerEvent; #[test] fn test_piped_observer_systems_no_input() { fn a(_: Trigger) {} fn b() {} let mut world = World::new(); world.observe(a.pipe(b)); } #[test] fn test_piped_observer_systems_with_inputs() { fn a(_: Trigger) -> u32 { 3 } fn b(_: In) {} let mut world = World::new(); world.observe(a.pipe(b)); } }