Simplify generics for the SystemParamFunction trait (#7675)
				
					
				
			# Objective
The `SystemParamFunction` (and `ExclusiveSystemParamFunction`) trait is very cumbersome to use, due to it requiring four generic type parameters. These are currently all used as marker parameters to satisfy rust's trait coherence rules.
### Example (before)
```rust
pub fn pipe<AIn, Shared, BOut, A, AParam, AMarker, B, BParam, BMarker>(
    mut system_a: A,
    mut system_b: B,
) -> impl FnMut(In<AIn>, ParamSet<(AParam, BParam)>) -> BOut
where
    A: SystemParamFunction<AIn, Shared, AParam, AMarker>,
    B: SystemParamFunction<Shared, BOut, BParam, BMarker>,
    AParam: SystemParam,
    BParam: SystemParam,
```
## Solution
Turn the `In`, `Out`, and `Param` generics into associated types. Merge the marker types together to retain coherence.
### Example (after)
```rust
pub fn pipe<A, B, AMarker, BMarker>(
    mut system_a: A,
    mut system_b: B,
) -> impl FnMut(In<A::In>, ParamSet<(A::Param, B::Param)>) -> B::Out
where
    A: SystemParamFunction<AMarker>,
    B: SystemParamFunction<BMarker, In = A::Out>,
```
---
## Changelog
+ Simplified the `SystemParamFunction` and `ExclusiveSystemParamFunction` traits.
## Migration Guide
For users of the `SystemParamFunction` trait, the generic type parameters `In`, `Out`, and `Param` have been turned into associated types. The same has been done with the `ExclusiveSystemParamFunction` trait.
			
			
This commit is contained in:
		
							parent
							
								
									11c7e5807a
								
							
						
					
					
						commit
						4f57f380c7
					
				@ -7,8 +7,7 @@ use bevy_utils::define_boxed_label;
 | 
			
		||||
use bevy_utils::label::DynHash;
 | 
			
		||||
 | 
			
		||||
use crate::system::{
 | 
			
		||||
    ExclusiveSystemParam, ExclusiveSystemParamFunction, IsExclusiveFunctionSystem,
 | 
			
		||||
    IsFunctionSystem, SystemParam, SystemParamFunction,
 | 
			
		||||
    ExclusiveSystemParamFunction, IsExclusiveFunctionSystem, IsFunctionSystem, SystemParamFunction,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
define_boxed_label!(ScheduleLabel);
 | 
			
		||||
@ -130,10 +129,9 @@ impl<S: SystemSet> IntoSystemSet<()> for S {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// systems
 | 
			
		||||
impl<In, Out, Param, Marker, F> IntoSystemSet<(IsFunctionSystem, In, Out, Param, Marker)> for F
 | 
			
		||||
impl<Marker, F> IntoSystemSet<(IsFunctionSystem, Marker)> for F
 | 
			
		||||
where
 | 
			
		||||
    Param: SystemParam,
 | 
			
		||||
    F: SystemParamFunction<In, Out, Param, Marker>,
 | 
			
		||||
    F: SystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    type Set = SystemTypeSet<Self>;
 | 
			
		||||
 | 
			
		||||
@ -144,11 +142,9 @@ where
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// exclusive systems
 | 
			
		||||
impl<In, Out, Param, Marker, F> IntoSystemSet<(IsExclusiveFunctionSystem, In, Out, Param, Marker)>
 | 
			
		||||
    for F
 | 
			
		||||
impl<Marker, F> IntoSystemSet<(IsExclusiveFunctionSystem, Marker)> for F
 | 
			
		||||
where
 | 
			
		||||
    Param: ExclusiveSystemParam,
 | 
			
		||||
    F: ExclusiveSystemParamFunction<In, Out, Param, Marker>,
 | 
			
		||||
    F: ExclusiveSystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    type Set = SystemTypeSet<Self>;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,30 +18,26 @@ use std::{any::TypeId, borrow::Cow, marker::PhantomData};
 | 
			
		||||
/// [`ExclusiveSystemParam`]s.
 | 
			
		||||
///
 | 
			
		||||
/// [`ExclusiveFunctionSystem`] must be `.initialized` before they can be run.
 | 
			
		||||
pub struct ExclusiveFunctionSystem<In, Out, Param, Marker, F>
 | 
			
		||||
pub struct ExclusiveFunctionSystem<Marker, F>
 | 
			
		||||
where
 | 
			
		||||
    Param: ExclusiveSystemParam,
 | 
			
		||||
    F: ExclusiveSystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    func: F,
 | 
			
		||||
    param_state: Option<Param::State>,
 | 
			
		||||
    param_state: Option<<F::Param as ExclusiveSystemParam>::State>,
 | 
			
		||||
    system_meta: SystemMeta,
 | 
			
		||||
    world_id: Option<WorldId>,
 | 
			
		||||
    // NOTE: PhantomData<fn()-> T> gives this safe Send/Sync impls
 | 
			
		||||
    marker: PhantomData<fn(In) -> (Out, Marker)>,
 | 
			
		||||
    marker: PhantomData<fn() -> Marker>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct IsExclusiveFunctionSystem;
 | 
			
		||||
 | 
			
		||||
impl<In, Out, Param, Marker, F> IntoSystem<In, Out, (IsExclusiveFunctionSystem, Param, Marker)>
 | 
			
		||||
    for F
 | 
			
		||||
impl<Marker, F> IntoSystem<F::In, F::Out, (IsExclusiveFunctionSystem, Marker)> for F
 | 
			
		||||
where
 | 
			
		||||
    In: 'static,
 | 
			
		||||
    Out: 'static,
 | 
			
		||||
    Param: ExclusiveSystemParam + 'static,
 | 
			
		||||
    Marker: 'static,
 | 
			
		||||
    F: ExclusiveSystemParamFunction<In, Out, Param, Marker> + Send + Sync + 'static,
 | 
			
		||||
    F: ExclusiveSystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    type System = ExclusiveFunctionSystem<In, Out, Param, Marker, F>;
 | 
			
		||||
    type System = ExclusiveFunctionSystem<Marker, F>;
 | 
			
		||||
    fn into_system(func: Self) -> Self::System {
 | 
			
		||||
        ExclusiveFunctionSystem {
 | 
			
		||||
            func,
 | 
			
		||||
@ -55,16 +51,13 @@ where
 | 
			
		||||
 | 
			
		||||
const PARAM_MESSAGE: &str = "System's param_state was not found. Did you forget to initialize this system before running it?";
 | 
			
		||||
 | 
			
		||||
impl<In, Out, Param, Marker, F> System for ExclusiveFunctionSystem<In, Out, Param, Marker, F>
 | 
			
		||||
impl<Marker, F> System for ExclusiveFunctionSystem<Marker, F>
 | 
			
		||||
where
 | 
			
		||||
    In: 'static,
 | 
			
		||||
    Out: 'static,
 | 
			
		||||
    Param: ExclusiveSystemParam + 'static,
 | 
			
		||||
    Marker: 'static,
 | 
			
		||||
    F: ExclusiveSystemParamFunction<In, Out, Param, Marker> + Send + Sync + 'static,
 | 
			
		||||
    F: ExclusiveSystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    type In = In;
 | 
			
		||||
    type Out = Out;
 | 
			
		||||
    type In = F::In;
 | 
			
		||||
    type Out = F::Out;
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn name(&self) -> Cow<'static, str> {
 | 
			
		||||
@ -103,7 +96,7 @@ where
 | 
			
		||||
        let saved_last_tick = world.last_change_tick;
 | 
			
		||||
        world.last_change_tick = self.system_meta.last_change_tick;
 | 
			
		||||
 | 
			
		||||
        let params = Param::get_param(
 | 
			
		||||
        let params = F::Param::get_param(
 | 
			
		||||
            self.param_state.as_mut().expect(PARAM_MESSAGE),
 | 
			
		||||
            &self.system_meta,
 | 
			
		||||
        );
 | 
			
		||||
@ -141,7 +134,7 @@ where
 | 
			
		||||
    fn initialize(&mut self, world: &mut World) {
 | 
			
		||||
        self.world_id = Some(world.id());
 | 
			
		||||
        self.system_meta.last_change_tick = world.change_tick().wrapping_sub(MAX_CHANGE_AGE);
 | 
			
		||||
        self.param_state = Some(Param::init(world, &mut self.system_meta));
 | 
			
		||||
        self.param_state = Some(F::Param::init(world, &mut self.system_meta));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn update_archetype_component_access(&mut self, _world: &World) {}
 | 
			
		||||
@ -165,27 +158,38 @@ where
 | 
			
		||||
///
 | 
			
		||||
/// This trait can be useful for making your own systems which accept other systems,
 | 
			
		||||
/// sometimes called higher order systems.
 | 
			
		||||
pub trait ExclusiveSystemParamFunction<In, Out, Param: ExclusiveSystemParam, Marker>:
 | 
			
		||||
    Send + Sync + 'static
 | 
			
		||||
{
 | 
			
		||||
pub trait ExclusiveSystemParamFunction<Marker>: Send + Sync + 'static {
 | 
			
		||||
    /// The input type to this system. See [`System::In`].
 | 
			
		||||
    type In;
 | 
			
		||||
 | 
			
		||||
    /// The return type of this system. See [`System::Out`].
 | 
			
		||||
    type Out;
 | 
			
		||||
 | 
			
		||||
    /// The [`ExclusiveSystemParam`]/s defined by this system's `fn` parameters.
 | 
			
		||||
    type Param: ExclusiveSystemParam;
 | 
			
		||||
 | 
			
		||||
    /// Executes this system once. See [`System::run`].
 | 
			
		||||
    fn run(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        world: &mut World,
 | 
			
		||||
        input: In,
 | 
			
		||||
        param_value: ExclusiveSystemParamItem<Param>,
 | 
			
		||||
    ) -> Out;
 | 
			
		||||
        input: Self::In,
 | 
			
		||||
        param_value: ExclusiveSystemParamItem<Self::Param>,
 | 
			
		||||
    ) -> Self::Out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! impl_exclusive_system_function {
 | 
			
		||||
    ($($param: ident),*) => {
 | 
			
		||||
        #[allow(non_snake_case)]
 | 
			
		||||
        impl<Out, Func: Send + Sync + 'static, $($param: ExclusiveSystemParam),*> ExclusiveSystemParamFunction<(), Out, ($($param,)*), ()> for Func
 | 
			
		||||
        impl<Out, Func: Send + Sync + 'static, $($param: ExclusiveSystemParam),*> ExclusiveSystemParamFunction<((), Out, $($param,)*)> for Func
 | 
			
		||||
        where
 | 
			
		||||
        for <'a> &'a mut Func:
 | 
			
		||||
                FnMut(&mut World, $($param),*) -> Out +
 | 
			
		||||
                FnMut(&mut World, $(ExclusiveSystemParamItem<$param>),*) -> Out,
 | 
			
		||||
            Out: 'static,
 | 
			
		||||
        {
 | 
			
		||||
            type In = ();
 | 
			
		||||
            type Out = Out;
 | 
			
		||||
            type Param = ($($param,)*);
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn run(&mut self, world: &mut World, _in: (), param_value: ExclusiveSystemParamItem< ($($param,)*)>) -> Out {
 | 
			
		||||
                // Yes, this is strange, but `rustc` fails to compile this impl
 | 
			
		||||
@ -204,13 +208,16 @@ macro_rules! impl_exclusive_system_function {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        #[allow(non_snake_case)]
 | 
			
		||||
        impl<Input, Out, Func: Send + Sync + 'static, $($param: ExclusiveSystemParam),*> ExclusiveSystemParamFunction<Input, Out, ($($param,)*), InputMarker> for Func
 | 
			
		||||
        impl<Input, Out, Func: Send + Sync + 'static, $($param: ExclusiveSystemParam),*> ExclusiveSystemParamFunction<(Input, Out, $($param,)* InputMarker)> for Func
 | 
			
		||||
        where
 | 
			
		||||
        for <'a> &'a mut Func:
 | 
			
		||||
                FnMut(In<Input>, &mut World, $($param),*) -> Out +
 | 
			
		||||
                FnMut(In<Input>, &mut World, $(ExclusiveSystemParamItem<$param>),*) -> Out,
 | 
			
		||||
            Out: 'static,
 | 
			
		||||
        {
 | 
			
		||||
            type In = Input;
 | 
			
		||||
            type Out = Out;
 | 
			
		||||
            type Param = ($($param,)*);
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn run(&mut self, world: &mut World, input: Input, param_value: ExclusiveSystemParamItem< ($($param,)*)>) -> Out {
 | 
			
		||||
                // Yes, this is strange, but `rustc` fails to compile this impl
 | 
			
		||||
 | 
			
		||||
@ -371,30 +371,27 @@ pub struct InputMarker;
 | 
			
		||||
/// becomes the functions [`In`] tagged parameter or `()` if no such parameter exists.
 | 
			
		||||
///
 | 
			
		||||
/// [`FunctionSystem`] must be `.initialized` before they can be run.
 | 
			
		||||
pub struct FunctionSystem<In, Out, Param, Marker, F>
 | 
			
		||||
pub struct FunctionSystem<Marker, F>
 | 
			
		||||
where
 | 
			
		||||
    Param: SystemParam,
 | 
			
		||||
    F: SystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    func: F,
 | 
			
		||||
    param_state: Option<Param::State>,
 | 
			
		||||
    param_state: Option<<F::Param as SystemParam>::State>,
 | 
			
		||||
    system_meta: SystemMeta,
 | 
			
		||||
    world_id: Option<WorldId>,
 | 
			
		||||
    archetype_generation: ArchetypeGeneration,
 | 
			
		||||
    // NOTE: PhantomData<fn()-> T> gives this safe Send/Sync impls
 | 
			
		||||
    marker: PhantomData<fn(In) -> (Out, Marker)>,
 | 
			
		||||
    marker: PhantomData<fn() -> Marker>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct IsFunctionSystem;
 | 
			
		||||
 | 
			
		||||
impl<In, Out, Param, Marker, F> IntoSystem<In, Out, (IsFunctionSystem, Param, Marker)> for F
 | 
			
		||||
impl<Marker, F> IntoSystem<F::In, F::Out, (IsFunctionSystem, Marker)> for F
 | 
			
		||||
where
 | 
			
		||||
    In: 'static,
 | 
			
		||||
    Out: 'static,
 | 
			
		||||
    Param: SystemParam + 'static,
 | 
			
		||||
    Marker: 'static,
 | 
			
		||||
    F: SystemParamFunction<In, Out, Param, Marker> + Send + Sync + 'static,
 | 
			
		||||
    F: SystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    type System = FunctionSystem<In, Out, Param, Marker, F>;
 | 
			
		||||
    type System = FunctionSystem<Marker, F>;
 | 
			
		||||
    fn into_system(func: Self) -> Self::System {
 | 
			
		||||
        FunctionSystem {
 | 
			
		||||
            func,
 | 
			
		||||
@ -407,9 +404,9 @@ where
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<In, Out, Param, Marker, F> FunctionSystem<In, Out, Param, Marker, F>
 | 
			
		||||
impl<Marker, F> FunctionSystem<Marker, F>
 | 
			
		||||
where
 | 
			
		||||
    Param: SystemParam,
 | 
			
		||||
    F: SystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    /// Message shown when a system isn't initialised
 | 
			
		||||
    // When lines get too long, rustfmt can sometimes refuse to format them.
 | 
			
		||||
@ -417,16 +414,13 @@ where
 | 
			
		||||
    const PARAM_MESSAGE: &'static str = "System's param_state was not found. Did you forget to initialize this system before running it?";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<In, Out, Param, Marker, F> System for FunctionSystem<In, Out, Param, Marker, F>
 | 
			
		||||
impl<Marker, F> System for FunctionSystem<Marker, F>
 | 
			
		||||
where
 | 
			
		||||
    In: 'static,
 | 
			
		||||
    Out: 'static,
 | 
			
		||||
    Param: SystemParam + 'static,
 | 
			
		||||
    Marker: 'static,
 | 
			
		||||
    F: SystemParamFunction<In, Out, Param, Marker> + Send + Sync + 'static,
 | 
			
		||||
    F: SystemParamFunction<Marker>,
 | 
			
		||||
{
 | 
			
		||||
    type In = In;
 | 
			
		||||
    type Out = Out;
 | 
			
		||||
    type In = F::In;
 | 
			
		||||
    type Out = F::Out;
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn name(&self) -> Cow<'static, str> {
 | 
			
		||||
@ -466,7 +460,7 @@ where
 | 
			
		||||
        // We update the archetype component access correctly based on `Param`'s requirements
 | 
			
		||||
        // in `update_archetype_component_access`.
 | 
			
		||||
        // Our caller upholds the requirements.
 | 
			
		||||
        let params = Param::get_param(
 | 
			
		||||
        let params = F::Param::get_param(
 | 
			
		||||
            self.param_state.as_mut().expect(Self::PARAM_MESSAGE),
 | 
			
		||||
            &self.system_meta,
 | 
			
		||||
            world,
 | 
			
		||||
@ -488,14 +482,14 @@ where
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn apply_buffers(&mut self, world: &mut World) {
 | 
			
		||||
        let param_state = self.param_state.as_mut().expect(Self::PARAM_MESSAGE);
 | 
			
		||||
        Param::apply(param_state, &self.system_meta, world);
 | 
			
		||||
        F::Param::apply(param_state, &self.system_meta, world);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn initialize(&mut self, world: &mut World) {
 | 
			
		||||
        self.world_id = Some(world.id());
 | 
			
		||||
        self.system_meta.last_change_tick = world.change_tick().wrapping_sub(MAX_CHANGE_AGE);
 | 
			
		||||
        self.param_state = Some(Param::init_state(world, &mut self.system_meta));
 | 
			
		||||
        self.param_state = Some(F::Param::init_state(world, &mut self.system_meta));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn update_archetype_component_access(&mut self, world: &World) {
 | 
			
		||||
@ -507,7 +501,7 @@ where
 | 
			
		||||
 | 
			
		||||
        for archetype_index in archetype_index_range {
 | 
			
		||||
            let param_state = self.param_state.as_mut().unwrap();
 | 
			
		||||
            Param::new_archetype(
 | 
			
		||||
            F::Param::new_archetype(
 | 
			
		||||
                param_state,
 | 
			
		||||
                &archetypes[ArchetypeId::new(archetype_index)],
 | 
			
		||||
                &mut self.system_meta,
 | 
			
		||||
@ -531,13 +525,11 @@ where
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// SAFETY: `F`'s param is `ReadOnlySystemParam`, so this system will only read from the world.
 | 
			
		||||
unsafe impl<In, Out, Param, Marker, F> ReadOnlySystem for FunctionSystem<In, Out, Param, Marker, F>
 | 
			
		||||
unsafe impl<Marker, F> ReadOnlySystem for FunctionSystem<Marker, F>
 | 
			
		||||
where
 | 
			
		||||
    In: 'static,
 | 
			
		||||
    Out: 'static,
 | 
			
		||||
    Param: ReadOnlySystemParam + 'static,
 | 
			
		||||
    Marker: 'static,
 | 
			
		||||
    F: SystemParamFunction<In, Out, Param, Marker> + Send + Sync + 'static,
 | 
			
		||||
    F: SystemParamFunction<Marker>,
 | 
			
		||||
    F::Param: ReadOnlySystemParam,
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -560,20 +552,15 @@ where
 | 
			
		||||
/// use bevy_ecs::prelude::*;
 | 
			
		||||
/// use bevy_ecs::system::{SystemParam, SystemParamItem};
 | 
			
		||||
///
 | 
			
		||||
/// // Unfortunately, we need all of these generics. `A` is the first system, with its
 | 
			
		||||
/// // parameters and marker type required for coherence. `B` is the second system, and
 | 
			
		||||
/// // the other generics are for the input/output types of `A` and `B`.
 | 
			
		||||
/// /// Pipe creates a new system which calls `a`, then calls `b` with the output of `a`
 | 
			
		||||
/// pub fn pipe<AIn, Shared, BOut, A, AParam, AMarker, B, BParam, BMarker>(
 | 
			
		||||
/// pub fn pipe<A, B, AMarker, BMarker>(
 | 
			
		||||
///     mut a: A,
 | 
			
		||||
///     mut b: B,
 | 
			
		||||
/// ) -> impl FnMut(In<AIn>, ParamSet<(AParam, BParam)>) -> BOut
 | 
			
		||||
/// ) -> impl FnMut(In<A::In>, ParamSet<(A::Param, B::Param)>) -> B::Out
 | 
			
		||||
/// where
 | 
			
		||||
///     // We need A and B to be systems, add those bounds
 | 
			
		||||
///     A: SystemParamFunction<AIn, Shared, AParam, AMarker>,
 | 
			
		||||
///     B: SystemParamFunction<Shared, BOut, BParam, BMarker>,
 | 
			
		||||
///     AParam: SystemParam,
 | 
			
		||||
///     BParam: SystemParam,
 | 
			
		||||
///     A: SystemParamFunction<AMarker>,
 | 
			
		||||
///     B: SystemParamFunction<BMarker, In = A::Out>,
 | 
			
		||||
/// {
 | 
			
		||||
///     // The type of `params` is inferred based on the return of this function above
 | 
			
		||||
///     move |In(a_in), mut params| {
 | 
			
		||||
@ -606,19 +593,32 @@ where
 | 
			
		||||
/// ```
 | 
			
		||||
/// [`PipeSystem`]: crate::system::PipeSystem
 | 
			
		||||
/// [`ParamSet`]: crate::system::ParamSet
 | 
			
		||||
pub trait SystemParamFunction<In, Out, Param: SystemParam, Marker>: Send + Sync + 'static {
 | 
			
		||||
    fn run(&mut self, input: In, param_value: SystemParamItem<Param>) -> Out;
 | 
			
		||||
pub trait SystemParamFunction<Marker>: Send + Sync + 'static {
 | 
			
		||||
    /// The input type to this system. See [`System::In`].
 | 
			
		||||
    type In;
 | 
			
		||||
 | 
			
		||||
    /// The return type of this system. See [`System::Out`].
 | 
			
		||||
    type Out;
 | 
			
		||||
 | 
			
		||||
    /// The [`SystemParam`]/s used by this system to access the [`World`].
 | 
			
		||||
    type Param: SystemParam;
 | 
			
		||||
 | 
			
		||||
    /// Executes this system once. See [`System::run`] or [`System::run_unsafe`].
 | 
			
		||||
    fn run(&mut self, input: Self::In, param_value: SystemParamItem<Self::Param>) -> Self::Out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! impl_system_function {
 | 
			
		||||
    ($($param: ident),*) => {
 | 
			
		||||
        #[allow(non_snake_case)]
 | 
			
		||||
        impl<Out, Func: Send + Sync + 'static, $($param: SystemParam),*> SystemParamFunction<(), Out, ($($param,)*), ()> for Func
 | 
			
		||||
        impl<Out, Func: Send + Sync + 'static, $($param: SystemParam),*> SystemParamFunction<((), Out, $($param,)*)> for Func
 | 
			
		||||
        where
 | 
			
		||||
        for <'a> &'a mut Func:
 | 
			
		||||
                FnMut($($param),*) -> Out +
 | 
			
		||||
                FnMut($(SystemParamItem<$param>),*) -> Out, Out: 'static
 | 
			
		||||
        {
 | 
			
		||||
            type In = ();
 | 
			
		||||
            type Out = Out;
 | 
			
		||||
            type Param = ($($param,)*);
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn run(&mut self, _input: (), param_value: SystemParamItem< ($($param,)*)>) -> Out {
 | 
			
		||||
                // Yes, this is strange, but `rustc` fails to compile this impl
 | 
			
		||||
@ -637,12 +637,15 @@ macro_rules! impl_system_function {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #[allow(non_snake_case)]
 | 
			
		||||
        impl<Input, Out, Func: Send + Sync + 'static, $($param: SystemParam),*> SystemParamFunction<Input, Out, ($($param,)*), InputMarker> for Func
 | 
			
		||||
        impl<Input, Out, Func: Send + Sync + 'static, $($param: SystemParam),*> SystemParamFunction<(Input, Out, $($param,)* InputMarker)> for Func
 | 
			
		||||
        where
 | 
			
		||||
        for <'a> &'a mut Func:
 | 
			
		||||
                FnMut(In<Input>, $($param),*) -> Out +
 | 
			
		||||
                FnMut(In<Input>, $(SystemParamItem<$param>),*) -> Out, Out: 'static
 | 
			
		||||
        {
 | 
			
		||||
            type In = Input;
 | 
			
		||||
            type Out = Out;
 | 
			
		||||
            type Param = ($($param,)*);
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn run(&mut self, input: Input, param_value: SystemParamItem< ($($param,)*)>) -> Out {
 | 
			
		||||
                #[allow(clippy::too_many_arguments)]
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user