-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a
SystemParam
primitive for deferred mutations; allow `#[derive…
…]`ing more types of SystemParam (#6817) # Objective One pattern to increase parallelism is deferred mutation: instead of directly mutating the world (and preventing other systems from running at the same time), you queue up operations to be applied to the world at the end of the stage. The most common example of this pattern uses the `Commands` SystemParam. In order to avoid the overhead associated with commands, some power users may want to add their own deferred mutation behavior. To do this, you must implement the unsafe trait `SystemParam`, which interfaces with engine internals in a way that we'd like users to be able to avoid. ## Solution Add the `Deferred<T>` primitive `SystemParam`, which encapsulates the deferred mutation pattern. This can be combined with other types of `SystemParam` to safely and ergonomically create powerful custom types. Essentially, this is just a variant of `Local<T>` which can run code at the end of the stage. This type is used in the engine to derive `Commands` and `ParallelCommands`, which removes a bunch of unsafe boilerplate. ### Example ```rust use bevy_ecs::system::{Deferred, SystemBuffer}; /// Sends events with a delay, but may run in parallel with other event writers. #[derive(SystemParam)] pub struct BufferedEventWriter<'s, E: Event> { queue: Deferred<'s, EventQueue<E>>, } struct EventQueue<E>(Vec<E>); impl<'s, E: Event> BufferedEventWriter<'s, E> { /// Queues up an event to be sent at the end of this stage. pub fn send(&mut self, event: E) { self.queue.0.push(event); } } // The `SystemBuffer` trait controls how [`Deferred`] gets applied at the end of the stage. impl<E: Event> SystemBuffer for EventQueue<E> { fn apply(&mut self, world: &mut World) { let mut events = world.resource_mut::<Events<E>>(); for e in self.0.drain(..) { events.send(e); } } } ``` --- ## Changelog + Added the `SystemParam` type `Deferred<T>`, which can be used to defer `World` mutations. Powered by the new trait `SystemBuffer`.
- Loading branch information
1 parent
952735f
commit d26b63a
Showing
4 changed files
with
210 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters