Skip to content

Commit 90eaaa9

Browse files
committed
support the run_system_with_input Command
1 parent 7f68e79 commit 90eaaa9

File tree

2 files changed

+75
-8
lines changed

2 files changed

+75
-8
lines changed

crates/bevy_ecs/src/system/commands/mod.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
self as bevy_ecs,
66
bundle::Bundle,
77
entity::{Entities, Entity},
8-
system::{RunSystem, SystemId},
8+
system::{RunSystemWithInput, SystemId},
99
world::{EntityWorldMut, FromWorld, World},
1010
};
1111
use bevy_ecs_macros::SystemParam;
@@ -524,7 +524,17 @@ impl<'w, 's> Commands<'w, 's> {
524524
///
525525
/// Calls [`World::run_system`](crate::system::World::run_system).
526526
pub fn run_system(&mut self, id: SystemId) {
527-
self.queue.push(RunSystem::new(id));
527+
self.run_system_with_input(id, ())
528+
}
529+
530+
/// Runs the system corresponding to the given [`SystemId`].
531+
/// Systems are ran in an exclusive and single threaded way.
532+
/// Running slow systems can become a bottleneck.
533+
///
534+
/// Calls [`World::run_system_with_input`](crate::system::World::run_system_with_input).
535+
pub fn run_system_with_input<I: 'static + Send>(&mut self, id: SystemId<I>, input: I) {
536+
self.queue
537+
.push(RunSystemWithInput::new_with_input(id, input));
528538
}
529539

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

crates/bevy_ecs/src/system/system_registry.rs

+63-6
Original file line numberDiff line numberDiff line change
@@ -299,26 +299,55 @@ impl World {
299299
}
300300
}
301301

302-
/// The [`Command`] type for [`World::run_system`].
302+
/// The [`Command`] type for [`World::run_system`] or [`World::run_system_with_input`].
303303
///
304304
/// This command runs systems in an exclusive and single threaded way.
305305
/// Running slow systems can become a bottleneck.
306+
///
307+
/// If the system needs an [`In<_>`](crate::system::In) input value to run, it must
308+
/// be provided as part of the command.
309+
///
310+
/// There is no way to get the output of a system when run as a command, because the
311+
/// execution of the system happens later. To get the output of a system, use
312+
/// [World::run_system] or [World::run_system_with_input] instead of running the system as a command.
306313
#[derive(Debug, Clone)]
307-
pub struct RunSystem {
308-
system_id: SystemId,
314+
pub struct RunSystemWithInput<I: 'static> {
315+
system_id: SystemId<I>,
316+
input: I,
309317
}
310318

319+
/// The [`Command`] type for [`World::run_system`].
320+
///
321+
/// This command runs systems in an exclusive and single threaded way.
322+
/// Running slow systems can become a bottleneck.
323+
///
324+
/// If the system needs an [`In<_>`](crate::system::In) input value to run, use the
325+
/// [crate::system::RunSystemWithInput] type instead.
326+
///
327+
/// There is no way to get the output of a system when run as a command, because the
328+
/// execution of the system happens later. To get the output of a system, use
329+
/// [World::run_system] or [World::run_system_with_input] instead of running the system as a command.
330+
pub type RunSystem = RunSystemWithInput<()>;
331+
311332
impl RunSystem {
312333
/// Creates a new [`Command`] struct, which can be added to [`Commands`](crate::system::Commands)
313334
pub fn new(system_id: SystemId) -> Self {
314-
Self { system_id }
335+
Self::new_with_input(system_id, ())
336+
}
337+
}
338+
339+
impl<I: 'static> RunSystemWithInput<I> {
340+
/// Creates a new [`Command`] struct, which can be added to [`Commands`](crate::system::Commands)
341+
/// in order to run the specified system with the provided [`In<_>`](crate::system::In) input value.
342+
pub fn new_with_input(system_id: SystemId<I>, input: I) -> Self {
343+
Self { system_id, input }
315344
}
316345
}
317346

318-
impl Command for RunSystem {
347+
impl<I: 'static + Send> Command for RunSystemWithInput<I> {
319348
#[inline]
320349
fn apply(self, world: &mut World) {
321-
let _ = world.run_system(self.system_id);
350+
let _ = world.run_system_with_input(self.system_id, self.input);
322351
}
323352
}
324353

@@ -505,4 +534,32 @@ mod tests {
505534
let _ = world.run_system(nested_id);
506535
assert_eq!(*world.resource::<Counter>(), Counter(5));
507536
}
537+
538+
#[test]
539+
fn nested_systems_with_inputs() {
540+
use crate::system::SystemId;
541+
542+
#[derive(Component)]
543+
struct Callback(SystemId<u8>, u8);
544+
545+
fn nested(query: Query<&Callback>, mut commands: Commands) {
546+
for callback in query.iter() {
547+
commands.run_system_with_input(callback.0, callback.1);
548+
}
549+
}
550+
551+
let mut world = World::new();
552+
world.insert_resource(Counter(0));
553+
554+
let increment_by =
555+
world.register_system(|In(amt): In<u8>, mut counter: ResMut<Counter>| {
556+
counter.0 += amt;
557+
});
558+
let nested_id = world.register_system(nested);
559+
560+
world.spawn(Callback(increment_by, 2));
561+
world.spawn(Callback(increment_by, 3));
562+
let _ = world.run_system(nested_id);
563+
assert_eq!(*world.resource::<Counter>(), Counter(5));
564+
}
508565
}

0 commit comments

Comments
 (0)