Skip to content

Commit

Permalink
Add 'World::run_system_with_input' function + allow `World::run_syste…
Browse files Browse the repository at this point in the history
…m` to get system output (#10380)

# Objective

Allows chained systems taking an `In<_>` input parameter to be run as
one-shot systems. This API was mentioned in #8963.

In addition, `run_system(_with_input)` returns the system output, for
any `'static` output type.

## Solution

A new function, `World::run_system_with_input` allows a `SystemId<I, O>`
to be run by providing an `I` value as input and producing `O` as an
output.

`SystemId<I, O>` is now generic over the input type `I` and output type
`O`, along with the related functions and types `RegisteredSystem`,
`RemovedSystem`, `register_system`, `remove_system`, and
`RegisteredSystemError`. These default to `()`, preserving the existing
API, for all of the public types.

---

## Changelog

- Added `World::run_system_with_input` function to allow one-shot
systems that take `In<_>` input parameters
- Changed `World::run_system` and `World::register_system` to support
systems with return types beyond `()`
- Added `Commands::run_system_with_input` command that schedules a
one-shot system with an `In<_>` input parameter
  • Loading branch information
Nathan-Fenner committed Nov 15, 2023
1 parent bad55c1 commit 1f05e1e
Show file tree
Hide file tree
Showing 2 changed files with 308 additions and 38 deletions.
22 changes: 20 additions & 2 deletions crates/bevy_ecs/src/system/commands/mod.rs
Expand Up @@ -5,7 +5,7 @@ use crate::{
self as bevy_ecs,
bundle::Bundle,
entity::{Entities, Entity},
system::{RunSystem, SystemId},
system::{RunSystemWithInput, SystemId},
world::{EntityWorldMut, FromWorld, World},
};
use bevy_ecs_macros::SystemParam;
Expand Down Expand Up @@ -523,8 +523,26 @@ impl<'w, 's> Commands<'w, 's> {
/// Running slow systems can become a bottleneck.
///
/// Calls [`World::run_system`](crate::system::World::run_system).
///
/// There is no way to get the output of a system when run as a command, because the
/// execution of the system happens later. To get the output of a system, use
/// [`World::run_system`] or [`World::run_system_with_input`] instead of running the system as a command.
pub fn run_system(&mut self, id: SystemId) {
self.queue.push(RunSystem::new(id));
self.run_system_with_input(id, ());
}

/// Runs the system corresponding to the given [`SystemId`].
/// Systems are ran in an exclusive and single threaded way.
/// Running slow systems can become a bottleneck.
///
/// Calls [`World::run_system_with_input`](crate::system::World::run_system_with_input).
///
/// There is no way to get the output of a system when run as a command, because the
/// execution of the system happens later. To get the output of a system, use
/// [`World::run_system`] or [`World::run_system_with_input`] instead of running the system as a command.
pub fn run_system_with_input<I: 'static + Send>(&mut self, id: SystemId<I>, input: I) {
self.queue
.push(RunSystemWithInput::new_with_input(id, input));
}

/// Pushes a generic [`Command`] to the command queue.
Expand Down

0 comments on commit 1f05e1e

Please sign in to comment.