-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Add systems to sets based on their world accesses #7857
Description
What problem does this solve or what need does it fill?
Currently, it is difficult to order systems based only on their logical constraints. In cases where you want a system to run after (or before) other systems which access a resource or component, you need to have global knowledge of the schedule and which systems might access that data.
One example of this is for events: if you have a system that reads AppExit events, it must run after the system that sends those events -- otherwise the event will be missed forever. Ordering the systems correctly requires knowing which system sends the event and adding a dependency to it, which is difficult to discover. See #7067, which is motivated by this issue.
What solution would you like?
Make it possible to automatically assign systems to a set based on their world accesses. An event reader system with proper ordering could look like:
fn read_app_exit(mut events: EventReader<AppExit>) { ... }
app.add_system(read_app_exit.after(SendsEvents::<AppExit>::default());When combined with #7838, transform propagation could be as simple as:
#[derive(Component)]
#[component(write_set = WriteTransform)] // any system with access to `&mut Transform` will be added to this set.
pub struct Transform { ... }
// Perform transform propagation after every system has modified `Transform`,
// and after their commands have been flushed.
app.add_system(transform_propagate_system.after_and_flush(WriteTransform));There should be a way of manually opting out of access sets:
fn jump(q: Query<&mut Transform>) { ... }
// This system can run after `transform_propagate_system`.
app.add_system(jump.without_set(WritesTransform));What alternative(s) have you considered?
Do nothing, and continue using global reasoning to order systems.
Additional context
A variant of this feature that is restricted to events was originally suggested in #4872.