Skip to content

Inferred command flushes (hard sync points) and at-least once system separation #7838

Closed
@alice-i-cecile

Description

What problem does this solve or what need does it fill?

When working with command flushes, you rarely care that two systems are separated by a particular copy of apply_system_buffers.

Instead, you care that it is "separated by at least one copy". This pattern occurs commonly: with command buffers, state transitions, transform propagation and pretty much anything you might use the Deferred type (#6817) for.

Trying to manage this in a single app can be challenging, as it requires a fairly global view of system scheduling that's easy to accidentally break.
The problem gets much worse when third-party plugins are involved though: each plugin must add its own cleanup systems to uphold its invariants, and is unaware of what other plugins may be doing, even if they could trivially share these cleanup systems.

What solution would you like?

Add a new form of system ordering, which requires commands to be applied at least once between them.

This could look like:

// Special casing
app.add_system(a.before_and_flush(b));

// Generalized chain-like syntax on system sets
app.add_systems((a,b).separated_by(apply_system_buffers));
app.configure_set(MySet.seperated_by(apply_system_buffers));

// Generalized two argument syntax
app.add_system(a.before_and_seperated_by(b, apply_system_buffers);

The scheduler should then attempt to ensure that at least one system of the appropriate type is run between a and b
Of course, figuring out how to do so efficiently is far from trivial and an MVP should probably be quite naive (perhaps only checking, rather than automatically inserting!).

Interestingly, I think that this should only work for system type sets, not arbitrary system sets. It's far too easy to get very surprising behavior if the exact system separating your system can change in non-local ways.

What alternative(s) have you considered?

Better graph visualization would help, but doesn't solve the problem of third-party plugins that have no way of being aware of each other.

This could be generalized to arbitrary systems which would be very useful for cache-flushing patterns like #4513 or state transitions. It's unclear if that will be more or less complex than simply doing so for apply_state_transitions.

Additional context

Previously discussed in bevyengine/rfcs#45, but cut due to scope concerns.

This would be a powerful tool to enable better configurability of plugins (#2160), as plugin authors can be much less strict about the provided configuration.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleD-ComplexQuite challenging from either a design or technical perspective. Ask for help!X-ControversialThere is active debate or serious implications around merging this PR

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions