Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Queries that add/remove components #334

Open
Ralith opened this issue Aug 28, 2023 · 1 comment · May be fixed by #337
Open

Queries that add/remove components #334

Ralith opened this issue Aug 28, 2023 · 1 comment · May be fixed by #337
Labels
enhancement New feature or request

Comments

@Ralith
Copy link
Owner

Ralith commented Aug 28, 2023

Common patterns involve iterating over a query and adding, adding if absent, or removing a component from every entity. This presently requires a somewhat awkward and suboptimal dance where operations are buffered in a CommandBuffer or moral equivalent and executed in a separate pass after the query completes. We could extend the query machinery to support these patterns directly with query transformers that allow components to be directly written to or consumed from archetype storage, though considerable care will be required to soundly handle corner cases including incomplete iteration, leaked queries, and failure to insert all expected components.

Design notes:

  • Entities must be moved only after they are visited. Before would prevent dynamic addition/removal decisions, and during would invalidate live component references.
  • Moving entities between archetypes naively can cause them to be visited multiple times. Because entities are always inserted at the end of an archetype, this could be avoided by capturing a snapshot of the len of each archetype when the query begins, and halting iteration at that point.
  • Components cannot be moved while any borrows from the query are still live. Movement of entities between archetypes must therefore happen no sooner than the Drop impl of an object that outlives the query lifetime. This will require a guard object, and is therefore incompatible with the existing query_mut/query_one_mut API.
  • Two new Query methods:
    • One that traverses the archetype graph to reflect component insertion/removals. Compound queries execute this for each inner query in any order to arrive at the final archetype.
    • One that populates entries in the final archetype
  • Care must be taken to preserve safety in the presence of arbitrary drops, unwinds, and leaks of the query iterator and any query items.
    • A query that yields ownership of components must poison affected archetypes until cleanup completes
  • QueryMut and similar must carry borrows of the whole World so they can add new archetypes
@Ralith Ralith added the enhancement New feature or request label Aug 28, 2023
@Ralith
Copy link
Owner Author

Ralith commented Aug 28, 2023

A straw implementation might place a CommandBuffer in the query iterator that gets executed on drop.

One significant limitation is that such queries must take &mut World, and hence cannot contain random access to unrelated entities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant