Try   HackMD

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:

  1. Does my parent have this component?
  2. Do any of my immediate children have this component?
  3. Do any of my parents or grandparents etc have this component?
  4. Do any of my children or grandchildren etc have this component?

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>>