Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Objective
We want to be able to run queries that span multiple entities, for example:
Get the Name of entities with Spaceship, that are DocketTo entities with Planet
(which is roughly
Query<(&Name, DockedTo<(), With<Planet>>), With<SpaceShip>)>
It is already possible to do this by using multiple queries in a system, but the search can be more efficient is a single query is aware of all the constraints between the multiple sources.
Here we use 'source' to designate an entity for which we are trying to fit a constraint.
In bevy, all the current queries are single-source: we are iterating through entities that fit the constraint Query<D, F>.
For multi-source queries, you iterate through tuples of entities that fit the constraint.
For example
Query<(&Name, DockedTo<(), With<Planet>>), With<SpaceShip>)>
, iterates through all pairs (E1, E2) whereE1 satisfies
Query<(&Name, With<SpaceShip>)
, E2 satisfiesQuery<(), With<Planet>>
and E1/E2 are linked withDockedTo(E1, E2)
.Solution
This PR currently adds everything in a separate file that doesn't interact with the rest of the codebase because:
It adds:
The query is built like so:
QueryPlan::query_iter()
which returns an iterator that returns the tuple of entities (one entity per source) that matches the query. The item we return is actually a tuple ofUnsafeEntityCell
; we could convert it to a tuple ofFilteredEntityRef/Mut
(if the query has dynamic components) or a tuple of(D1, D2, D3)
(one typed-data per source).Soft limitations (these are not real blockers, they were just not implemented in this prototype)
Relationship
s, notRelationshipTarget
Bigger limitations
FilteredAccess
to check if the query matches the archetype, so doesn't support non-archetypal filters and some QueryData. To fix this we could either add these concepts in the dynamic query plan ?Todo
only tested with a single case, I am sure that the current logic is incorrect.
-> I don't update the VariableState correctly on backtracking!!
-> I don't update the
written
correctly on backtracking!!one long-term goal could be to switch ALL existing queries to use this approach, in which case the QueryState and QueryIterationCursor would be modified? All existing queries would become a one-source QueryPlan. The difficult part would be check how we can encode all existing QueryData/QueryFilter implementations in the QueryPlan.