Skip to main content

Module macros

Module macros 

Source
Expand description

The declarative front end for a query.

Writing a query by hand takes three pieces: a struct of items, a type for the plan, and an impl with two bodies. This macro derives all of it from one declaration, so what the caller writes is the shape of one row:

pub struct Health(pub i32);
pub struct Armor(pub i32);

query! {
    /// One combatant, as the combat pass reads it.
    pub struct Combatant<'a> {
        pub entity: Entity,
        pub health: &'a mut Health,
        pub armor: &'a Armor,
    }
}

let mut world = World::new();
let entity = world.root_scope_mut().spawn(bundle![Health(10), Armor(2)]);

for row in world.root_scope().query::<Combatant>().iter() {
    row.health.0 -= row.armor.0;
}

assert_eq!(world.root_scope().query_one::<&Health>(entity).unwrap().get().0, 8);

The lifetime is nominal: the items a query yields borrow from the holder, never from the declaration, so Combatant, Combatant<'static> and Combatant<'_> name the same query.

§Fields

FieldYieldsMatches
&'a T&'a Tonly archetypes carrying T
&'a mut T&'a mut Tonly archetypes carrying T
Option<&'a T>Option<&'a T>every archetype
Option<&'a mut T>Option<&'a mut T>every archetype
EntityEntityevery archetype
Has<T>boolevery archetype

A field whose type is none of these is reported at compile time, naming the field. A component named twice with at least one of the two exclusive panics when the query is iterated, the same as (&T, &mut T) does.

§Visibility

The struct takes the visibility it is declared with, and its fields may carry attributes and their own visibility: #[derive(Debug)], doc comments and pub(crate) all travel as written.