pub trait WorldQuery {
type Item<'w>;
type State: QueryState;
// Required methods
fn init_state(world: &World) -> Self::State;
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>;
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool;
fn fetch<'w>(
state: &Self::State,
world: &'w World,
entity: Entity,
) -> Option<Self::Item<'w>>;
// Provided method
fn fetch_mut<'w>(
state: &Self::State,
world: &'w mut World,
entity: Entity,
) -> Option<Self::Item<'w>> { ... }
}Expand description
Trait for types that can be queried from a World.
WorldQuery is the foundational trait of the ECS query system. It defines:
- What type of data the query produces (
Item) - What state the query caches (
State) - How to match archetypes (
matches_archetype) - How to fetch data from the world (
fetch)
§Generic Associated Type
The Item<'w> associated type uses a Generic Associated Type (GAT) to
express that the fetched item has a lifetime tied to the world borrow.
This enables returning references to component data.
§State Caching
The State type caches information needed for efficient queries, typically:
- Component IDs (avoids repeated TypeId lookups)
- Cached archetype matches (avoids repeated set operations)
§Safety
Implementors must ensure:
matches_archetypeaccurately reflects what entities can be fetchedfetchreturnsNonefor entities that don’t match- Mutable queries conflict with other queries on the same component
§Built-in Implementations
The following types implement WorldQuery:
&TwhereT: Component- Fetches immutable component reference&mut TwhereT: Component- Fetches mutable component referenceEntity- Fetches the entity ID itself- Tuples
(A, B, ...)- Combines multiple queries Option<Q>- Optional query, always matchesWith<T>- Filter for entities that have T (no data)Without<T>- Filter for entities that don’t have T (no data)
§Example
use goud_engine::ecs::{Component, Entity, World};
use goud_engine::ecs::query::WorldQuery;
#[derive(Debug)]
struct Health(f32);
impl Component for Health {}
// The trait bounds ensure type safety:
fn query_requires_world_query<Q: WorldQuery>() {}
// Entity always implements WorldQuery
query_requires_world_query::<Entity>();Required Associated Types§
Sourcetype Item<'w>
type Item<'w>
The type of data this query fetches.
This is a Generic Associated Type (GAT) that takes a lifetime parameter
'w representing the world borrow lifetime. This allows the item to
contain references to data stored in the world.
Examples:
- For
&T:Item<'w> = &'w T - For
&mut T:Item<'w> = &'w mut T - For
Entity:Item<'w> = Entity(no reference needed)
Sourcetype State: QueryState
type State: QueryState
The cached state for this query.
State is initialized once via init_state and reused for subsequent
queries. This avoids repeated lookups of component IDs and other
metadata.
Examples:
- For
&T:State = ComponentId - For tuples:
State = (A::State, B::State, ...)
Required Methods§
Sourcefn init_state(world: &World) -> Self::State
fn init_state(world: &World) -> Self::State
Sourcefn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
Sourcefn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
Checks whether this query matches the given archetype.
Returns true if entities in the archetype can produce a valid Item.
This is used to filter archetypes during query iteration.
§Arguments
state- The cached query statearchetype- The archetype to check
§Returns
true if entities in this archetype match the query.
Sourcefn fetch<'w>(
state: &Self::State,
world: &'w World,
entity: Entity,
) -> Option<Self::Item<'w>>
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Fetches data for a specific entity from the world.
Returns Some(Item) if the entity has all required components,
None otherwise.
§Arguments
state- The cached query stateworld- Reference to the world containing component dataentity- The entity to fetch data for
§Returns
Some(Item) if the entity matches the query, None otherwise.
§Safety Note
This method takes an immutable world reference but may return mutable component references. The caller must ensure aliasing rules are maintained (typically enforced by the query iterator).
Provided Methods§
Sourcefn fetch_mut<'w>(
state: &Self::State,
world: &'w mut World,
entity: Entity,
) -> Option<Self::Item<'w>>
fn fetch_mut<'w>( state: &Self::State, world: &'w mut World, entity: Entity, ) -> Option<Self::Item<'w>>
Fetches data for a specific entity from a mutable world reference.
This variant is used when mutable component access is needed.
The default implementation calls fetch with an immutable borrow,
but mutable query implementations override this.
§Arguments
state- The cached query stateworld- Mutable reference to the worldentity- The entity to fetch data for
§Returns
Some(Item) if the entity matches the query, None otherwise.
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 WorldQuery for ()
Unit type () represents an empty query.
impl WorldQuery for ()
Unit type () represents an empty query.
This is useful as a base case for tuple queries and for queries that only use filters without fetching any data.
type Item<'w> = ()
type State = ()
fn init_state(_world: &World) -> Self::State
fn component_access(_state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(_state: &Self::State, _archetype: &Archetype) -> bool
fn fetch<'w>( _state: &Self::State, _world: &'w World, _entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<A: WorldQuery> WorldQuery for (A,)
impl<A: WorldQuery> WorldQuery for (A,)
type Item<'w> = (<A as WorldQuery>::Item<'w>,)
type State = (<A as WorldQuery>::State,)
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<A: WorldQuery, B: WorldQuery> WorldQuery for (A, B)
impl<A: WorldQuery, B: WorldQuery> WorldQuery for (A, B)
type Item<'w> = (<A as WorldQuery>::Item<'w>, <B as WorldQuery>::Item<'w>)
type State = (<A as WorldQuery>::State, <B as WorldQuery>::State)
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<A: WorldQuery, B: WorldQuery, C: WorldQuery> WorldQuery for (A, B, C)
impl<A: WorldQuery, B: WorldQuery, C: WorldQuery> WorldQuery for (A, B, C)
type Item<'w> = (<A as WorldQuery>::Item<'w>, <B as WorldQuery>::Item<'w>, <C as WorldQuery>::Item<'w>)
type State = (<A as WorldQuery>::State, <B as WorldQuery>::State, <C as WorldQuery>::State)
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery> WorldQuery for (A, B, C, D)
impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery> WorldQuery for (A, B, C, D)
type Item<'w> = (<A as WorldQuery>::Item<'w>, <B as WorldQuery>::Item<'w>, <C as WorldQuery>::Item<'w>, <D as WorldQuery>::Item<'w>)
type State = (<A as WorldQuery>::State, <B as WorldQuery>::State, <C as WorldQuery>::State, <D as WorldQuery>::State)
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery, E: WorldQuery> WorldQuery for (A, B, C, D, E)
impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery, E: WorldQuery> WorldQuery for (A, B, C, D, E)
type Item<'w> = (<A as WorldQuery>::Item<'w>, <B as WorldQuery>::Item<'w>, <C as WorldQuery>::Item<'w>, <D as WorldQuery>::Item<'w>, <E as WorldQuery>::Item<'w>)
type State = (<A as WorldQuery>::State, <B as WorldQuery>::State, <C as WorldQuery>::State, <D as WorldQuery>::State, <E as WorldQuery>::State)
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery, E: WorldQuery, F: WorldQuery> WorldQuery for (A, B, C, D, E, F)
impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery, E: WorldQuery, F: WorldQuery> WorldQuery for (A, B, C, D, E, F)
type Item<'w> = (<A as WorldQuery>::Item<'w>, <B as WorldQuery>::Item<'w>, <C as WorldQuery>::Item<'w>, <D as WorldQuery>::Item<'w>, <E as WorldQuery>::Item<'w>, <F as WorldQuery>::Item<'w>)
type State = (<A as WorldQuery>::State, <B as WorldQuery>::State, <C as WorldQuery>::State, <D as WorldQuery>::State, <E as WorldQuery>::State, <F as WorldQuery>::State)
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery, E: WorldQuery, F: WorldQuery, G: WorldQuery> WorldQuery for (A, B, C, D, E, F, G)
impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery, E: WorldQuery, F: WorldQuery, G: WorldQuery> WorldQuery for (A, B, C, D, E, F, G)
type Item<'w> = (<A as WorldQuery>::Item<'w>, <B as WorldQuery>::Item<'w>, <C as WorldQuery>::Item<'w>, <D as WorldQuery>::Item<'w>, <E as WorldQuery>::Item<'w>, <F as WorldQuery>::Item<'w>, <G as WorldQuery>::Item<'w>)
type State = (<A as WorldQuery>::State, <B as WorldQuery>::State, <C as WorldQuery>::State, <D as WorldQuery>::State, <E as WorldQuery>::State, <F as WorldQuery>::State, <G as WorldQuery>::State)
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery, E: WorldQuery, F: WorldQuery, G: WorldQuery, H: WorldQuery> WorldQuery for (A, B, C, D, E, F, G, H)
impl<A: WorldQuery, B: WorldQuery, C: WorldQuery, D: WorldQuery, E: WorldQuery, F: WorldQuery, G: WorldQuery, H: WorldQuery> WorldQuery for (A, B, C, D, E, F, G, H)
type Item<'w> = (<A as WorldQuery>::Item<'w>, <B as WorldQuery>::Item<'w>, <C as WorldQuery>::Item<'w>, <D as WorldQuery>::Item<'w>, <E as WorldQuery>::Item<'w>, <F as WorldQuery>::Item<'w>, <G as WorldQuery>::Item<'w>, <H as WorldQuery>::Item<'w>)
type State = (<A as WorldQuery>::State, <B as WorldQuery>::State, <C as WorldQuery>::State, <D as WorldQuery>::State, <E as WorldQuery>::State, <F as WorldQuery>::State, <G as WorldQuery>::State, <H as WorldQuery>::State)
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<Q: WorldQuery> WorldQuery for Option<Q>
Optional query wrapper.
impl<Q: WorldQuery> WorldQuery for Option<Q>
Optional query wrapper.
Option<Q> always matches every archetype. When the inner query Q can
fetch data for an entity, the result is Some(Q::Item). When it cannot,
the result is None. In both cases, the outer fetch returns Some(...),
so the entity is never skipped by the query system.
§Use Cases
- Querying for a component that only some entities have
- Avoiding the need for separate queries when a component is optional
- Combining required and optional components in tuple queries
§Example
// Query all entities with Position, optionally fetching Velocity
// (&Position, Option<&Velocity>)
// - Entities with both: (pos, Some(vel))
// - Entities with only Position: (pos, None)type Item<'w> = Option<<Q as WorldQuery>::Item<'w>>
type State = <Q as WorldQuery>::State
fn init_state(world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(_state: &Self::State, _archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
fn fetch_mut<'w>( state: &Self::State, world: &'w mut World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<T: Component> WorldQuery for &T
Query for an immutable component reference.
impl<T: Component> WorldQuery for &T
Query for an immutable component reference.
&T queries fetch a reference to component T for each matching entity.
This is one of the most common query types.
§Archetype Matching
An archetype matches &T if it contains component T. The query returns
None for entities that don’t have the component.
§Parallel Safety
&T is a read-only query and implements ReadOnlyWorldQuery. Multiple
&T queries for the same component can run in parallel, and &T can run
alongside &U for different components.
§Example
use goud_engine::ecs::{World, Component, Entity};
use goud_engine::ecs::query::WorldQuery;
#[derive(Debug, Clone, Copy, PartialEq)]
struct Position { x: f32, y: f32 }
impl Component for Position {}
let mut world = World::new();
let entity = world.spawn_empty();
world.insert(entity, Position { x: 1.0, y: 2.0 });
// Initialize query state
let state = <&Position>::init_state(&world);
// Fetch component reference
let pos = <&Position>::fetch(&state, &world, entity);
assert!(pos.is_some());
assert_eq!(pos.unwrap(), &Position { x: 1.0, y: 2.0 });§Access Conflicts
&Tconflicts with&mut T(read-write conflict)&Tdoes NOT conflict with&T(multiple readers allowed)&Tdoes NOT conflict with&Uwhere U ≠ T
type Item<'w> = &'w T
type State = ComponentId
fn init_state(_world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch<'w>( state: &Self::State, world: &'w World, entity: Entity, ) -> Option<Self::Item<'w>>
Source§impl<T: Component> WorldQuery for &mut T
Query for a mutable component reference.
impl<T: Component> WorldQuery for &mut T
Query for a mutable component reference.
&mut T queries fetch a mutable reference to component T for each matching
entity. This allows modifying component data in place.
§Archetype Matching
An archetype matches &mut T if it contains component T. The query returns
None for entities that don’t have the component.
§Access Conflicts
Mutable queries have strict access requirements:
&mut Tconflicts with&T(write-read conflict)&mut Tconflicts with&mut T(write-write conflict)&mut Tdoes NOT conflict with&Uor&mut Uwhere U ≠ T
The scheduler uses this information to prevent parallel execution of conflicting systems.
§Thread Safety
&mut T does NOT implement ReadOnlyWorldQuery. This means:
- Systems using
&mut Tcannot run in parallel with other systems accessingT - The query iterator enforces exclusive access at runtime
§Example
use goud_engine::ecs::{World, Component, Entity};
use goud_engine::ecs::query::WorldQuery;
#[derive(Debug, Clone, Copy, PartialEq)]
struct Health(f32);
impl Component for Health {}
let mut world = World::new();
let entity = world.spawn_empty();
world.insert(entity, Health(100.0));
// Initialize query state
let state = <&mut Health>::init_state(&world);
// Fetch mutable component reference
if let Some(health) = <&mut Health>::fetch_mut(&state, &mut world, entity) {
health.0 -= 10.0; // Modify in place
}
// Verify modification
assert_eq!(world.get::<Health>(entity), Some(&Health(90.0)));§Important Notes
- The
fetchmethod returnsNonebecause mutable access requires a mutable world reference. Usefetch_mutfor mutable queries. - The query system enforces that only one mutable access to a component exists at any time, preventing aliasing issues.
Source§fn fetch<'w>(
_state: &Self::State,
_world: &'w World,
_entity: Entity,
) -> Option<Self::Item<'w>>
fn fetch<'w>( _state: &Self::State, _world: &'w World, _entity: Entity, ) -> Option<Self::Item<'w>>
Returns None because mutable access requires fetch_mut.
This is intentional - the immutable world reference cannot provide mutable component access without violating Rust’s aliasing rules.
type Item<'w> = &'w mut T
type State = MutState
fn init_state(_world: &World) -> Self::State
fn component_access(state: &Self::State) -> BTreeSet<ComponentId>
fn matches_archetype(state: &Self::State, archetype: &Archetype) -> bool
fn fetch_mut<'w>( state: &Self::State, world: &'w mut World, entity: Entity, ) -> Option<Self::Item<'w>>
Implementors§
Source§impl WorldQuery for Entity
Entity can be queried to get the entity ID itself.
impl WorldQuery for Entity
Entity can be queried to get the entity ID itself.
This is useful when you need the entity ID along with component data, or when iterating over all entities in an archetype.