From 95778adf9868ca3a4400338b1b16337b754cae78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Mockers?= Date: Sat, 22 May 2021 18:51:06 +0200 Subject: [PATCH 01/11] run a system from a command --- Cargo.toml | 4 +++ crates/bevy_ecs/src/system/commands/mod.rs | 25 ++++++++++++++++- examples/README.md | 1 + examples/ecs/system_command.rs | 32 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 examples/ecs/system_command.rs diff --git a/Cargo.toml b/Cargo.toml index f95b76f75a9ee..788863fb9438e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -301,6 +301,10 @@ path = "examples/ecs/state.rs" name = "system_chaining" path = "examples/ecs/system_chaining.rs" +[[example]] +name = "system_command" +path = "examples/ecs/system_command.rs" + [[example]] name = "system_param" path = "examples/ecs/system_param.rs" diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 0488b09e4f770..9d367ff1b619f 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -8,7 +8,10 @@ use crate::{ }; use bevy_utils::tracing::debug; pub use command_queue::CommandQueue; -use std::marker::PhantomData; +use parking_lot::Mutex; +use std::{cell::RefCell, marker::PhantomData}; + +use super::System; /// A [`World`] mutation. pub trait Command: Send + Sync + 'static { @@ -152,6 +155,13 @@ impl<'a> Commands<'a> { }); } + /// Run a one off [`System`]. + pub fn run_system(&mut self, system: impl System) { + self.queue.push(RunSystem { + system: Mutex::new(RefCell::new(Box::new(system))), + }); + } + /// Adds a command directly to the command list. pub fn add(&mut self, command: C) { self.queue.push(command); @@ -387,6 +397,19 @@ impl Command for RemoveResource { } } +pub struct RunSystem { + system: Mutex>>>, +} + +impl Command for RunSystem { + fn write(self: Box, world: &mut World) { + let lock = self.system.lock(); + let mut system = lock.borrow_mut(); + system.initialize(world); + system.run((), world); + } +} + #[cfg(test)] #[allow(clippy::float_cmp, clippy::approx_constant)] mod tests { diff --git a/examples/README.md b/examples/README.md index 37b76a3a34830..24fe8aad7701d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -167,6 +167,7 @@ Example | File | Description `startup_system` | [`ecs/startup_system.rs`](./ecs/startup_system.rs) | Demonstrates a startup system (one that runs once when the app starts up) `state` | [`ecs/state.rs`](./ecs/state.rs) | Illustrates how to use States to control transitioning from a Menu state to an InGame state `system_chaining` | [`ecs/system_chaining.rs`](./ecs/system_chaining.rs) | Chain two systems together, specifying a return type in a system (such as `Result`) +`system_command` | [`ecs/system_command.rs`](./ecs/system_command.rs) | Run a system from a command `system_param` | [`ecs/system_param.rs`](./ecs/system_param.rs) | Illustrates creating custom system parameters with `SystemParam` `system_sets` | [`ecs/system_sets.rs`](./ecs/system_sets.rs) | Shows `SystemSet` use along with run criterion `timers` | [`ecs/timers.rs`](./ecs/timers.rs) | Illustrates ticking `Timer` resources inside systems and handling their state diff --git a/examples/ecs/system_command.rs b/examples/ecs/system_command.rs new file mode 100644 index 0000000000000..d8d19fdecd48e --- /dev/null +++ b/examples/ecs/system_command.rs @@ -0,0 +1,32 @@ +use bevy::prelude::*; +/// This example triggers a system from a command +fn main() { + App::build() + .add_plugins(DefaultPlugins) + .add_startup_system(spawn.system()) + .add_system(trigger_sync.system()) + .run(); +} + +pub struct Player; + +/// Spawn some players to sync +fn spawn(mut commands: Commands) { + commands.spawn().insert(Player); + commands.spawn().insert(Player); +} + +fn trigger_sync(mut commands: Commands, mut last_sync: Local, time: Res