unlit_ecs/query/mod.rs
1//! Queries: picking entities by the components they carry.
2//!
3//! A query is a type, not a value. The components to hand out are written in the
4//! turbofish, so the compiler checks them, and the iterator resolves them once
5//! per archetype instead of once per row.
6//!
7//! | Item | Yields |
8//! | --- | --- |
9//! | `&T` | the component, shared; only archetypes carrying it match |
10//! | `&mut T` | the component, exclusive; only archetypes carrying it match |
11//! | `Option<&T>` | `Some` when the archetype carries the component |
12//! | `Option<&mut T>` | `Some` when it carries it, exclusive |
13//! | `Entity` | the entity itself |
14//! | [`Has<T>`] | whether the archetype carries `T`, narrowing nothing |
15//!
16//! A tuple of items asks for all of them at once and yields a tuple of their
17//! items, and tuples nest: `(&a, (&b, &c))` asks for the same three components
18//! as `(&a, &b, &c)` and yields `(&A, (&B, &C))`. An item written `&(a, b)` is
19//! one component whose type is that tuple, not two, and an item outside the
20//! forms above fails to compile.
21//!
22//! A query is held rather than borrowed one row at a time: [`crate::QueryBorrow`]
23//! is what a scope hands out, it claims the components it will reach when it is
24//! built, and the claims are released when it is dropped. Iterating it is
25//! [`crate::QueryBorrow::iter`].
26//!
27//! ```rust
28//! # use unlit_ecs::{Entity, Has, World, bundle};
29//! let mut world = World::new();
30//! world.root_scope_mut().spawn(bundle![1u32, 10.0f32]);
31//! world.root_scope_mut().spawn(bundle![2u32, true]);
32//!
33//! let mut query = world.root_scope().query::<&u32>();
34//! let sum: u32 = query.iter().map(|value| *value).sum();
35//! assert_eq!(sum, 3);
36//!
37//! // The entity, its component, and whether it also carries a `bool`. The
38//! // `Has<bool>` reports the answer without narrowing anything, so both spawns
39//! // above are visited and the one without a `bool` prints `false`.
40//! for (entity, value, has_bool) in world.root_scope().query::<(Entity, &u32, Has<bool>)>().iter() {
41//! println!("{entity:?} has {value}, and a bool: {has_bool}");
42//! }
43//!
44//! // Tuples nest, so this asks for the same components and yields
45//! // `(&u32, (&f32,))` instead of `(&u32, &f32)`.
46//! for (value, (height,)) in world.root_scope().query::<(&u32, (&f32,))>().iter() {
47//! let _ = (value, height);
48//! }
49//! ```
50//!
51//! A query visits archetypes in creation order and rows in storage order, so
52//! iteration is deterministic. It skips the rows the scope cannot see and the
53//! tree's two scaffolding entities.
54//!
55//! Narrowing which archetypes a query visits, including by a component set only
56//! known at run time, is [`crate::QueryBorrow::by`].
57//!
58//! # Queries of your own
59//!
60//! A row that carries more than a tuple impl covers, or one whose components are
61//! worth naming, is declared with the [`crate::query!`] macro:
62//!
63//! ```rust
64//! # use unlit_ecs::{Entity, Has, World, bundle, query};
65//! pub struct Health(pub i32);
66//! pub struct Armor(pub i32);
67//! pub struct Mana(pub i32);
68//!
69//! query! {
70//! /// Everything one combatant is made of.
71//! pub struct Combatant<'a> {
72//! pub entity: Entity,
73//! pub health: &'a mut Health,
74//! pub armor: &'a Armor,
75//! /// `None` for a row that carries no mana.
76//! pub mana: Option<&'a Mana>,
77//! pub has_armor: Has<Armor>,
78//! }
79//! }
80//!
81//! let mut world = World::new();
82//! world.root_scope_mut().spawn(bundle![Health(10), Armor(2)]);
83//!
84//! for row in world.root_scope().query::<Combatant>().iter() {
85//! row.health.0 -= row.armor.0;
86//! assert!(row.has_armor);
87//! assert!(row.mana.is_none());
88//! }
89//! ```
90//!
91//! The declaration is one row: the macro derives the item struct and the
92//! [`Query`] impl from it. No `unsafe` is involved on the caller's side, and
93//! the claims the query makes are exactly the fields it declares: a component is
94//! claimed by asking the [`PlanBuilder`] for it, so there is no second list
95//! that could disagree with what the query actually reaches.
96
97use core::any::TypeId;
98use core::cell::UnsafeCell;
99use core::marker::PhantomData;
100
101use crate::archetype::Archetype;
102use crate::borrow::Claims;
103use crate::entity::Entity;
104use crate::world::World;
105
106#[macro_use]
107mod macros;
108mod iter;
109
110pub use iter::QueryIter;
111
112/// Whether a component is reached shared or exclusive.
113///
114/// A query reports it per component while it resolves its plan, so the holder
115/// knows what to claim before anything is handed out.
116#[derive(Clone, Copy, Debug, PartialEq, Eq)]
117pub enum Mode {
118 /// Reached shared.
119 Read,
120 /// Reached exclusive.
121 Write,
122}
123
124impl Mode {
125 /// The verb a conflict message uses for this mode as a requirement.
126 pub(crate) fn verb(self) -> &'static str {
127 match self {
128 Self::Read => "read",
129 Self::Write => "write",
130 }
131 }
132
133 /// How a conflict message describes a claim already held in this mode.
134 pub(crate) fn adverb(self) -> &'static str {
135 match self {
136 Self::Read => "shared",
137 Self::Write => "exclusively",
138 }
139 }
140}
141
142/// One component a query reaches, and how.
143pub(crate) type Ask = (TypeId, &'static str, Mode);
144
145/// A claimed column, shared.
146///
147/// Handed out by [`PlanBuilder::read`] and kept in a query's plan. It is
148/// [`Copy`], because reading a column twice is not a conflict.
149pub struct Col<'w, T: 'static> {
150 cells: &'w [UnsafeCell<T>],
151}
152
153impl<T: 'static> Clone for Col<'_, T> {
154 fn clone(&self) -> Self {
155 *self
156 }
157}
158
159impl<T: 'static> Copy for Col<'_, T> {}
160
161impl<'w, T: 'static> Col<'w, T> {
162 /// The value at `row`.
163 ///
164 /// It lives as long as the claim behind it, so nothing writes the column
165 /// while any item names it.
166 #[inline]
167 pub fn at(&self, row: usize) -> &'w T {
168 let cell = self
169 .cells
170 .get(row)
171 .unwrap_or_else(|| panic!("row {row} is past the end of a claimed column"));
172 // SAFETY: the holder claimed this column shared for 'w, so nothing
173 // writes it while this reference lives, and the row is in bounds.
174 unsafe { &*cell.get() }
175 }
176
177 /// The number of values in the column, one per row of the archetype.
178 #[inline]
179 #[must_use]
180 pub fn len(&self) -> usize {
181 self.cells.len()
182 }
183
184 /// Whether the column holds no value.
185 #[inline]
186 #[must_use]
187 pub fn is_empty(&self) -> bool {
188 self.cells.is_empty()
189 }
190}
191
192/// A claimed column, exclusive.
193///
194/// Handed out by [`PlanBuilder::write`] and kept in a query's plan. Unlike
195/// [`Col`] it is not [`Copy`], and [`ColMut::at`] takes the handle
196/// exclusively: that is what makes one [`Query::read`] hand out at most one
197/// exclusive reference per column, which in turn is why declaring a query needs
198/// no `unsafe`.
199pub struct ColMut<'w, T: 'static> {
200 cells: &'w [UnsafeCell<T>],
201}
202
203impl<'w, T: 'static> ColMut<'w, T> {
204 /// The value at `row`, exclusively.
205 ///
206 /// Taking `&mut self` is the safety argument: the caller can reach the
207 /// same cell twice only by calling this twice, and the first reference is
208 /// still alive then, so the compiler refuses the second call.
209 #[inline]
210 pub fn at(&mut self, row: usize) -> &mut T {
211 let cell = self
212 .cells
213 .get(row)
214 .unwrap_or_else(|| panic!("row {row} is past the end of a claimed column"));
215 // SAFETY: the holder claimed this column exclusively for the plan's
216 // life, and this handle is the only way to the cells, so no other
217 // reference to any row of it exists.
218 unsafe { &mut *cell.get() }
219 }
220
221 /// The number of values in the column, one per row of the archetype.
222 #[inline]
223 #[must_use]
224 pub fn len(&self) -> usize {
225 self.cells.len()
226 }
227
228 /// Whether the column holds no value.
229 #[inline]
230 #[must_use]
231 pub fn is_empty(&self) -> bool {
232 self.cells.is_empty()
233 }
234}
235
236/// What one archetype offers, and what a query asks of it while resolving its
237/// plan.
238///
239/// This is the only way a query reaches a column, so asking for one *is* the
240/// claim: there is no separate list of reached components that could disagree
241/// with what [`Query::read`] actually reads. A duplicate ask that would need
242/// two modes for one type is refused here, before anything is handed out.
243pub struct PlanBuilder<'w> {
244 archetype: &'w Archetype,
245 asked: Vec<Ask>,
246 marker: PhantomData<&'w ()>,
247}
248
249impl<'w> PlanBuilder<'w> {
250 pub(crate) fn new(archetype: &'w Archetype, asked: Vec<Ask>) -> Self {
251 Self {
252 archetype,
253 asked,
254 marker: PhantomData,
255 }
256 }
257
258 /// The asks recorded so far, which is what the holder claims.
259 pub(crate) fn asks(&self) -> &[Ask] {
260 &self.asked
261 }
262
263 /// Recover the buffer, so the next archetype reuses it instead of
264 /// allocating.
265 pub(crate) fn into_asks(self) -> Vec<Ask> {
266 self.asked
267 }
268
269 /// The archetype's column of `T`, shared. `None` when it carries no
270 /// `T`, which is what makes the query skip it.
271 pub fn read<T: 'static>(&mut self) -> Option<Col<'w, T>> {
272 let cells = self.ask::<T>(Mode::Read)?;
273 Some(Col { cells })
274 }
275
276 /// The archetype's column of `T`, exclusive. `None` when it carries no
277 /// `T`.
278 pub fn write<T: 'static>(&mut self) -> Option<ColMut<'w, T>> {
279 let cells = self.ask::<T>(Mode::Write)?;
280 Some(ColMut { cells })
281 }
282
283 /// Whether the archetype carries `T`.
284 ///
285 /// Claims nothing: a yes/no answer cannot alias anything, which is what
286 /// keeps `(&mut T, Has<T>)` legal.
287 #[inline]
288 #[must_use]
289 pub fn has<T: 'static>(&self) -> bool {
290 self.archetype.has::<T>()
291 }
292
293 /// The entities of the archetype, one per row.
294 #[inline]
295 #[must_use]
296 pub fn entities(&self) -> &'w [Entity] {
297 self.archetype.entities()
298 }
299
300 /// Record that the query reaches `T` in `mode`, and resolve its column.
301 ///
302 /// Panics when the same query asks for `T` twice with at least one of the
303 /// asks exclusive: the two would hand out references that cannot coexist.
304 fn ask<T: 'static>(&mut self, mode: Mode) -> Option<&'w [UnsafeCell<T>]> {
305 let type_id = TypeId::of::<T>();
306 for (asked, name, asked_mode) in &self.asked {
307 if *asked == type_id && (*asked_mode == Mode::Write || mode == Mode::Write) {
308 panic!(
309 "component `{name}` is already borrowed {} by this query, and this {} cannot share it",
310 asked_mode.adverb(),
311 mode.verb(),
312 );
313 }
314 }
315 self.asked
316 .push((type_id, core::any::type_name::<T>(), mode));
317 self.archetype.column::<T>().map(|column| column.cells())
318 }
319}
320
321/// What to fetch from every entity a query matches.
322///
323/// The type is the query: it says which components to hand out and which
324/// archetypes to visit. A query is resolved once per archetype into
325/// [`Query::Plan`] and then read once per row, so iterating costs one
326/// component lookup per archetype rather than one per row.
327///
328/// The impls cover the forms listed in the [module documentation](self), and the
329/// [`crate::query!`] macro derives this trait for a row of the caller's own.
330///
331/// Implementing it by hand needs no `unsafe`: the plan is built through a
332/// [`PlanBuilder`], which claims the very columns it hands out.
333#[diagnostic::on_unimplemented(
334 message = "`{Self}` is not a query",
335 label = "a query is `&C`, `&mut C`, `Option<&C>`, `Option<&mut C>`, `Entity`, `Has<C>`, or a tuple of those",
336 note = "`&(a, b)` is one component whose type is the tuple, and `(&a, &b)` is two; a row with named fields is declared with `query!`"
337)]
338pub trait Query {
339 /// What one matched row yields.
340 ///
341 /// It borrows from the holder that yielded it, never from the world, so an
342 /// item cannot outlive the claims behind it.
343 type Item<'a>;
344
345 /// What is resolved once per archetype and then read once per row.
346 ///
347 /// It borrows from the world, so it may keep the columns of the archetype.
348 /// A row is read through `&mut` of it, which is what keeps the exclusive
349 /// references of one read from aliasing those of the next.
350 type Plan<'w>;
351
352 /// Resolve the plan for one archetype.
353 ///
354 /// `None` means the archetype does not match, and the query skips it.
355 /// Asking the builder for a column the archetype lacks is how a required
356 /// component narrows the query: `builder.read::<T>()?`.
357 fn prepare<'w>(builder: &mut PlanBuilder<'w>) -> Option<Self::Plan<'w>>;
358
359 /// Read the row at `row` through the resolved plan.
360 ///
361 /// The plan is taken exclusively, so one call reaches at most one exclusive
362 /// reference per column.
363 fn read<'a, 'w: 'a>(plan: &'a mut Self::Plan<'w>, row: usize) -> Self::Item<'a>;
364}
365
366/// Asks for `T` shared.
367impl<T: 'static> Query for &T {
368 type Item<'a> = &'a T;
369 type Plan<'w> = Col<'w, T>;
370
371 fn prepare<'w>(builder: &mut PlanBuilder<'w>) -> Option<Self::Plan<'w>> {
372 builder.read::<T>()
373 }
374
375 fn read<'a, 'w: 'a>(plan: &'a mut Self::Plan<'w>, row: usize) -> Self::Item<'a> {
376 plan.at(row)
377 }
378}
379
380/// Asks for `T` exclusive.
381impl<T: 'static> Query for &mut T {
382 type Item<'a> = &'a mut T;
383 type Plan<'w> = ColMut<'w, T>;
384
385 fn prepare<'w>(builder: &mut PlanBuilder<'w>) -> Option<Self::Plan<'w>> {
386 builder.write::<T>()
387 }
388
389 fn read<'a, 'w: 'a>(plan: &'a mut Self::Plan<'w>, row: usize) -> Self::Item<'a> {
390 plan.at(row)
391 }
392}
393
394/// Asks for `T` shared when the archetype carries it.
395impl<T: 'static> Query for Option<&T> {
396 type Item<'a> = Option<&'a T>;
397 type Plan<'w> = Option<Col<'w, T>>;
398
399 fn prepare<'w>(builder: &mut PlanBuilder<'w>) -> Option<Self::Plan<'w>> {
400 Some(builder.read::<T>())
401 }
402
403 fn read<'a, 'w: 'a>(plan: &'a mut Self::Plan<'w>, row: usize) -> Self::Item<'a> {
404 plan.as_ref().map(|column| column.at(row))
405 }
406}
407
408/// Asks for `T` exclusive when the archetype carries it.
409impl<T: 'static> Query for Option<&mut T> {
410 type Item<'a> = Option<&'a mut T>;
411 type Plan<'w> = Option<ColMut<'w, T>>;
412
413 fn prepare<'w>(builder: &mut PlanBuilder<'w>) -> Option<Self::Plan<'w>> {
414 Some(builder.write::<T>())
415 }
416
417 fn read<'a, 'w: 'a>(plan: &'a mut Self::Plan<'w>, row: usize) -> Self::Item<'a> {
418 plan.as_mut().map(|column| column.at(row))
419 }
420}
421
422/// Asks for the entity itself.
423///
424/// It is an item like any other, so it can be written first, last, or on its
425/// own: a query over `Entity` alone yields every entity the scope sees.
426impl Query for Entity {
427 type Item<'a> = Entity;
428 type Plan<'w> = &'w [Entity];
429
430 fn prepare<'w>(builder: &mut PlanBuilder<'w>) -> Option<Self::Plan<'w>> {
431 Some(builder.entities())
432 }
433
434 fn read<'a, 'w: 'a>(plan: &'a mut Self::Plan<'w>, row: usize) -> Self::Item<'a> {
435 plan[row]
436 }
437}
438
439/// Yields whether the archetype carries `T`.
440///
441/// The answer is read from the archetype's component set, so it reaches no value
442/// and never conflicts: `(&mut T, Has<T>)` is legal. Use it instead of
443/// `Option<&T>::is_some()` to ask about a component without borrowing it.
444///
445/// It narrows nothing: every archetype matches, and a row whose archetype lacks
446/// `T` yields `false`. That is what lets a query report presence for rows it
447/// was going to visit anyway, and what keeps `query_one::<Has<T>>` answering
448/// `Ok(false)` rather than an error for an entity that lacks `T`. To visit
449/// only the archetypes carrying `T`, pair it with
450/// [`crate::QueryBorrow::by`]: `.by(|archetype: &Archetype| archetype.has::<T>())`.
451#[derive(Clone, Copy, Debug)]
452pub struct Has<T>(PhantomData<fn() -> T>);
453
454impl<T: 'static> Query for Has<T> {
455 type Item<'a> = bool;
456 type Plan<'w> = bool;
457
458 fn prepare<'w>(builder: &mut PlanBuilder<'w>) -> Option<Self::Plan<'w>> {
459 Some(builder.has::<T>())
460 }
461
462 fn read<'a, 'w: 'a>(plan: &'a mut Self::Plan<'w>, _: usize) -> Self::Item<'a> {
463 *plan
464 }
465}
466
467macro_rules! impl_tuple {
468 ($($name:ident),+) => {
469 /// Asks for every member, yielding a tuple of their items.
470 impl<$($name: Query),+> Query for ($($name,)+) {
471 type Item<'a> = ($($name::Item<'a>,)+);
472 type Plan<'w> = ($($name::Plan<'w>,)+);
473
474 fn prepare<'w>(builder: &mut PlanBuilder<'w>) -> Option<Self::Plan<'w>> {
475 Some(($($name::prepare(builder)?,)+))
476 }
477
478 fn read<'a, 'w: 'a>(plan: &'a mut Self::Plan<'w>, row: usize) -> Self::Item<'a> {
479 #[expect(non_snake_case, reason = "the pattern binds one variable per tuple member")]
480 let ($($name,)+) = plan;
481 ($($name::read($name, row),)+)
482 }
483 }
484 };
485}
486
487impl_tuple!(Q0);
488impl_tuple!(Q0, Q1);
489impl_tuple!(Q0, Q1, Q2);
490impl_tuple!(Q0, Q1, Q2, Q3);
491impl_tuple!(Q0, Q1, Q2, Q3, Q4);
492impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5);
493impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5, Q6);
494impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7);
495impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8);
496impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9);
497impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10);
498impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11);
499impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12);
500impl_tuple!(Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13);
501impl_tuple!(
502 Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14
503);
504impl_tuple!(
505 Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15
506);
507
508/// Narrows the archetypes a query visits.
509///
510/// An unadorned query accepts every archetype its items match.
511/// [`crate::QueryBorrow::by`] installs a filter.
512///
513/// A filter is answered from the archetype alone, before any row is fetched and
514/// before any value is reached. Deciding there rather than skipping rows in the
515/// loop is both faster -- a rejected archetype costs one test instead of one per
516/// row -- and correct when the rows it rejects carry a component the caller
517/// reaches exclusively.
518///
519/// Implemented for `()`, which accepts everything, and for any
520/// `Fn(&Archetype) -> bool`. A closure can decide from anything an archetype
521/// knows, including a component set only known at run time, which a type-written
522/// query cannot name.
523///
524/// ```rust
525/// # use unlit_ecs::{Archetype, World, bundle};
526/// let mut world = World::new();
527/// world.root_scope_mut().spawn(bundle![1u32, true]);
528/// world.root_scope_mut().spawn(bundle![2u32]);
529///
530/// let mut query = world
531/// .root_scope()
532/// .query::<&u32>()
533/// .by(|archetype: &Archetype| !archetype.has::<bool>());
534/// let sum: u32 = query.iter().map(|value| *value).sum();
535/// assert_eq!(sum, 2);
536/// ```
537pub trait ArchetypeFilter {
538 /// Whether entities of `archetype` belong to this query.
539 fn accept(&self, archetype: &Archetype) -> bool;
540}
541
542impl ArchetypeFilter for () {
543 fn accept(&self, _: &Archetype) -> bool {
544 true
545 }
546}
547
548impl<F: Fn(&Archetype) -> bool> ArchetypeFilter for F {
549 fn accept(&self, archetype: &Archetype) -> bool {
550 self(archetype)
551 }
552}
553
554/// What a scope hands out for a query: the claims, and the way to iterate them.
555///
556/// The holder is created by [`crate::Scope::query`] and claims the components
557/// the query reaches, archetype by archetype, before it hands out anything.
558/// Iterating is [`QueryBorrow::iter`], and every item it yields borrows from
559/// this holder, so the claims outlive the items by construction.
560///
561/// Dropping the holder releases the claims. Forgetting it instead
562/// ([`core::mem::forget`]) leaks them: the components stay claimed for the rest
563/// of the world's life, and the next query for them panics rather than running
564/// alongside.
565pub struct QueryBorrow<'w, Q: Query, F: ArchetypeFilter = ()> {
566 world: &'w World,
567 scope: Entity,
568 filter: F,
569 claims: Claims<'w>,
570 /// The buffer a pass over the archetypes records its asks in, kept here so
571 /// that a second pass reuses it rather than allocating again.
572 asks: Vec<Ask>,
573 origin: &'static core::panic::Location<'static>,
574 marker: PhantomData<fn() -> Q>,
575}
576
577impl<'w, Q: Query> QueryBorrow<'w, Q, ()> {
578 pub(crate) fn new(
579 world: &'w World,
580 scope: Entity,
581 origin: &'static core::panic::Location<'static>,
582 ) -> Self {
583 Self {
584 world,
585 scope,
586 filter: (),
587 claims: Claims::new(world),
588 asks: Vec::new(),
589 origin,
590 marker: PhantomData,
591 }
592 }
593}
594
595impl<'w, Q: Query, F: ArchetypeFilter> QueryBorrow<'w, Q, F> {
596 /// Visit only the archetypes the filter accepts.
597 ///
598 /// The filter sees an archetype before any of its rows is fetched and before
599 /// any value is reached, so rejecting an archetype costs one test rather than
600 /// one per row, and works even when that archetype's components are already
601 /// claimed elsewhere. See [`ArchetypeFilter`].
602 ///
603 /// It may be applied part-way through an iteration, and then narrows the
604 /// archetype being visited too: what the filter rejects is not fetched, and
605 /// the rows already yielded stay yielded.
606 #[must_use]
607 pub fn by<G: ArchetypeFilter>(self, filter: G) -> QueryBorrow<'w, Q, G> {
608 QueryBorrow {
609 world: self.world,
610 scope: self.scope,
611 filter,
612 claims: self.claims,
613 asks: self.asks,
614 origin: self.origin,
615 marker: PhantomData,
616 }
617 }
618
619 /// Iterate the visible entities that match `Q`.
620 ///
621 /// The items borrow from this holder, so they cannot outlive it and it
622 /// cannot be iterated for one item at a time while another is alive: collect
623 /// them, or finish with each row before reaching for the next.
624 pub fn iter(&mut self) -> QueryIter<'_, 'w, Q> {
625 QueryIter::new(
626 self.world,
627 self.scope,
628 &self.filter,
629 &mut self.claims,
630 &mut self.asks,
631 self.origin,
632 )
633 }
634}
635
636/// What a scope hands out for a query over one entity.
637///
638/// Made by [`crate::Scope::query_one`], which claims the components the query
639/// reaches on that entity's row. A missing match is still answered with an
640/// error rather than a holder, so a caller that finds nothing holds no claim.
641///
642/// [`QueryOne::get`] is what reads the row, and it takes the holder
643/// exclusively: an exclusive item borrows from the call, so the compiler refuses
644/// a second one while the first is alive.
645pub struct QueryOne<'w, Q: Query> {
646 row: usize,
647 plan: Q::Plan<'w>,
648 /// Held for the life of the holder: dropping it is what releases the claim.
649 _claims: Claims<'w>,
650 marker: PhantomData<fn() -> Q>,
651}
652
653impl<'w, Q: Query> QueryOne<'w, Q> {
654 pub(crate) fn new(plan: Q::Plan<'w>, row: usize, claims: Claims<'w>) -> Self {
655 Self {
656 row,
657 plan,
658 _claims: claims,
659 marker: PhantomData,
660 }
661 }
662
663 /// What the query yields for this entity's row.
664 pub fn get(&mut self) -> Q::Item<'_> {
665 Q::read(&mut self.plan, self.row)
666 }
667}
668
669impl<Q: Query> core::fmt::Debug for QueryOne<'_, Q> {
670 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
671 f.debug_struct("QueryOne")
672 .field("row", &self.row)
673 .finish_non_exhaustive()
674 }
675}
676
677impl<Q: Query, F: ArchetypeFilter> core::fmt::Debug for QueryBorrow<'_, Q, F> {
678 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
679 f.debug_struct("QueryBorrow")
680 .field("scope", &self.scope)
681 .finish_non_exhaustive()
682 }
683}