Skip to content

Better callbacks: Allow type-erased cached one-shot systems #19847

Open
@viridia

Description

@viridia

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

Lately we've been discussing how to improve the use of one-shot systems as callbacks. Using registered systems that produce a SystemId has a number of beneficial properties, however it means that the user is responsible for unregistering the system at some point, otherwise you get leaking one-shots.

There are a couple of ways to get around the registration problem. One approach is to have some kind of framework that manages auto-deregistration when the SystemId goes out of scope, however this is a fairly complex and heavyweight solution, especially for smaller apps and examples.

Another approach is to use cached one-shot systems; however you can't easily pass these around in a type-erased way because the cache uses the type information as part of the key.

What solution would you like?

Based on discussions with various folks on Discord, what I am envisioning is some kind of dyn-compatible trait that contains both a reference to the one-shot function, and any dynamic type information needed to maintain the cache.

What I would like is to be able to define a enum that gives the user flexibility when specifying how they want to be notified:

enum Callback<I> {
    // Invoke a registered system
    System(SystemId<I>),
    // Invoke a cached system
    CachedSystem(Box<dyn CachedSystemHandle<I>>),
    // Don't do anything
    Ignore,
    // Additional notification mechanisms here
}

Once you create a CachedSystemHandle (which can be easily created from an IntoSystem), you can then pass this around as a parameter, invoke it using Commands, or drop it at any time without any cleanup.

Another name for this might be AnySystem.

@alice-i-cecile
@cart

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleS-Needs-DesignThis issue requires design work to think about how it would best be accomplished

    Type

    No type

    Projects

    Status

    Widget-ready

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions