From b03b7b557e8b60a348eb8818a3c2f4fa9a9c301e Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Mon, 17 Apr 2023 12:08:32 -0400 Subject: [PATCH] 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)); ``` --- crates/bevy_ecs/src/lib.rs | 4 +- crates/bevy_ecs/src/system/function_system.rs | 16 ++++++- crates/bevy_ecs/src/system/system_piping.rs | 42 ++----------------- 3 files changed, 20 insertions(+), 42 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index a5967a73ab..2e531493eb 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -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}, }; diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index e0401d4b72..bef4ee03b2 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -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: Sized { type System: System; /// 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` as its first parameter, where `T` + /// is the return type of the first system. + fn pipe(self, system: B) -> PipeSystem + where + B: IntoSystem, + { + 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 diff --git a/crates/bevy_ecs/src/system/system_piping.rs b/crates/bevy_ecs/src/system/system_piping.rs index cf3abdb7d4..8acb9a352f 100644 --- a/crates/bevy_ecs/src/system/system_piping.rs +++ b/crates/bevy_ecs/src/system/system_piping.rs @@ -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`](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: - IntoSystem<(), Payload, ParamA> + Sized -where - SystemB: IntoSystem, -{ - /// Pass the output of this system `A` into a second system `B`, creating a new compound system. - fn pipe(self, system: SystemB) -> PipeSystem; -} - -impl - IntoPipeSystem for SystemA -where - SystemA: IntoSystem<(), Payload, ParamA>, - SystemB: IntoSystem, -{ - fn pipe(self, system: SystemB) -> PipeSystem { - 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::(); - 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);