Skip to content

Query-level change detection #14510

@alice-i-cecile

Description

@alice-i-cecile

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

When generating data for things like reactive UI, it's important to be able to quickly and reliably know whether or not a query will return the same things as the last time you checked.

[3:55 PM]DreamerTalin: Consider, for example, a listbox that shows a list of saved games.
[3:55 PM]DreamerTalin: The list of saved games is a query result.
[3:55 PM]DreamerTalin: You want to re-render the list when a saved game is added or removed.
[3:56 PM]DreamerTalin: You can do this now by copying the query output into a resource or component (provided you compare the lists and don't mutate if there are no changes).

This is also useful as a general-purpose early return or run condition to save on wasted work.

What solution would you like?

The ideal API would look like:

// Checks for added / removed entities since the last time this system ran
query.any_structural_changes();

// Checks for any structural changes or mutations since the last time this system ran
query.any_changes();

To do this, add a change tick to QueryState which reflects when matching entities were "most recently added or removed".

This value should be kept up to date with observers.

Implementing "when did the values of entities in this query last change" will require combining the structural change tick stored in the query with the mutation change ticks on

What alternative(s) have you considered?

This work fits naturally with making queries entities, and storing their state as components. However, it does not need that work: generating the appropriate observers and storing state should be feasible anyways.

Currently, the only real workaround is to cache the entire query in a Local or similar. This is both slow and very memory-inefficient.

Additional context

This was asked for by @viridia in the context of reactive UI here.

As a nice bonus, this would offer another tool (complementary to ##5097) to make a any_changed run condition performant enough to not be a footgun.

If this is done as part of the work for #3742, we should be able to hook into the work being done to update the archetype cache.
Otherwise, it may be hard to justify the expense of running observers and updating this data for every query.

Metadata

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!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions