Skip to content

WorldQuery types for working with relationships #17647

Open
@alice-i-cecile

Description

@alice-i-cecile

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

Working with relationships in Bevy is cumbersome, requiring multiple queries, manual iteration and repeated calls to Query::get to correlate the information about the relationship graph with the data you actually want to fetch.

This is particularly annoying in the context of exclusive world access, as keeping multiple queries alive at once requires the use of SystemState.

Many of these systems follow very common patterns: surely we can write simple abstractions over them.

What solution would you like?

Add 4 query filter types:

  • RelatedTo<R: Relationship, F: QueryFilter>: is this entity related to an entity that matches the query filter?
  • Scan<RT: RelationshipTarget, F: QueryFilter>: do any of the entities which are related to this entity match the query filter?
  • WithAncestor<R: Relationship, F: QueryFilter>: is this entity transitively related to any entities (searching up recursively) that match the given query filter?
  • WithDescendant<RT: RelationshipTarget, F: QueryFilter>: do any of the entities which are transitively related to this entity (searching down recursively) match the query filter?

Implementation note: both WithAncestor and WithDescendant are naively O(N^2). We can cache the decisions made and check the cache to reduce that to O(N). That doesn't have to be in the first PR.

Add an initial query data type:

  • Related<R: Relationship, D: QueryData>: fetch the data of type D from the entity that this entity is related to via R.

Note that Option<Related<R, D>> is extremely useful for looking up data if and only if it exists.

Finally, add a type alias

  • type Parent<D: QueryData> = Related<R: ChildOf, D: QueryData>

What alternative(s) have you considered?

Users who need these helpers can continue to work with multiple queries per system. This is not very pleasant, and often obscures meaning.

Alternatively, these helpers should generally be implementable outside of bevy_ecs. Doing so is a non-trivial amount of work, and requires fairly complex unsafe code.

Additional context

These query helper types build on the work in #17398; while they are intended to be ergonomic, pleasant to work with and forward-compatible, performance is a secondary concern. Archetypal relations (as seen in flecs, or proposed as part of #17564) would likely improve the speed of many of these operations.

These types were first designed in https://hackmd.io/UCyLaF4YStC0cTSE8Fm7cw, and discussed on Discord.

Metadata

Metadata

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!D-UnsafeTouches with unsafe code in some wayS-Ready-For-ImplementationThis issue is ready for an implementation PR. Go for it!

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions