Requiring two queries and manually joining them sucks. We should make some WorldQuery types to make this process easier.
Four types of query filters desired:
Passing in general QueryFilter arguments is more powerful, but also more verbose.
We can't use both ChildOf
and Children
in the same position: need to disambiguate them based on type.
#[derive(QueryFilter)]
struct RelatedTo<R: Relation, F: QueryFilter>;
// Parent has Player
Query<&Transform, RelatedTo<ChildOf, With<Player>>>
// Any child has Player
Query<&Transform, Scan<Children, With<Player>>>
// Any ancestor has Player
Query<&Transform, WithAncestor<ChildOf, With<Player>>>
// Any descendant has Player
Query<&Transform, WithDescendant<Children, With<Player>>>
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). Doesn't have to be in the first PR.
We also want to be able to access QueryData
of related entities in a single query. We'll start with only "parent has data", to sidestep the vec questions.
#[derive(QueryData)]
struct Related<R: Relation, D: QueryData>;
// Get me each entity that has a transform and a parent who has a transform
Query<(&Transform, Related<ChildOf, &Transform>)>
// Get me each entity that has a transform and their parent's transform, if any
Query<(&Transform, Option<Related<ChildOf, &Transform>>)>
// Get me each entity that has a transform, and their grandparent's transform
Query<(&Transform, Related<ChildOf, Related<ChildOf, &Transform>>)>
// Get me the entity ID of the parent of each entity with a transform
Query<Related<ChildOf, Entity>>, With<Transform>>
With a type alias, this would become:
// Get me each entity that has a transform and a parent who has a transform
Query<(&Transform, Parent<&Transform>)>
// Get me each entity that has a transform and their parent's transform, if any
Query<(&Transform, Option<Parent<&Transform>>)>
// Get me each entity that has a transform, and their grandparent's transform
Query<(&Transform, Parent<Parent<&Transform>>)>
// Get me the entity ID of the parent of each entity with a transform
Query<Parent<Entity>, With<Transform>>