From 1a2cc63fcd2dbb02d45f8b3673561d66f0246bf1 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Tue, 29 Jun 2021 21:59:59 -0400 Subject: [PATCH 01/18] Basic implementation of World::run_system --- crates/bevy_ecs/src/world/mod.rs | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 862181538328b..8598fa20daab7 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -17,6 +17,7 @@ use crate::{ }, entity::{Entities, Entity}, query::{FilterFetch, QueryState, WorldQuery}, + schedule::SystemDescriptor, storage::{Column, SparseSet, Storages}, }; use std::{ @@ -916,6 +917,49 @@ impl World { column.check_change_ticks(change_tick); } } + + /// Runs a system in a sequential, blocking fashion on the `World` + /// + /// Use [System::run_unsafe] directly for manual unsafe execution + /// of simultaneous systems in parallel. + /// + /// The `system` parameter here can be any function + /// that could be added as a system to a standard `App`. + /// + /// This system cannot have an input or output; + /// use [World::run_system_chainable] instead + /// if this behavior is desired. + /// + /// #Examples + /// + /// ```rust + /// #[derive(Default)] + /// struct Counter(u8); + /// let mut world = World::new(); + /// + /// fn count_up(mut counter: ResMut){ + /// counter += 1; + /// } + /// + /// world.insert_resource::(Counter(0)); + /// world.run_system(count_up); + /// let counter = world.get_resource::().unwrap(); + /// assert_eq!(counter.0, 1); + /// ``` + pub fn run_system(&mut self, system: impl Into) { + let system_descriptor: SystemDescriptor = system.into(); + + match system_descriptor { + SystemDescriptor::Parallel(par_system_descriptor) => { + let mut boxed_system = par_system_descriptor.system; + boxed_system.run((), self); + } + SystemDescriptor::Exclusive(exc_system_descriptor) => { + let mut boxed_system = exc_system_descriptor.system; + boxed_system.run(self); + } + } + } } impl fmt::Debug for World { From 8e99532153ceff08cc8668e46a68c203c2a0cbcd Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Tue, 29 Jun 2021 22:49:35 -0400 Subject: [PATCH 02/18] Basic tests --- crates/bevy_ecs/src/world/mod.rs | 38 ++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 8598fa20daab7..01154b18d8802 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -933,12 +933,11 @@ impl World { /// #Examples /// /// ```rust - /// #[derive(Default)] /// struct Counter(u8); /// let mut world = World::new(); /// /// fn count_up(mut counter: ResMut){ - /// counter += 1; + /// counter.0 += 1; /// } /// /// world.insert_resource::(Counter(0)); @@ -1009,3 +1008,38 @@ impl Default for MainThreadValidator { } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::prelude::*; + + struct Counter(u8); + + fn count_up(mut counter: ResMut) { + counter.0 += 1; + } + + fn count_up_exclusive(world: &mut World) { + let mut counter = world.get_resource_mut::().unwrap(); + counter.0 += 1; + } + + #[test] + fn run_parallel_system_from_world() { + let mut world = World::new(); + world.insert_resource::(Counter(0)); + world.run_system(count_up.system()); + let counter = world.get_resource::().unwrap(); + assert_eq!(counter.0, 1); + } + + #[test] + fn run_exclusive_system_from_world() { + let mut world = World::new(); + world.insert_resource::(Counter(0)); + world.run_system(count_up_exclusive.exclusive_system()); + let counter = world.get_resource::().unwrap(); + assert_eq!(counter.0, 1); + } +} From 2496410edcf61e51755207073aada74b36caa4e2 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Tue, 29 Jun 2021 23:03:15 -0400 Subject: [PATCH 03/18] Semantically significant typo in docs --- crates/bevy_ecs/src/system/function_system.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 09790f742cbe0..246197f824237 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -221,10 +221,10 @@ impl> IntoSystem(pub In); pub struct InputMarker; -/// The [`System`] counter part of an ordinary function. +/// The [`System`] counterpart of an ordinary function. /// /// You get this by calling [`IntoSystem::system`] on a function that only accepts -/// [`SystemParam`]s. The output of the system becomes the functions return type, while the input +/// [`SystemParam`]s. The output of the system becomes the function's return type, while the input /// becomes the functions [`In`] tagged parameter or `()` if no such paramater exists. pub struct FunctionSystem where From fc16b63ee8c0bbdc23e87770513fed1769e720f2 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Tue, 29 Jun 2021 23:24:55 -0400 Subject: [PATCH 04/18] Correctly use IntoSystemDescriptor, not Into --- crates/bevy_ecs/src/world/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 01154b18d8802..bd6579bbbc116 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -17,7 +17,7 @@ use crate::{ }, entity::{Entities, Entity}, query::{FilterFetch, QueryState, WorldQuery}, - schedule::SystemDescriptor, + schedule::{IntoSystemDescriptor, SystemDescriptor}, storage::{Column, SparseSet, Storages}, }; use std::{ @@ -945,8 +945,8 @@ impl World { /// let counter = world.get_resource::().unwrap(); /// assert_eq!(counter.0, 1); /// ``` - pub fn run_system(&mut self, system: impl Into) { - let system_descriptor: SystemDescriptor = system.into(); + pub fn run_system(&mut self, system: impl IntoSystemDescriptor) { + let system_descriptor: SystemDescriptor = system.into_descriptor(); match system_descriptor { SystemDescriptor::Parallel(par_system_descriptor) => { From 9b3a5fad92822b28c0992de629238634abccc017 Mon Sep 17 00:00:00 2001 From: Alice Date: Wed, 30 Jun 2021 03:45:04 -0400 Subject: [PATCH 05/18] Run parallel systems on world correctly Credit to @mockersf for teaching me how to do this --- crates/bevy_ecs/src/world/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index bd6579bbbc116..eec85ce6ba938 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -951,7 +951,10 @@ impl World { match system_descriptor { SystemDescriptor::Parallel(par_system_descriptor) => { let mut boxed_system = par_system_descriptor.system; + boxed_system.initialize(self); boxed_system.run((), self); + // Immediately flushes any Commands or similar buffers created + boxed_system.apply_buffers(self); } SystemDescriptor::Exclusive(exc_system_descriptor) => { let mut boxed_system = exc_system_descriptor.system; From 5e2c89ef3ac97f39c0b5d30480b8f945948d2c2a Mon Sep 17 00:00:00 2001 From: Alice Date: Wed, 30 Jun 2021 03:55:42 -0400 Subject: [PATCH 06/18] Exclusive systems should also be initialized --- crates/bevy_ecs/src/world/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index eec85ce6ba938..5a6b48b28fc0d 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -958,6 +958,7 @@ impl World { } SystemDescriptor::Exclusive(exc_system_descriptor) => { let mut boxed_system = exc_system_descriptor.system; + boxed_system.initialize(self); boxed_system.run(self); } } From 34496ebc9c635e1f242b60a524f6c92be3db3655 Mon Sep 17 00:00:00 2001 From: Alice Date: Wed, 30 Jun 2021 04:14:25 -0400 Subject: [PATCH 07/18] Code cleanup --- crates/bevy_ecs/src/world/mod.rs | 60 +++++++++++--------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 5a6b48b28fc0d..62e2ee4a33e15 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -926,18 +926,16 @@ impl World { /// The `system` parameter here can be any function /// that could be added as a system to a standard `App`. /// - /// This system cannot have an input or output; - /// use [World::run_system_chainable] instead - /// if this behavior is desired. - /// /// #Examples /// /// ```rust + /// use bevy_ecs::prelude::*; + /// /// struct Counter(u8); /// let mut world = World::new(); /// /// fn count_up(mut counter: ResMut){ - /// counter.0 += 1; + /// counter.0 += 1; /// } /// /// world.insert_resource::(Counter(0)); @@ -945,6 +943,23 @@ impl World { /// let counter = world.get_resource::().unwrap(); /// assert_eq!(counter.0, 1); /// ``` + /// + /// ```rust + /// use bevy_ecs::prelude::*; + /// + /// struct Counter(u8); + /// let mut world = World::new(); + /// + /// fn count_up_exclusive(world: &mut World){ + /// let mut counter = world.get_resource_mut::().unwrap(); + /// counter.0 += 1; + /// } + /// + /// world.insert_resource::(Counter(0)); + /// world.run_system(count_up_exclusive.exclusive_system()); + /// let counter = world.get_resource::().unwrap(); + /// assert_eq!(counter.0, 1); + /// ``` pub fn run_system(&mut self, system: impl IntoSystemDescriptor) { let system_descriptor: SystemDescriptor = system.into_descriptor(); @@ -1012,38 +1027,3 @@ impl Default for MainThreadValidator { } } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::prelude::*; - - struct Counter(u8); - - fn count_up(mut counter: ResMut) { - counter.0 += 1; - } - - fn count_up_exclusive(world: &mut World) { - let mut counter = world.get_resource_mut::().unwrap(); - counter.0 += 1; - } - - #[test] - fn run_parallel_system_from_world() { - let mut world = World::new(); - world.insert_resource::(Counter(0)); - world.run_system(count_up.system()); - let counter = world.get_resource::().unwrap(); - assert_eq!(counter.0, 1); - } - - #[test] - fn run_exclusive_system_from_world() { - let mut world = World::new(); - world.insert_resource::(Counter(0)); - world.run_system(count_up_exclusive.exclusive_system()); - let counter = world.get_resource::().unwrap(); - assert_eq!(counter.0, 1); - } -} From 178840db64e4e1d1925a2af8a6721d37068ff293 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Wed, 30 Jun 2021 18:28:14 -0400 Subject: [PATCH 08/18] Improved doc strings --- crates/bevy_ecs/src/world/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 62e2ee4a33e15..363275bc95131 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -918,7 +918,7 @@ impl World { } } - /// Runs a system in a sequential, blocking fashion on the `World` + /// Runs a system in a blocking fashion on the `World` /// /// Use [System::run_unsafe] directly for manual unsafe execution /// of simultaneous systems in parallel. @@ -926,8 +926,9 @@ impl World { /// The `system` parameter here can be any function /// that could be added as a system to a standard `App`. /// - /// #Examples - /// + /// # Examples + /// + /// Here's an example of how to directly run an ordinary parallel system. /// ```rust /// use bevy_ecs::prelude::*; /// @@ -943,7 +944,7 @@ impl World { /// let counter = world.get_resource::().unwrap(); /// assert_eq!(counter.0, 1); /// ``` - /// + /// And here's how you directly run an exclusive system. /// ```rust /// use bevy_ecs::prelude::*; /// From b24128a8ecc16f4634dc3c94f4c6152568226b6f Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 2 Jul 2021 14:04:45 -0400 Subject: [PATCH 09/18] Related documentation improvements --- crates/bevy_ecs/src/system/system.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index eabf476730340..30dafcbf9a08f 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -65,8 +65,9 @@ pub trait System: Send + Sync + 'static { // SAFE: world and resources are exclusively borrowed unsafe { self.run_unsafe(input, world) } } + /// Applies any buffers (such as `Commands`) created by this system's parameters to the world fn apply_buffers(&mut self, world: &mut World); - /// Initialize the system. + /// Initialize the World, so that the system can safely run fn initialize(&mut self, _world: &mut World); fn check_change_tick(&mut self, change_tick: u32); } From e42035186f655976d6b63668ce67a1ca3bc020ca Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 2 Jul 2021 14:05:10 -0400 Subject: [PATCH 10/18] run_direct method for parallel systems --- crates/bevy_ecs/src/system/system.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 30dafcbf9a08f..dd6aa16827d05 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -61,10 +61,22 @@ pub trait System: Send + Sync + 'static { /// [`System::archetype_component_access()`]. unsafe fn run_unsafe(&mut self, input: Self::In, world: &World) -> Self::Out; /// Runs the system with the given input in the world. + /// + /// Use [`run_direct`] instead if you are manually running a system outside of a schedule fn run(&mut self, input: Self::In, world: &mut World) -> Self::Out { // SAFE: world and resources are exclusively borrowed unsafe { self.run_unsafe(input, world) } } + /// Runs the system directly on the world, initializing the world correctly; + /// immediately applying buffers (such as `Commands`) modified by its system parameters + /// + /// Use () as the `input` parameter for systems which do not take any chained input + fn run_direct(&mut self, input: Self::In, world: &mut World) -> Self::Out { + self.initialize(world); + let output = self.run(input, world); + self.apply_buffers(world); + return output; + } /// Applies any buffers (such as `Commands`) created by this system's parameters to the world fn apply_buffers(&mut self, world: &mut World); /// Initialize the World, so that the system can safely run From 440740c5f7d28026897bbc64cbc3ef2057856ca6 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 2 Jul 2021 14:10:05 -0400 Subject: [PATCH 11/18] run_direct for exclusive systems --- crates/bevy_ecs/src/system/exclusive_system.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/bevy_ecs/src/system/exclusive_system.rs b/crates/bevy_ecs/src/system/exclusive_system.rs index 7050355b6b8fe..3d7f7b04f660f 100644 --- a/crates/bevy_ecs/src/system/exclusive_system.rs +++ b/crates/bevy_ecs/src/system/exclusive_system.rs @@ -10,8 +10,18 @@ pub trait ExclusiveSystem: Send + Sync + 'static { fn id(&self) -> SystemId; + /// Runs the exclusive system in the world. + /// + /// Use [`run_direct`] instead if you are manually running a system outside of a schedule fn run(&mut self, world: &mut World); + /// Runs the exclusive system directly on the world, initializing the world correctly + fn run_direct(&mut self, world: &mut World) { + self.initialize(world); + self.run(world); + } + + /// Initialize the World, so that the system can safely run fn initialize(&mut self, world: &mut World); fn check_change_tick(&mut self, change_tick: u32); From da2f44754f9edb49197697bfda0fc38a2d3c0ae6 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 2 Jul 2021 15:09:38 -0400 Subject: [PATCH 12/18] Basic (but failing doc tests) error[E0599]: no method named `run_direct` found for struct `ExclusiveSystemFn` in the current scope --- .../bevy_ecs/src/system/exclusive_system.rs | 20 +++++++++++++++++++ crates/bevy_ecs/src/system/system.rs | 17 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/crates/bevy_ecs/src/system/exclusive_system.rs b/crates/bevy_ecs/src/system/exclusive_system.rs index 3d7f7b04f660f..cdf5c363b1939 100644 --- a/crates/bevy_ecs/src/system/exclusive_system.rs +++ b/crates/bevy_ecs/src/system/exclusive_system.rs @@ -13,9 +13,29 @@ pub trait ExclusiveSystem: Send + Sync + 'static { /// Runs the exclusive system in the world. /// /// Use [`run_direct`] instead if you are manually running a system outside of a schedule + fn run(&mut self, world: &mut World); /// Runs the exclusive system directly on the world, initializing the world correctly + /// + /// # Example + /// + /// ```rust + /// use bevy_ecs::prelude::*; + /// + /// struct Counter(u8); + /// let mut world = World::new(); + /// + /// fn count_up(world: &mut World){ + /// let mut counter = world.get_resource_mut::().unwrap(); + /// counter.0 += 1; + /// } + /// + /// world.insert_resource::(Counter(0)); + /// count_up.exclusive_system().run_direct(world); + /// let counter = world.get_resource::().unwrap(); + /// assert_eq!(counter.0, 1); + ///``` fn run_direct(&mut self, world: &mut World) { self.initialize(world); self.run(world); diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index dd6aa16827d05..7fafa6694baf3 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -71,6 +71,23 @@ pub trait System: Send + Sync + 'static { /// immediately applying buffers (such as `Commands`) modified by its system parameters /// /// Use () as the `input` parameter for systems which do not take any chained input + /// + /// # Examples + /// ```rust + /// use bevy_ecs::prelude::*; + /// + /// struct Counter(u8); + /// let mut world = World::new(); + /// + /// fn count_up(mut counter: ResMut){ + /// counter.0 += 1; + /// } + /// + /// world.insert_resource::(Counter(0)); + /// count_up.run_direct((), world); + /// let counter = world.get_resource::().unwrap(); + /// assert_eq!(counter.0, 1); + /// ``` fn run_direct(&mut self, input: Self::In, world: &mut World) -> Self::Out { self.initialize(world); let output = self.run(input, world); From aa0724107aa7cb286d41257779e9ee0b70da1739 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 2 Jul 2021 16:18:14 -0400 Subject: [PATCH 13/18] Mention lack of parallelism in doc strings --- crates/bevy_ecs/src/system/system.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 7fafa6694baf3..8c4dda5fb86be 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -70,7 +70,11 @@ pub trait System: Send + Sync + 'static { /// Runs the system directly on the world, initializing the world correctly; /// immediately applying buffers (such as `Commands`) modified by its system parameters /// - /// Use () as the `input` parameter for systems which do not take any chained input + /// Use () as the `input` parameter for systems which do not take any chained input. + /// + /// Only one system will run at a time when executed in this way; + /// use a [`Schedule`] (or a custom abstraction created with [`run_unsafe`]) + /// when system parallelism is desired. /// /// # Examples /// ```rust From d5835c1ca9e11f811596c1edb7a95c5315c65a69 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 2 Jul 2021 16:29:36 -0400 Subject: [PATCH 14/18] Fixed broken tests --- crates/bevy_ecs/src/lib.rs | 5 +++-- crates/bevy_ecs/src/system/exclusive_system.rs | 7 ++++++- crates/bevy_ecs/src/system/system.rs | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index fa50ae8efd22a..838583a942a56 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -29,8 +29,9 @@ pub mod prelude { Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, SystemStage, }, system::{ - Commands, ConfigurableSystem, In, IntoChainSystem, IntoExclusiveSystem, IntoSystem, - Local, NonSend, NonSendMut, Query, QuerySet, RemovedComponents, Res, ResMut, System, + Commands, ConfigurableSystem, ExclusiveSystem, In, IntoChainSystem, + IntoExclusiveSystem, IntoSystem, Local, NonSend, NonSendMut, Query, QuerySet, + RemovedComponents, Res, ResMut, System, }, world::{FromWorld, Mut, World}, }; diff --git a/crates/bevy_ecs/src/system/exclusive_system.rs b/crates/bevy_ecs/src/system/exclusive_system.rs index cdf5c363b1939..3c1419af53cff 100644 --- a/crates/bevy_ecs/src/system/exclusive_system.rs +++ b/crates/bevy_ecs/src/system/exclusive_system.rs @@ -32,7 +32,7 @@ pub trait ExclusiveSystem: Send + Sync + 'static { /// } /// /// world.insert_resource::(Counter(0)); - /// count_up.exclusive_system().run_direct(world); + /// count_up.exclusive_system().run_direct(&mut world); /// let counter = world.get_resource::().unwrap(); /// assert_eq!(counter.0, 1); ///``` @@ -78,6 +78,11 @@ impl ExclusiveSystem for ExclusiveSystemFn { world.last_change_tick = saved_last_tick; } + fn run_direct(&mut self, world: &mut World) { + self.initialize(world); + self.run(world); + } + fn initialize(&mut self, _: &mut World) {} fn check_change_tick(&mut self, change_tick: u32) { diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 8c4dda5fb86be..12204600bc1e8 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -88,7 +88,7 @@ pub trait System: Send + Sync + 'static { /// } /// /// world.insert_resource::(Counter(0)); - /// count_up.run_direct((), world); + /// count_up.system().run_direct((), &mut world); /// let counter = world.get_resource::().unwrap(); /// assert_eq!(counter.0, 1); /// ``` From faf36a7e8e9dcc4570a2e3f6c3fd01025d0a3974 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 2 Jul 2021 16:59:25 -0400 Subject: [PATCH 15/18] Satisfy the clippy gods --- crates/bevy_ecs/src/system/system.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 12204600bc1e8..598afc7e61c2f 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -96,7 +96,7 @@ pub trait System: Send + Sync + 'static { self.initialize(world); let output = self.run(input, world); self.apply_buffers(world); - return output; + output } /// Applies any buffers (such as `Commands`) created by this system's parameters to the world fn apply_buffers(&mut self, world: &mut World); From f379b376b4daa46dbc94569f8c72d9613794f875 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 2 Jul 2021 16:59:25 -0400 Subject: [PATCH 16/18] Removed accidentally included old impl --- crates/bevy_ecs/src/world/mod.rs | 62 -------------------------------- 1 file changed, 62 deletions(-) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 363275bc95131..add2ae4c93316 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -917,68 +917,6 @@ impl World { column.check_change_ticks(change_tick); } } - - /// Runs a system in a blocking fashion on the `World` - /// - /// Use [System::run_unsafe] directly for manual unsafe execution - /// of simultaneous systems in parallel. - /// - /// The `system` parameter here can be any function - /// that could be added as a system to a standard `App`. - /// - /// # Examples - /// - /// Here's an example of how to directly run an ordinary parallel system. - /// ```rust - /// use bevy_ecs::prelude::*; - /// - /// struct Counter(u8); - /// let mut world = World::new(); - /// - /// fn count_up(mut counter: ResMut){ - /// counter.0 += 1; - /// } - /// - /// world.insert_resource::(Counter(0)); - /// world.run_system(count_up); - /// let counter = world.get_resource::().unwrap(); - /// assert_eq!(counter.0, 1); - /// ``` - /// And here's how you directly run an exclusive system. - /// ```rust - /// use bevy_ecs::prelude::*; - /// - /// struct Counter(u8); - /// let mut world = World::new(); - /// - /// fn count_up_exclusive(world: &mut World){ - /// let mut counter = world.get_resource_mut::().unwrap(); - /// counter.0 += 1; - /// } - /// - /// world.insert_resource::(Counter(0)); - /// world.run_system(count_up_exclusive.exclusive_system()); - /// let counter = world.get_resource::().unwrap(); - /// assert_eq!(counter.0, 1); - /// ``` - pub fn run_system(&mut self, system: impl IntoSystemDescriptor) { - let system_descriptor: SystemDescriptor = system.into_descriptor(); - - match system_descriptor { - SystemDescriptor::Parallel(par_system_descriptor) => { - let mut boxed_system = par_system_descriptor.system; - boxed_system.initialize(self); - boxed_system.run((), self); - // Immediately flushes any Commands or similar buffers created - boxed_system.apply_buffers(self); - } - SystemDescriptor::Exclusive(exc_system_descriptor) => { - let mut boxed_system = exc_system_descriptor.system; - boxed_system.initialize(self); - boxed_system.run(self); - } - } - } } impl fmt::Debug for World { From 82c0443836f7207906a798abc80cfe0c390c8b1c Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sun, 4 Jul 2021 23:27:50 -0400 Subject: [PATCH 17/18] Corrected comments on system initialization --- crates/bevy_ecs/src/system/exclusive_system.rs | 2 +- crates/bevy_ecs/src/system/system.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/system/exclusive_system.rs b/crates/bevy_ecs/src/system/exclusive_system.rs index 3c1419af53cff..c0801c8a93b3a 100644 --- a/crates/bevy_ecs/src/system/exclusive_system.rs +++ b/crates/bevy_ecs/src/system/exclusive_system.rs @@ -16,7 +16,7 @@ pub trait ExclusiveSystem: Send + Sync + 'static { fn run(&mut self, world: &mut World); - /// Runs the exclusive system directly on the world, initializing the world correctly + /// Runs the exclusive system directly on the world, correctly initializing its state first /// /// # Example /// diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 598afc7e61c2f..b48474583d9e4 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -100,7 +100,7 @@ pub trait System: Send + Sync + 'static { } /// Applies any buffers (such as `Commands`) created by this system's parameters to the world fn apply_buffers(&mut self, world: &mut World); - /// Initialize the World, so that the system can safely run + /// Initializes the system from the world, so that it may be run successfully fn initialize(&mut self, _world: &mut World); fn check_change_tick(&mut self, change_tick: u32); } From c0a18017134c58c9197e55772ce1bcf0f1f7d82d Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 30 Jul 2021 14:48:18 -0400 Subject: [PATCH 18/18] System-yeet for .run and friends --- crates/bevy_ecs/src/system/function_system.rs | 52 ++++++++++++++++++- crates/bevy_ecs/src/system/system.rs | 2 +- crates/bevy_ecs/src/world/mod.rs | 1 - 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 246197f824237..a341655fa67a3 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -299,6 +299,52 @@ where } } +/// Allows end users to call system-running methods from the [`System`](crate::system::System) trait without .system(). +pub trait RunnableSystem: + IntoSystem +{ + fn apply_buffers(self, world: &mut World); + + fn initialize(self, _world: &mut World); + + fn run(self, input: In, world: &mut World) -> Out; + + fn run_direct(self, input: In, world: &mut World) -> Out; +} + +impl RunnableSystem for F +where + In: 'static, + Out: 'static, + Param: SystemParam + 'static, + Marker: 'static, + F: SystemParamFunction + + IntoSystem< + In, + Out, + (IsFunctionSystem, Param, Marker), + System = FunctionSystem, + > + Send + + Sync + + 'static, +{ + fn apply_buffers(self, world: &mut World) { + self.system().apply_buffers(world); + } + + fn initialize(self, world: &mut World) { + self.system().initialize(world); + } + + fn run(self, input: In, world: &mut World) -> Out { + self.system().run(input, world) + } + + fn run_direct(self, input: In, world: &mut World) -> Out { + self.system().run_direct(input, world) + } +} + pub struct IsFunctionSystem; impl IntoSystem for F @@ -366,13 +412,17 @@ where #[inline] unsafe fn run_unsafe(&mut self, input: Self::In, world: &World) -> Self::Out { let change_tick = world.increment_change_tick(); - let out = self.func.run( + // Trait disambiguation required here to disambiguate .run call + // the .run found in the `RunnableSystem` trait + let out = >::run( + &mut self.func, input, self.param_state.as_mut().unwrap(), &self.system_meta, world, change_tick, ); + self.system_meta.last_change_tick = change_tick; out } diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index b48474583d9e4..bd94aee8495b9 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -88,7 +88,7 @@ pub trait System: Send + Sync + 'static { /// } /// /// world.insert_resource::(Counter(0)); - /// count_up.system().run_direct((), &mut world); + /// count_up.run_direct((), &mut world); /// let counter = world.get_resource::().unwrap(); /// assert_eq!(counter.0, 1); /// ``` diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index add2ae4c93316..862181538328b 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -17,7 +17,6 @@ use crate::{ }, entity::{Entities, Entity}, query::{FilterFetch, QueryState, WorldQuery}, - schedule::{IntoSystemDescriptor, SystemDescriptor}, storage::{Column, SparseSet, Storages}, }; use std::{