Filters

A filter allows further specifying, and consequently narrowing, the subset of entities to visit.

For instance, a filter can allow querying the set of entities which have a specified component, or the set of entities which do not have the specified components, among others.

With and Without

Allows including or excluding a set of entities from the query depending on their components.

Combined with tag like components, a query which only yields the player can be achieved.

#![allow(unused)]

fn main() {
        let mut query = Query::new((name(), health())).with_filter(player().with());

        let mut borrow = query.borrow(&world);

        if let Some((name, health)) = borrow.iter().next() {
            tracing::info!("The player {name} is alive and well at {health} health");
        } else {
            tracing::info!("The player seems to have perished");
        }

}

... or everything that isn't a player, that of course still has the required name and health.

#![allow(unused)]

fn main() {
        let mut query = Query::new((name(), health())).with_filter(player().without());

        for (name, health) in &mut query.borrow(&world) {
            tracing::info!("Npc: {name} at {health} health");
        }

}

Combinators

Several filters can be combined using & and |, as well as !.

Comparison

It is also possible to filter on the value of a component.

This is different from using filter on the iterator, as the comparison will filter and select before the query traverses the entities, which means it avoids unnecessary modification events for mutable queries.

#![allow(unused)]

fn main() {
        let mut query = Query::new(name()).with_filter(health().without() | health().ge(35.0));
        for name in &mut query.borrow(&world) {
            tracing::info!("{name} is still standing strong");
        }

}