Simplify system piping and make it more flexible (#8377)
# Objective - Currently, it is not possible to call `.pipe` on a system that takes any input other than `()`. - The `IntoPipeSystem` trait is currently very difficult to parse due to its use of generics. ## Solution Remove the `IntoPipeSystem` trait, and move the `pipe` method to `IntoSystem`. --- ## Changelog - System piping has been made more flexible: it is now possible to call `.pipe` on a system that takes an input. ## Migration Guide The `IntoPipeSystem` trait has been removed, and the `pipe` method has been moved to the `IntoSystem` trait. ```rust // Before: use bevy_ecs::system::IntoPipeSystem; schedule.add_systems(first.pipe(second)); // After: use bevy_ecs::system::IntoSystem; schedule.add_systems(first.pipe(second)); ```
This commit is contained in:
		
							parent
							
								
									65292fd559
								
							
						
					
					
						commit
						b03b7b557e
					
				@ -46,8 +46,8 @@ pub mod prelude {
 | 
			
		||||
        system::{
 | 
			
		||||
            adapter as system_adapter,
 | 
			
		||||
            adapter::{dbg, error, ignore, info, unwrap, warn},
 | 
			
		||||
            Commands, Deferred, In, IntoPipeSystem, IntoSystem, Local, NonSend, NonSendMut,
 | 
			
		||||
            ParallelCommands, ParamSet, Query, Res, ResMut, Resource, System, SystemParamFunction,
 | 
			
		||||
            Commands, Deferred, In, IntoSystem, Local, NonSend, NonSendMut, ParallelCommands,
 | 
			
		||||
            ParamSet, Query, Res, ResMut, Resource, System, SystemParamFunction,
 | 
			
		||||
        },
 | 
			
		||||
        world::{FromWorld, World},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ use crate::{
 | 
			
		||||
use bevy_utils::all_tuples;
 | 
			
		||||
use std::{any::TypeId, borrow::Cow, marker::PhantomData};
 | 
			
		||||
 | 
			
		||||
use super::ReadOnlySystem;
 | 
			
		||||
use super::{PipeSystem, ReadOnlySystem};
 | 
			
		||||
 | 
			
		||||
/// The metadata of a [`System`].
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
@ -329,6 +329,20 @@ pub trait IntoSystem<In, Out, Marker>: Sized {
 | 
			
		||||
    type System: System<In = In, Out = Out>;
 | 
			
		||||
    /// Turns this value into its corresponding [`System`].
 | 
			
		||||
    fn into_system(this: Self) -> Self::System;
 | 
			
		||||
 | 
			
		||||
    /// Pass the output of this system `A` into a second system `B`, creating a new compound system.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The second system must have `In<T>` as its first parameter, where `T`
 | 
			
		||||
    /// is the return type of the first system.
 | 
			
		||||
    fn pipe<B, Final, MarkerB>(self, system: B) -> PipeSystem<Self::System, B::System>
 | 
			
		||||
    where
 | 
			
		||||
        B: IntoSystem<Out, Final, MarkerB>,
 | 
			
		||||
    {
 | 
			
		||||
        let system_a = IntoSystem::into_system(self);
 | 
			
		||||
        let system_b = IntoSystem::into_system(system);
 | 
			
		||||
        let name = format!("Pipe({}, {})", system_a.name(), system_b.name());
 | 
			
		||||
        PipeSystem::new(system_a, system_b, Cow::Owned(name))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Systems implicitly implement IntoSystem
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
use crate::system::{IntoSystem, System};
 | 
			
		||||
use std::borrow::Cow;
 | 
			
		||||
use crate::system::System;
 | 
			
		||||
 | 
			
		||||
use super::{CombinatorSystem, Combine};
 | 
			
		||||
 | 
			
		||||
@ -65,37 +64,6 @@ where
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// An extension trait providing the [`IntoPipeSystem::pipe`] method to pass input from one system into the next.
 | 
			
		||||
///
 | 
			
		||||
/// The first system must have return type `T`
 | 
			
		||||
/// and the second system must have [`In<T>`](crate::system::In) as its first system parameter.
 | 
			
		||||
///
 | 
			
		||||
/// This trait is blanket implemented for all system pairs that fulfill the type requirements.
 | 
			
		||||
///
 | 
			
		||||
/// See [`PipeSystem`].
 | 
			
		||||
pub trait IntoPipeSystem<ParamA, Payload, SystemB, ParamB, Out>:
 | 
			
		||||
    IntoSystem<(), Payload, ParamA> + Sized
 | 
			
		||||
where
 | 
			
		||||
    SystemB: IntoSystem<Payload, Out, ParamB>,
 | 
			
		||||
{
 | 
			
		||||
    /// Pass the output of this system `A` into a second system `B`, creating a new compound system.
 | 
			
		||||
    fn pipe(self, system: SystemB) -> PipeSystem<Self::System, SystemB::System>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<SystemA, ParamA, Payload, SystemB, ParamB, Out>
 | 
			
		||||
    IntoPipeSystem<ParamA, Payload, SystemB, ParamB, Out> for SystemA
 | 
			
		||||
where
 | 
			
		||||
    SystemA: IntoSystem<(), Payload, ParamA>,
 | 
			
		||||
    SystemB: IntoSystem<Payload, Out, ParamB>,
 | 
			
		||||
{
 | 
			
		||||
    fn pipe(self, system: SystemB) -> PipeSystem<SystemA::System, SystemB::System> {
 | 
			
		||||
        let system_a = IntoSystem::into_system(self);
 | 
			
		||||
        let system_b = IntoSystem::into_system(system);
 | 
			
		||||
        let name = format!("Pipe({}, {})", system_a.name(), system_b.name());
 | 
			
		||||
        PipeSystem::new(system_a, system_b, Cow::Owned(name))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// A collection of common adapters for [piping](super::PipeSystem) the result of a system.
 | 
			
		||||
pub mod adapter {
 | 
			
		||||
    use crate::system::In;
 | 
			
		||||
@ -313,7 +281,7 @@ mod tests {
 | 
			
		||||
    use bevy_utils::default;
 | 
			
		||||
 | 
			
		||||
    use super::adapter::*;
 | 
			
		||||
    use crate::{self as bevy_ecs, prelude::*, system::PipeSystem};
 | 
			
		||||
    use crate::{self as bevy_ecs, prelude::*};
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn assert_systems() {
 | 
			
		||||
@ -384,11 +352,7 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
        let mut world = World::new();
 | 
			
		||||
        world.init_resource::<Flag>();
 | 
			
		||||
        let mut sys = PipeSystem::new(
 | 
			
		||||
            IntoSystem::into_system(first),
 | 
			
		||||
            IntoSystem::into_system(second),
 | 
			
		||||
            "".into(),
 | 
			
		||||
        );
 | 
			
		||||
        let mut sys = first.pipe(second);
 | 
			
		||||
        sys.initialize(&mut world);
 | 
			
		||||
 | 
			
		||||
        sys.run(default(), &mut world);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user