elevator_core/query/mod.rs
1//! ECS-style query builder for iterating entities by component composition.
2//!
3//! # Examples
4//!
5//! ```
6//! use elevator_core::components::{Position, Rider, Route};
7//! use elevator_core::prelude::*;
8//! use elevator_core::query::{Ext, With, Without};
9//! use elevator_core::world::ExtKey;
10//!
11//! use serde::{Serialize, Deserialize};
12//!
13//! #[derive(Debug, Clone, Serialize, Deserialize)]
14//! struct VipTag { level: u32 }
15//!
16//! let mut sim = SimulationBuilder::demo().build().unwrap();
17//! let rider_eid = sim.spawn_rider(StopId(0), StopId(1), 75.0).unwrap();
18//!
19//! // Attach an extension component.
20//! sim.world_mut().insert_ext(rider_eid.entity(), VipTag { level: 5 }, ExtKey::from_type_name());
21//!
22//! let world = sim.world();
23//!
24//! // All riders with a position
25//! for (id, rider, pos) in world.query::<(EntityId, &Rider, &Position)>().iter() {
26//! println!("{id:?}: phase={:?} at {}", rider.phase(), pos.value());
27//! }
28//!
29//! // Entities with Position but without Route
30//! for (id, pos) in world.query::<(EntityId, &Position)>()
31//! .without::<Route>()
32//! .iter()
33//! {
34//! println!("{id:?} at {}", pos.value());
35//! }
36//!
37//! // Extension components (cloned)
38//! for (id, vip) in world.query::<(EntityId, &Ext<VipTag>)>().iter() {
39//! println!("VIP rider {id:?}: level {}", vip.level);
40//! }
41//! ```
42
43pub(crate) mod storage;
44
45mod fetch;
46mod filter;
47mod iter;
48
49pub use fetch::{Ext, ExtMut, WorldQuery};
50pub use filter::{ExtWith, ExtWithout, QueryFilter, With, Without};
51pub use iter::{ExtQueryMut, QueryBuilder, QueryIter};