use bevy_utils::all_tuples; use crate::{ prelude::{Bundle, Trigger}, system::{System, SystemParam, SystemParamFunction, SystemParamItem}, }; use super::IntoSystem; /// Implemented for systems that have an [`Observer`] as the first argument. /// /// [`Observer`]: crate::observer::Observer pub trait ObserverSystem: System, Out = ()> + Send + 'static { } impl, Out = ()> + Send + 'static> ObserverSystem for T { } /// Implemented for systems that convert into [`ObserverSystem`]. 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, (), M> + Send + 'static, M, E: 'static, B: Bundle> IntoObserverSystem for S where S::System: ObserverSystem, { type System = , (), M>>::System; fn into_system(this: Self) -> Self::System { IntoSystem::into_system(this) } } macro_rules! impl_system_function { ($($param: ident),*) => { #[allow(non_snake_case)] impl SystemParamFunction, $($param,)*)> for Func where for <'a> &'a mut Func: FnMut(Trigger, $($param),*) + FnMut(Trigger, $(SystemParamItem<$param>),*) { type In = Trigger<'static, E, B>; type Out = (); type Param = ($($param,)*); #[inline] fn run(&mut self, input: Trigger<'static, E, B>, param_value: SystemParamItem< ($($param,)*)>) { #[allow(clippy::too_many_arguments)] fn call_inner( mut f: impl FnMut(Trigger<'static, E, B>, $($param,)*), input: Trigger<'static, E, B>, $($param: $param,)* ){ f(input, $($param,)*) } let ($($param,)*) = param_value; call_inner(self, input, $($param),*) } } } } all_tuples!(impl_system_function, 0, 16, F);