mirror of
https://github.com/bevyengine/bevy
synced 2024-11-28 23:50:20 +00:00
Rename system chaining to system piping (#6230)
# Objective > System chaining is a confusing name: it implies the ability to construct non-linear graphs, and suggests a sense of system ordering that is only incidentally true. Instead, it actually works by passing data from one system to the next, much like the pipe operator. > In the accepted [stageless RFC](https://github.com/bevyengine/rfcs/blob/main/rfcs/45-stageless.md), this concept is renamed to piping, and "system chaining" is used to construct groups of systems with ordering dependencies between them. Fixes #6225. ## Changelog System chaining has been renamed to system piping to improve clarity (and free up the name for new ordering APIs). ## Migration Guide The `.chain(handler_system)` method on systems is now `.pipe(handler_system)`. The `IntoChainSystem` trait is now `IntoPipeSystem`, and the `ChainSystem` struct is now `PipeSystem`.
This commit is contained in:
parent
6ce7ce208e
commit
c0a93aa7a4
8 changed files with 62 additions and 60 deletions
10
Cargo.toml
10
Cargo.toml
|
@ -872,12 +872,12 @@ category = "ECS (Entity Component System)"
|
||||||
wasm = false
|
wasm = false
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "system_chaining"
|
name = "system_piping"
|
||||||
path = "examples/ecs/system_chaining.rs"
|
path = "examples/ecs/system_piping.rs"
|
||||||
|
|
||||||
[package.metadata.example.system_chaining]
|
[package.metadata.example.system_piping]
|
||||||
name = "System Chaining"
|
name = "System Piping"
|
||||||
description = "Chain two systems together, specifying a return type in a system (such as `Result`)"
|
description = "Pipe the output of one system into a second, allowing you to handle any errors gracefully"
|
||||||
category = "ECS (Entity Component System)"
|
category = "ECS (Entity Component System)"
|
||||||
wasm = false
|
wasm = false
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub mod prelude {
|
||||||
Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, SystemStage,
|
Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, SystemStage,
|
||||||
},
|
},
|
||||||
system::{
|
system::{
|
||||||
adapter as system_adapter, Commands, In, IntoChainSystem, IntoSystem, Local, NonSend,
|
adapter as system_adapter, Commands, In, IntoPipeSystem, IntoSystem, Local, NonSend,
|
||||||
NonSendMut, ParallelCommands, ParamSet, Query, RemovedComponents, Res, ResMut,
|
NonSendMut, ParallelCommands, ParamSet, Query, RemovedComponents, Res, ResMut,
|
||||||
Resource, System, SystemParamFunction,
|
Resource, System, SystemParamFunction,
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
||||||
RunCriteriaDescriptor, RunCriteriaDescriptorCoercion, RunCriteriaLabel, ShouldRun,
|
RunCriteriaDescriptor, RunCriteriaDescriptorCoercion, RunCriteriaLabel, ShouldRun,
|
||||||
SystemSet,
|
SystemSet,
|
||||||
},
|
},
|
||||||
system::{In, IntoChainSystem, Local, Res, ResMut, Resource},
|
system::{In, IntoPipeSystem, Local, Res, ResMut, Resource},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
|
@ -79,7 +79,7 @@ where
|
||||||
(move |state: Res<State<T>>| {
|
(move |state: Res<State<T>>| {
|
||||||
state.stack.last().unwrap() == &pred && state.transition.is_none()
|
state.stack.last().unwrap() == &pred && state.transition.is_none()
|
||||||
})
|
})
|
||||||
.chain(should_run_adapter::<T>)
|
.pipe(should_run_adapter::<T>)
|
||||||
.after(DriverLabel::of::<T>())
|
.after(DriverLabel::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ where
|
||||||
Some(_) => false,
|
Some(_) => false,
|
||||||
None => *is_inactive,
|
None => *is_inactive,
|
||||||
})
|
})
|
||||||
.chain(should_run_adapter::<T>)
|
.pipe(should_run_adapter::<T>)
|
||||||
.after(DriverLabel::of::<T>())
|
.after(DriverLabel::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ where
|
||||||
Some(_) => false,
|
Some(_) => false,
|
||||||
None => *is_in_stack,
|
None => *is_in_stack,
|
||||||
})
|
})
|
||||||
.chain(should_run_adapter::<T>)
|
.pipe(should_run_adapter::<T>)
|
||||||
.after(DriverLabel::of::<T>())
|
.after(DriverLabel::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ where
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.chain(should_run_adapter::<T>)
|
.pipe(should_run_adapter::<T>)
|
||||||
.after(DriverLabel::of::<T>())
|
.after(DriverLabel::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ where
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.chain(should_run_adapter::<T>)
|
.pipe(should_run_adapter::<T>)
|
||||||
.after(DriverLabel::of::<T>())
|
.after(DriverLabel::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ where
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.chain(should_run_adapter::<T>)
|
.pipe(should_run_adapter::<T>)
|
||||||
.after(DriverLabel::of::<T>())
|
.after(DriverLabel::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ where
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.chain(should_run_adapter::<T>)
|
.pipe(should_run_adapter::<T>)
|
||||||
.after(DriverLabel::of::<T>())
|
.after(DriverLabel::of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -499,7 +499,7 @@ impl<T> Copy for SystemTypeIdLabel<T> {}
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// To create something like [`ChainSystem`], but in entirely safe code.
|
/// To create something like [`PipeSystem`], but in entirely safe code.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use std::num::ParseIntError;
|
/// use std::num::ParseIntError;
|
||||||
|
@ -510,8 +510,8 @@ impl<T> Copy for SystemTypeIdLabel<T> {}
|
||||||
/// // Unfortunately, we need all of these generics. `A` is the first system, with its
|
/// // 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
|
/// // 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`.
|
/// // the other generics are for the input/output types of `A` and `B`.
|
||||||
/// /// Chain creates a new system which calls `a`, then calls `b` with the output of `a`
|
/// /// Pipe creates a new system which calls `a`, then calls `b` with the output of `a`
|
||||||
/// pub fn chain<AIn, Shared, BOut, A, AParam, AMarker, B, BParam, BMarker>(
|
/// pub fn pipe<AIn, Shared, BOut, A, AParam, AMarker, B, BParam, BMarker>(
|
||||||
/// mut a: A,
|
/// mut a: A,
|
||||||
/// mut b: B,
|
/// mut b: B,
|
||||||
/// ) -> impl FnMut(In<AIn>, ParamSet<(SystemParamItem<AParam>, SystemParamItem<BParam>)>) -> BOut
|
/// ) -> impl FnMut(In<AIn>, ParamSet<(SystemParamItem<AParam>, SystemParamItem<BParam>)>) -> BOut
|
||||||
|
@ -529,15 +529,15 @@ impl<T> Copy for SystemTypeIdLabel<T> {}
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// // Usage example for `chain`:
|
/// // Usage example for `pipe`:
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let mut world = World::default();
|
/// let mut world = World::default();
|
||||||
/// world.insert_resource(Message("42".to_string()));
|
/// world.insert_resource(Message("42".to_string()));
|
||||||
///
|
///
|
||||||
/// // chain the `parse_message_system`'s output into the `filter_system`s input
|
/// // pipe the `parse_message_system`'s output into the `filter_system`s input
|
||||||
/// let mut chained_system = IntoSystem::into_system(chain(parse_message, filter));
|
/// let mut piped_system = IntoSystem::into_system(pipe(parse_message, filter));
|
||||||
/// chained_system.initialize(&mut world);
|
/// piped_system.initialize(&mut world);
|
||||||
/// assert_eq!(chained_system.run((), &mut world), Some(42));
|
/// assert_eq!(piped_system.run((), &mut world), Some(42));
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[derive(Resource)]
|
/// #[derive(Resource)]
|
||||||
|
@ -551,7 +551,7 @@ impl<T> Copy for SystemTypeIdLabel<T> {}
|
||||||
/// result.ok().filter(|&n| n < 100)
|
/// result.ok().filter(|&n| n < 100)
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// [`ChainSystem`]: crate::system::ChainSystem
|
/// [`PipeSystem`]: crate::system::PipeSystem
|
||||||
/// [`ParamSet`]: crate::system::ParamSet
|
/// [`ParamSet`]: crate::system::ParamSet
|
||||||
pub trait SystemParamFunction<In, Out, Param: SystemParam, Marker>: Send + Sync + 'static {
|
pub trait SystemParamFunction<In, Out, Param: SystemParam, Marker>: Send + Sync + 'static {
|
||||||
fn run(&mut self, input: In, param_value: SystemParamItem<Param>) -> Out;
|
fn run(&mut self, input: In, param_value: SystemParamItem<Param>) -> Out;
|
||||||
|
|
|
@ -75,8 +75,8 @@ mod function_system;
|
||||||
mod query;
|
mod query;
|
||||||
#[allow(clippy::module_inception)]
|
#[allow(clippy::module_inception)]
|
||||||
mod system;
|
mod system;
|
||||||
mod system_chaining;
|
|
||||||
mod system_param;
|
mod system_param;
|
||||||
|
mod system_piping;
|
||||||
|
|
||||||
pub use commands::*;
|
pub use commands::*;
|
||||||
pub use exclusive_function_system::*;
|
pub use exclusive_function_system::*;
|
||||||
|
@ -84,8 +84,8 @@ pub use exclusive_system_param::*;
|
||||||
pub use function_system::*;
|
pub use function_system::*;
|
||||||
pub use query::*;
|
pub use query::*;
|
||||||
pub use system::*;
|
pub use system::*;
|
||||||
pub use system_chaining::*;
|
|
||||||
pub use system_param::*;
|
pub use system_param::*;
|
||||||
|
pub use system_piping::*;
|
||||||
|
|
||||||
/// Ensure that a given function is a system
|
/// Ensure that a given function is a system
|
||||||
///
|
///
|
||||||
|
|
|
@ -7,10 +7,11 @@ use crate::{
|
||||||
};
|
};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
/// A [`System`] that chains two systems together, creating a new system that routes the output of
|
/// A [`System`] created by piping the output of the first system into the input of the second.
|
||||||
/// the first system into the input of the second system, yielding the output of the second system.
|
|
||||||
///
|
///
|
||||||
/// Given two systems `A` and `B`, A may be chained with `B` as `A.chain(B)` if the output type of `A` is
|
/// This can be repeated indefinitely, but system pipes cannot branch: the output is consumed by the receiving system.
|
||||||
|
///
|
||||||
|
/// Given two systems `A` and `B`, A may be piped into `B` as `A.pipe(B)` if the output type of `A` is
|
||||||
/// equal to the input type of `B`.
|
/// equal to the input type of `B`.
|
||||||
///
|
///
|
||||||
/// Note that for [`FunctionSystem`](crate::system::FunctionSystem)s the output is the return value
|
/// Note that for [`FunctionSystem`](crate::system::FunctionSystem)s the output is the return value
|
||||||
|
@ -28,10 +29,10 @@ use std::borrow::Cow;
|
||||||
/// let mut world = World::default();
|
/// let mut world = World::default();
|
||||||
/// world.insert_resource(Message("42".to_string()));
|
/// world.insert_resource(Message("42".to_string()));
|
||||||
///
|
///
|
||||||
/// // chain the `parse_message_system`'s output into the `filter_system`s input
|
/// // pipe the `parse_message_system`'s output into the `filter_system`s input
|
||||||
/// let mut chained_system = parse_message_system.chain(filter_system);
|
/// let mut piped_system = parse_message_system.pipe(filter_system);
|
||||||
/// chained_system.initialize(&mut world);
|
/// piped_system.initialize(&mut world);
|
||||||
/// assert_eq!(chained_system.run((), &mut world), Some(42));
|
/// assert_eq!(piped_system.run((), &mut world), Some(42));
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[derive(Resource)]
|
/// #[derive(Resource)]
|
||||||
|
@ -45,7 +46,7 @@ use std::borrow::Cow;
|
||||||
/// result.ok().filter(|&n| n < 100)
|
/// result.ok().filter(|&n| n < 100)
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct ChainSystem<SystemA, SystemB> {
|
pub struct PipeSystem<SystemA, SystemB> {
|
||||||
system_a: SystemA,
|
system_a: SystemA,
|
||||||
system_b: SystemB,
|
system_b: SystemB,
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
|
@ -53,7 +54,7 @@ pub struct ChainSystem<SystemA, SystemB> {
|
||||||
archetype_component_access: Access<ArchetypeComponentId>,
|
archetype_component_access: Access<ArchetypeComponentId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SystemA: System, SystemB: System<In = SystemA::Out>> System for ChainSystem<SystemA, SystemB> {
|
impl<SystemA: System, SystemB: System<In = SystemA::Out>> System for PipeSystem<SystemA, SystemB> {
|
||||||
type In = SystemA::In;
|
type In = SystemA::In;
|
||||||
type Out = SystemB::Out;
|
type Out = SystemB::Out;
|
||||||
|
|
||||||
|
@ -121,33 +122,34 @@ impl<SystemA: System, SystemB: System<In = SystemA::Out>> System for ChainSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An extension trait providing the [`IntoChainSystem::chain`] method for convenient [`System`]
|
/// An extension trait providing the [`IntoPipeSystem::pipe`] method to pass input from one system into the next.
|
||||||
/// chaining.
|
|
||||||
///
|
///
|
||||||
/// This trait is blanket implemented for all system pairs that fulfill the chaining requirement.
|
/// The first system must have return type `T`
|
||||||
|
/// and the second system must have [`In<T>`](crate::system::In) as its first system parameter.
|
||||||
///
|
///
|
||||||
/// See [`ChainSystem`].
|
/// This trait is blanket implemented for all system pairs that fulfill the type requirements.
|
||||||
pub trait IntoChainSystem<ParamA, Payload, SystemB, ParamB, Out>:
|
///
|
||||||
|
/// See [`PipeSystem`].
|
||||||
|
pub trait IntoPipeSystem<ParamA, Payload, SystemB, ParamB, Out>:
|
||||||
IntoSystem<(), Payload, ParamA> + Sized
|
IntoSystem<(), Payload, ParamA> + Sized
|
||||||
where
|
where
|
||||||
SystemB: IntoSystem<Payload, Out, ParamB>,
|
SystemB: IntoSystem<Payload, Out, ParamB>,
|
||||||
{
|
{
|
||||||
/// Chain this system `A` with another system `B` creating a new system that feeds system A's
|
/// Pass the output of this system `A` into a second system `B`, creating a new compound system.
|
||||||
/// output into system `B`, returning the output of system `B`.
|
fn pipe(self, system: SystemB) -> PipeSystem<Self::System, SystemB::System>;
|
||||||
fn chain(self, system: SystemB) -> ChainSystem<Self::System, SystemB::System>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SystemA, ParamA, Payload, SystemB, ParamB, Out>
|
impl<SystemA, ParamA, Payload, SystemB, ParamB, Out>
|
||||||
IntoChainSystem<ParamA, Payload, SystemB, ParamB, Out> for SystemA
|
IntoPipeSystem<ParamA, Payload, SystemB, ParamB, Out> for SystemA
|
||||||
where
|
where
|
||||||
SystemA: IntoSystem<(), Payload, ParamA>,
|
SystemA: IntoSystem<(), Payload, ParamA>,
|
||||||
SystemB: IntoSystem<Payload, Out, ParamB>,
|
SystemB: IntoSystem<Payload, Out, ParamB>,
|
||||||
{
|
{
|
||||||
fn chain(self, system: SystemB) -> ChainSystem<SystemA::System, SystemB::System> {
|
fn pipe(self, system: SystemB) -> PipeSystem<SystemA::System, SystemB::System> {
|
||||||
let system_a = IntoSystem::into_system(self);
|
let system_a = IntoSystem::into_system(self);
|
||||||
let system_b = IntoSystem::into_system(system);
|
let system_b = IntoSystem::into_system(system);
|
||||||
ChainSystem {
|
PipeSystem {
|
||||||
name: Cow::Owned(format!("Chain({}, {})", system_a.name(), system_b.name())),
|
name: Cow::Owned(format!("Pipe({}, {})", system_a.name(), system_b.name())),
|
||||||
system_a,
|
system_a,
|
||||||
system_b,
|
system_b,
|
||||||
archetype_component_access: Default::default(),
|
archetype_component_access: Default::default(),
|
||||||
|
@ -156,7 +158,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of common adapters for [chaining](super::ChainSystem) the result of a system.
|
/// A collection of common adapters for [piping](super::PipeSystem) the result of a system.
|
||||||
pub mod adapter {
|
pub mod adapter {
|
||||||
use crate::system::In;
|
use crate::system::In;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -168,9 +170,9 @@ pub mod adapter {
|
||||||
/// use bevy_ecs::prelude::*;
|
/// use bevy_ecs::prelude::*;
|
||||||
///
|
///
|
||||||
/// return1
|
/// return1
|
||||||
/// .chain(system_adapter::new(u32::try_from))
|
/// .pipe(system_adapter::new(u32::try_from))
|
||||||
/// .chain(system_adapter::unwrap)
|
/// .pipe(system_adapter::unwrap)
|
||||||
/// .chain(print);
|
/// .pipe(print);
|
||||||
///
|
///
|
||||||
/// fn return1() -> u64 { 1 }
|
/// fn return1() -> u64 { 1 }
|
||||||
/// fn print(In(x): In<impl std::fmt::Debug>) {
|
/// fn print(In(x): In<impl std::fmt::Debug>) {
|
||||||
|
@ -204,7 +206,7 @@ pub mod adapter {
|
||||||
/// .add_system_to_stage(
|
/// .add_system_to_stage(
|
||||||
/// CoreStage::Update,
|
/// CoreStage::Update,
|
||||||
/// // Panic if the load system returns an error.
|
/// // Panic if the load system returns an error.
|
||||||
/// load_save_system.chain(system_adapter::unwrap)
|
/// load_save_system.pipe(system_adapter::unwrap)
|
||||||
/// )
|
/// )
|
||||||
/// // ...
|
/// // ...
|
||||||
/// # ;
|
/// # ;
|
||||||
|
@ -224,7 +226,7 @@ pub mod adapter {
|
||||||
res.unwrap()
|
res.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// System adapter that ignores the output of the previous system in a chain.
|
/// System adapter that ignores the output of the previous system in a pipe.
|
||||||
/// This is useful for fallible systems that should simply return early in case of an `Err`/`None`.
|
/// This is useful for fallible systems that should simply return early in case of an `Err`/`None`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -248,7 +250,7 @@ pub mod adapter {
|
||||||
/// .add_system_to_stage(
|
/// .add_system_to_stage(
|
||||||
/// CoreStage::Update,
|
/// CoreStage::Update,
|
||||||
/// // If the system fails, just move on and try again next frame.
|
/// // If the system fails, just move on and try again next frame.
|
||||||
/// fallible_system.chain(system_adapter::ignore)
|
/// fallible_system.pipe(system_adapter::ignore)
|
||||||
/// )
|
/// )
|
||||||
/// // ...
|
/// // ...
|
||||||
/// # ;
|
/// # ;
|
||||||
|
@ -278,8 +280,8 @@ pub mod adapter {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_is_system(returning::<Result<u32, std::io::Error>>.chain(unwrap));
|
assert_is_system(returning::<Result<u32, std::io::Error>>.pipe(unwrap));
|
||||||
assert_is_system(returning::<Option<()>>.chain(ignore));
|
assert_is_system(returning::<Option<()>>.pipe(ignore));
|
||||||
assert_is_system(returning::<&str>.chain(new(u64::from_str)).chain(unwrap));
|
assert_is_system(returning::<&str>.pipe(new(u64::from_str)).pipe(unwrap));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -199,9 +199,9 @@ Example | Description
|
||||||
[Removal Detection](../examples/ecs/removal_detection.rs) | Query for entities that had a specific component removed in a previous stage during the current frame
|
[Removal Detection](../examples/ecs/removal_detection.rs) | Query for entities that had a specific component removed in a previous stage during the current frame
|
||||||
[Startup System](../examples/ecs/startup_system.rs) | Demonstrates a startup system (one that runs once when the app starts up)
|
[Startup System](../examples/ecs/startup_system.rs) | Demonstrates a startup system (one that runs once when the app starts up)
|
||||||
[State](../examples/ecs/state.rs) | Illustrates how to use States to control transitioning from a Menu state to an InGame state
|
[State](../examples/ecs/state.rs) | Illustrates how to use States to control transitioning from a Menu state to an InGame state
|
||||||
[System Chaining](../examples/ecs/system_chaining.rs) | Chain two systems together, specifying a return type in a system (such as `Result`)
|
|
||||||
[System Closure](../examples/ecs/system_closure.rs) | Show how to use closures as systems, and how to configure `Local` variables by capturing external state
|
[System Closure](../examples/ecs/system_closure.rs) | Show how to use closures as systems, and how to configure `Local` variables by capturing external state
|
||||||
[System Parameter](../examples/ecs/system_param.rs) | Illustrates creating custom system parameters with `SystemParam`
|
[System Parameter](../examples/ecs/system_param.rs) | Illustrates creating custom system parameters with `SystemParam`
|
||||||
|
[System Piping](../examples/ecs/system_piping.rs) | Pipe the output of one system into a second, allowing you to handle any errors gracefully
|
||||||
[System Sets](../examples/ecs/system_sets.rs) | Shows `SystemSet` use along with run criterion
|
[System Sets](../examples/ecs/system_sets.rs) | Shows `SystemSet` use along with run criterion
|
||||||
[Timers](../examples/ecs/timers.rs) | Illustrates ticking `Timer` resources inside systems and handling their state
|
[Timers](../examples/ecs/timers.rs) | Illustrates ticking `Timer` resources inside systems and handling their state
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Illustrates how to make a single system from multiple functions running in sequence and sharing
|
//! Illustrates how to make a single system from multiple functions running in sequence,
|
||||||
//! their inputs and outputs.
|
//! passing the output of the first into the input of the next.
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
@ -7,7 +7,7 @@ use bevy::prelude::*;
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.insert_resource(Message("42".to_string()))
|
.insert_resource(Message("42".to_string()))
|
||||||
.add_system(parse_message_system.chain(handler_system))
|
.add_system(parse_message_system.pipe(handler_system))
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue