bevy_ecs::query

Trait QueryData

Source
pub unsafe trait QueryData: WorldQuery {
    type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>;
}
Expand description

Types that can be fetched from a World using a Query.

There are many types that natively implement this trait:

  • Component references. (&T and &mut T) Fetches a component by reference (immutably or mutably).
  • QueryData tuples. If every element of a tuple implements QueryData, then the tuple itself also implements the same trait. This enables a single Query to access multiple components. Due to the current lack of variadic generics in Rust, the trait has been implemented for tuples from 0 to 15 elements, but nesting of tuples allows infinite WorldQuerys.
  • Entity. Gets the identifier of the queried entity.
  • EntityLocation. Gets the location metadata of the queried entity.
  • EntityRef. Read-only access to arbitrary components on the queried entity.
  • EntityMut. Mutable access to arbitrary components on the queried entity.
  • &Archetype. Read-only access to the archetype-level metadata of the queried entity.
  • Option. By default, a world query only tests entities that have the matching component types. Wrapping it into an Option will increase the query search space, and it will return None if an entity doesn’t satisfy the WorldQuery.
  • AnyOf. Equivalent to wrapping each world query inside it into an Option.
  • Ref. Similar to change detection filters but it is used as a query fetch parameter. It exposes methods to check for changes to the wrapped component.
  • Has. Returns a bool indicating whether the entity has the specified component.

Implementing the trait manually can allow for a fundamentally new type of behavior.

§Trait derivation

Query design can be easily structured by deriving QueryData for custom types. Despite the added complexity, this approach has several advantages over using QueryData tuples. The most relevant improvements are:

  • Reusability across multiple systems.
  • There is no need to destructure a tuple since all fields are named.
  • Subqueries can be composed together to create a more complex query.
  • Methods can be implemented for the query items.
  • There is no hardcoded limit on the number of elements.

This trait can only be derived for structs, if each field also implements QueryData.

use bevy_ecs::query::QueryData;

#[derive(QueryData)]
struct MyQuery {
    entity: Entity,
    // It is required that all reference lifetimes are explicitly annotated, just like in any
    // struct. Each lifetime should be 'static.
    component_a: &'static ComponentA,
    component_b: &'static ComponentB,
}

fn my_system(query: Query<MyQuery>) {
    for q in &query {
        q.component_a;
    }
}

§Macro expansion

Expanding the macro will declare one or three additional structs, depending on whether or not the struct is marked as mutable. For a struct named X, the additional structs will be:

Struct namemutable onlyDescription
XItemThe type of the query item for X
XReadOnlyItemThe type of the query item for XReadOnly
XReadOnlyReadOnly variant of X

§Adding mutable references

Simply adding mutable references to a derived QueryData will result in a compilation error:

#[derive(QueryData)]
struct CustomQuery {
    component_a: &'static mut ComponentA,
}

To grant mutable access to components, the struct must be marked with the #[query_data(mutable)] attribute. This will also create three more structs that will be used for accessing the query immutably (see table above).

#[derive(QueryData)]
#[query_data(mutable)]
struct CustomQuery {
    component_a: &'static mut ComponentA,
}

§Adding methods to query items

It is possible to add methods to query items in order to write reusable logic about related components. This will often make systems more readable because low level logic is moved out from them. It is done by adding impl blocks with methods for the -Item or -ReadOnlyItem generated structs.

#[derive(Component)]
struct Health(f32);

#[derive(Component)]
struct Buff(f32);

#[derive(QueryData)]
#[query_data(mutable)]
struct HealthQuery {
    health: &'static mut Health,
    buff: Option<&'static mut Buff>,
}

// `HealthQueryItem` is only available when accessing the query with mutable methods.
impl<'w> HealthQueryItem<'w> {
    fn damage(&mut self, value: f32) {
        self.health.0 -= value;
    }

    fn total(&self) -> f32 {
        self.health.0 + self.buff.as_deref().map_or(0.0, |Buff(buff)| *buff)
    }
}

// `HealthQueryReadOnlyItem` is only available when accessing the query with immutable methods.
impl<'w> HealthQueryReadOnlyItem<'w> {
    fn total(&self) -> f32 {
        self.health.0 + self.buff.map_or(0.0, |Buff(buff)| *buff)
    }
}

fn my_system(mut health_query: Query<HealthQuery>) {
    // The item returned by the iterator is of type `HealthQueryReadOnlyItem`.
    for health in health_query.iter() {
        println!("Total: {}", health.total());
    }
    // The item returned by the iterator is of type `HealthQueryItem`.
    for mut health in &mut health_query {
        health.damage(1.0);
        println!("Total (mut): {}", health.total());
    }
}

§Deriving traits for query items

The QueryData derive macro does not automatically implement the traits of the struct to the query item types. Something similar can be done by using the #[query_data(derive(...))] attribute. This will apply the listed derivable traits to the query item structs.

#[derive(QueryData)]
#[query_data(mutable, derive(Debug))]
struct CustomQuery {
    component_a: &'static ComponentA,
}

// This function statically checks that `T` implements `Debug`.
fn assert_debug<T: std::fmt::Debug>() {}

assert_debug::<CustomQueryItem>();
assert_debug::<CustomQueryReadOnlyItem>();

§Query composition

It is possible to use any QueryData as a field of another one. This means that a QueryData can also be used as a subquery, potentially in multiple places.

#[derive(QueryData)]
struct SubQuery {
    component_a: &'static ComponentA,
    component_b: &'static ComponentB,
}

#[derive(QueryData)]
struct MyQuery {
    subquery: SubQuery,
    component_c: &'static ComponentC,
}

§Generic Queries

When writing generic code, it is often necessary to use PhantomData to constrain type parameters. Since QueryData is implemented for all PhantomData<T> types, this pattern can be used with this macro.

#[derive(QueryData)]
pub struct GenericQuery<T> {
    id: Entity,
    marker: PhantomData<T>,
}

§Safety

Component access of Self::ReadOnly must be a subset of Self and Self::ReadOnly must match exactly the same archetypes/tables as Self

Required Associated Types§

Source

type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>

The read-only variant of this QueryData, which satisfies the ReadOnlyQueryData trait.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl QueryData for ()

Source§

impl<'__w, T: Component> QueryData for &'__w mut T

SAFETY: access of &T is a subset of &mut T

Source§

impl<F: QueryData> QueryData for (F₁, F₂, …, Fₙ)

This trait is implemented for tuples up to 16 items long.

Source§

impl<T: Component> QueryData for &T

SAFETY: Self is the same as Self::ReadOnly

Source§

impl<T: QueryData> QueryData for Option<T>

Source§

impl<T: ?Sized> QueryData for PhantomData<T>

SAFETY: Self::ReadOnly is Self

Implementors§

Source§

impl QueryData for &Archetype

SAFETY: Self is the same as Self::ReadOnly

Source§

impl QueryData for Entity

SAFETY: Self is the same as Self::ReadOnly

Source§

impl QueryData for EntityLocation

SAFETY: Self is the same as Self::ReadOnly

Source§

impl QueryData for AnyOf<()>

Source§

impl<'__w, T: Component> QueryData for Mut<'__w, T>

Source§

type ReadOnly = Ref<'__w, T>

Source§

impl<'__w, T: Component> QueryData for Ref<'__w, T>

SAFETY: Self is the same as Self::ReadOnly

Source§

type ReadOnly = Ref<'__w, T>

Source§

impl<'a> QueryData for EntityMut<'a>

SAFETY: access of EntityRef is a subset of EntityMut

Source§

impl<'a> QueryData for EntityRef<'a>

SAFETY: Self is the same as Self::ReadOnly

Source§

impl<'a> QueryData for FilteredEntityMut<'a>

SAFETY: access of FilteredEntityRef is a subset of FilteredEntityMut

Source§

impl<'a> QueryData for FilteredEntityRef<'a>

SAFETY: Self is the same as Self::ReadOnly

Source§

impl<'a, B> QueryData for EntityMutExcept<'a, B>
where B: Bundle,

SAFETY: All accesses that EntityRefExcept provides are also accesses that EntityMutExcept provides.

Source§

impl<'a, B> QueryData for EntityRefExcept<'a, B>
where B: Bundle,

SAFETY: Self is the same as Self::ReadOnly.

Source§

impl<F: QueryData> QueryData for AnyOf<(F₁, F₂, …, Fₙ)>

This trait is implemented for tuples up to 16 items long.

Source§

impl<T: Component> QueryData for Has<T>

SAFETY: Self is the same as Self::ReadOnly