Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run system from &mut World #2417

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/system/function_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,10 @@ impl<In, Out, Sys: System<In = In, Out = Out>> IntoSystem<In, Out, AlreadyWasSys
pub struct In<In>(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<In, Out, Param, Marker, F>
where
Expand Down
63 changes: 63 additions & 0 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::{
},
entity::{Entities, Entity},
query::{FilterFetch, QueryState, WorldQuery},
schedule::{IntoSystemDescriptor, SystemDescriptor},
storage::{Column, SparseSet, Storages},
};
use std::{
Expand Down Expand Up @@ -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>){
/// counter.0 += 1;
/// }
///
/// world.insert_resource::<Counter>(Counter(0));
/// world.run_system(count_up);
/// let counter = world.get_resource::<Counter>().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::<Counter>().unwrap();
/// counter.0 += 1;
/// }
///
/// world.insert_resource::<Counter>(Counter(0));
/// world.run_system(count_up_exclusive.exclusive_system());
/// let counter = world.get_resource::<Counter>().unwrap();
/// assert_eq!(counter.0, 1);
/// ```
pub fn run_system<Params>(&mut self, system: impl IntoSystemDescriptor<Params>) {
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 {
Expand Down