Trait bevy::ecs::system::SystemParamFunction
[−]pub trait SystemParamFunction<In, Out, Param, Marker>: 'static + Send + Sync where
Param: SystemParam, {
fn run(
&mut self,
input: In,
param_value: <<Param as SystemParam>::Fetch as SystemParamFetch<'_, '_>>::Item
) -> Out;
}
Expand description
A trait implemented for all functions that can be used as System
s.
This trait can be useful for making your own systems which accept other systems, sometimes called higher order systems.
This should be used in combination with ParamSet
when calling other systems
within your system.
Using ParamSet
in this case avoids SystemParam
collisions.
Example
To create something like ChainSystem
, but in entirely safe code.
use std::num::ParseIntError;
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`.
/// Chain 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>(
mut a: A,
mut b: B,
) -> impl FnMut(In<AIn>, ParamSet<(SystemParamItem<AParam>, SystemParamItem<BParam>)>) -> BOut
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,
{
// The type of `params` is inferred based on the return of this function above
move |In(a_in), mut params| {
let shared = a.run(a_in, params.p0());
b.run(shared, params.p1())
}
}
// Usage example for `chain`:
fn main() {
let mut world = World::default();
world.insert_resource(Message("42".to_string()));
// chain the `parse_message_system`'s output into the `filter_system`s input
let mut chained_system = IntoSystem::into_system(chain(parse_message, filter));
chained_system.initialize(&mut world);
assert_eq!(chained_system.run((), &mut world), Some(42));
}
struct Message(String);
fn parse_message(message: Res<Message>) -> Result<usize, ParseIntError> {
message.0.parse::<usize>()
}
fn filter(In(result): In<Result<usize, ParseIntError>>) -> Option<usize> {
result.ok().filter(|&n| n < 100)
}