diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 566ef78dbf9c7..f75f7bd6a30b4 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 diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 5068fdc4e5074..a70766ecf8d41 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -18,6 +18,7 @@ use crate::{ }, entity::{Entities, Entity}, query::{FilterFetch, QueryState, WorldQuery}, + schedule::{IntoSystemDescriptor, SystemDescriptor}, storage::{Column, SparseSet, Storages}, }; use std::{ @@ -917,6 +918,68 @@ 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 {