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

WorldQuery types for working with relationships #17647

Open
6 tasks
alice-i-cecile opened this issue Feb 2, 2025 · 1 comment
Open
6 tasks

WorldQuery types for working with relationships #17647

alice-i-cecile opened this issue Feb 2, 2025 · 1 comment
Assignees
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! D-Unsafe Touches with unsafe code in some way S-Needs-Design This issue requires design work to think about how it would best be accomplished

Comments

@alice-i-cecile
Copy link
Member

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.

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! labels Feb 2, 2025
@alice-i-cecile alice-i-cecile self-assigned this Feb 2, 2025
@alice-i-cecile alice-i-cecile added S-Needs-Design This issue requires design work to think about how it would best be accomplished and removed S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! labels Feb 3, 2025
@alice-i-cecile
Copy link
Member Author

After exploring this in #17649, I quickly discovered that WorldQuery and friends really only want to look up data from a single entity at once. This applies to both the current non-fragmenting relations, as well as any future archetypal relations APIs to do the same sort of thing.

In order to unblock this flavor of API (which I still think is very elegant and intuitive and would make Bevy code easier to read and write!), we need to modify how WorldQuery::fetch works, to allow changing the table / archetype we're looking at halfway through. This will both a) be fairly slow and b) pose serious soundness risks. If you're keen on tackling this, pull together a working group please so we can carefully design and get multiple sets of eyes on any implementation.

@alice-i-cecile alice-i-cecile added the D-Unsafe Touches with unsafe code in some way label Feb 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! D-Unsafe Touches with unsafe code in some way S-Needs-Design This issue requires design work to think about how it would best be accomplished
Projects
None yet
Development

No branches or pull requests

1 participant