hecs/
query.rs

1#[cfg(feature = "std")]
2use core::any::Any;
3use core::any::TypeId;
4use core::marker::PhantomData;
5use core::ptr::NonNull;
6use core::slice::Iter as SliceIter;
7#[cfg(feature = "std")]
8use std::sync::{Arc, RwLock};
9
10use crate::alloc::boxed::Box;
11#[cfg(feature = "std")]
12use hashbrown::hash_map;
13
14use crate::archetype::Archetype;
15use crate::entities::EntityMeta;
16#[cfg(feature = "std")]
17use crate::TypeIdMap;
18use crate::{Component, Entity, World};
19
20/// A collection of component types to fetch from a [`World`](crate::World)
21///
22/// The interface of this trait is a private implementation detail.
23pub trait Query {
24    /// Type of results yielded by the query
25    ///
26    /// This is usually the same type as the query itself, except with an appropriate lifetime.
27    type Item<'a>;
28
29    #[doc(hidden)]
30    type Fetch: Fetch;
31
32    #[doc(hidden)]
33    /// Access the `n`th item in this archetype, an entity with generation `generation`, without bounds checking
34    ///
35    /// # Safety
36    /// - Must only be called after [`Fetch::borrow`] or with exclusive access to the archetype
37    /// - [`Fetch::release`] must not be called while `'a` is still live
38    /// - Bounds-checking must be performed externally
39    /// - Any resulting borrows must be legal (e.g. no &mut to something another iterator might access)
40    unsafe fn get<'a>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'a>;
41}
42
43/// Marker trait indicating whether a given [`Query`] will not produce unique references
44#[allow(clippy::missing_safety_doc)]
45pub unsafe trait QueryShared {}
46
47/// Streaming iterators over contiguous homogeneous ranges of components
48#[allow(clippy::missing_safety_doc)]
49pub unsafe trait Fetch: Clone + Sized + 'static {
50    /// The type of the data which can be cached to speed up retrieving
51    /// the relevant type states from a matching [`Archetype`]
52    type State: Copy + Send + Sync;
53
54    /// A value on which `get` may never be called
55    fn dangling() -> Self;
56
57    /// How this query will access `archetype`, if at all
58    fn access(archetype: &Archetype) -> Option<Access>;
59
60    /// Acquire dynamic borrows from `archetype`
61    fn borrow(archetype: &Archetype, state: Self::State);
62    /// Look up state for `archetype` if it should be traversed
63    fn prepare(archetype: &Archetype) -> Option<Self::State>;
64    /// Construct a `Fetch` for `archetype` based on the associated state
65    fn execute(archetype: &Archetype, state: Self::State) -> Self;
66    /// Release dynamic borrows acquired by `borrow`
67    fn release(archetype: &Archetype, state: Self::State);
68
69    /// Invoke `f` for every component type that may be borrowed and whether the borrow is unique
70    fn for_each_borrow(f: impl FnMut(TypeId, bool));
71}
72
73/// Type of access a [`Query`] may have to an [`Archetype`]
74#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
75pub enum Access {
76    /// Read entity IDs only, no components
77    Iterate,
78    /// Read components
79    Read,
80    /// Read and write components
81    Write,
82}
83
84impl Query for Entity {
85    type Item<'q> = Entity;
86    type Fetch = FetchEntity;
87
88    unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
89        let id = fetch.0.as_ptr().add(n).read();
90        Entity {
91            id,
92            generation: meta.get_unchecked(id as usize).generation,
93        }
94    }
95}
96unsafe impl QueryShared for Entity {}
97
98#[doc(hidden)]
99#[derive(Clone)]
100pub struct FetchEntity(NonNull<u32>);
101
102unsafe impl Fetch for FetchEntity {
103    type State = ();
104
105    fn dangling() -> Self {
106        Self(NonNull::dangling())
107    }
108
109    fn access(_: &Archetype) -> Option<Access> {
110        Some(Access::Iterate)
111    }
112
113    fn borrow(_: &Archetype, (): Self::State) {}
114
115    fn prepare(_: &Archetype) -> Option<Self::State> {
116        Some(())
117    }
118
119    fn execute(archetype: &Archetype, (): Self::State) -> Self {
120        Self(archetype.entities())
121    }
122
123    fn release(_: &Archetype, (): Self::State) {}
124
125    fn for_each_borrow(_: impl FnMut(TypeId, bool)) {}
126}
127
128impl<T: Component> Query for &'_ T {
129    type Item<'q> = &'q T;
130
131    type Fetch = FetchRead<T>;
132
133    unsafe fn get<'q>(_: &[EntityMeta], fetch: &FetchRead<T>, n: usize) -> &'q T {
134        &*fetch.0.as_ptr().add(n)
135    }
136}
137
138unsafe impl<T> QueryShared for &'_ T {}
139
140#[doc(hidden)]
141pub struct FetchRead<T>(NonNull<T>);
142
143unsafe impl<T: Component> Fetch for FetchRead<T> {
144    type State = usize;
145
146    fn dangling() -> Self {
147        Self(NonNull::dangling())
148    }
149
150    fn access(archetype: &Archetype) -> Option<Access> {
151        if archetype.has::<T>() {
152            Some(Access::Read)
153        } else {
154            None
155        }
156    }
157
158    fn borrow(archetype: &Archetype, state: Self::State) {
159        archetype.borrow::<T>(state);
160    }
161    fn prepare(archetype: &Archetype) -> Option<Self::State> {
162        archetype.get_state::<T>()
163    }
164    fn execute(archetype: &Archetype, state: Self::State) -> Self {
165        unsafe { Self(archetype.get_base(state)) }
166    }
167    fn release(archetype: &Archetype, state: Self::State) {
168        archetype.release::<T>(state);
169    }
170
171    fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
172        f(TypeId::of::<T>(), false);
173    }
174}
175
176impl<T> Clone for FetchRead<T> {
177    #[inline]
178    fn clone(&self) -> Self {
179        Self(self.0)
180    }
181}
182
183impl<T: Component> Query for &'_ mut T {
184    type Item<'q> = &'q mut T;
185
186    type Fetch = FetchWrite<T>;
187
188    unsafe fn get<'q>(_: &[EntityMeta], fetch: &FetchWrite<T>, n: usize) -> &'q mut T {
189        &mut *fetch.0.as_ptr().add(n)
190    }
191}
192
193#[doc(hidden)]
194pub struct FetchWrite<T>(NonNull<T>);
195
196unsafe impl<T: Component> Fetch for FetchWrite<T> {
197    type State = usize;
198
199    fn dangling() -> Self {
200        Self(NonNull::dangling())
201    }
202
203    fn access(archetype: &Archetype) -> Option<Access> {
204        if archetype.has::<T>() {
205            Some(Access::Write)
206        } else {
207            None
208        }
209    }
210
211    fn borrow(archetype: &Archetype, state: Self::State) {
212        archetype.borrow_mut::<T>(state);
213    }
214    #[allow(clippy::needless_question_mark)]
215    fn prepare(archetype: &Archetype) -> Option<Self::State> {
216        Some(archetype.get_state::<T>()?)
217    }
218    fn execute(archetype: &Archetype, state: Self::State) -> Self {
219        unsafe { Self(archetype.get_base::<T>(state)) }
220    }
221    fn release(archetype: &Archetype, state: Self::State) {
222        archetype.release_mut::<T>(state);
223    }
224
225    fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
226        f(TypeId::of::<T>(), true);
227    }
228}
229
230impl<T> Clone for FetchWrite<T> {
231    #[inline]
232    fn clone(&self) -> Self {
233        Self(self.0)
234    }
235}
236
237impl<T: Query> Query for Option<T> {
238    type Item<'q> = Option<T::Item<'q>>;
239
240    type Fetch = TryFetch<T::Fetch>;
241
242    unsafe fn get<'q>(
243        meta: &[EntityMeta],
244        fetch: &TryFetch<T::Fetch>,
245        n: usize,
246    ) -> Option<T::Item<'q>> {
247        Some(T::get(meta, fetch.0.as_ref()?, n))
248    }
249}
250
251unsafe impl<T: QueryShared> QueryShared for Option<T> {}
252
253#[doc(hidden)]
254#[derive(Clone)]
255pub struct TryFetch<T>(Option<T>);
256
257unsafe impl<T: Fetch> Fetch for TryFetch<T> {
258    type State = Option<T::State>;
259
260    fn dangling() -> Self {
261        Self(None)
262    }
263
264    fn access(archetype: &Archetype) -> Option<Access> {
265        Some(T::access(archetype).unwrap_or(Access::Iterate))
266    }
267
268    fn borrow(archetype: &Archetype, state: Self::State) {
269        if let Some(state) = state {
270            T::borrow(archetype, state);
271        }
272    }
273    fn prepare(archetype: &Archetype) -> Option<Self::State> {
274        Some(T::prepare(archetype))
275    }
276    fn execute(archetype: &Archetype, state: Self::State) -> Self {
277        Self(state.map(|state| T::execute(archetype, state)))
278    }
279    fn release(archetype: &Archetype, state: Self::State) {
280        if let Some(state) = state {
281            T::release(archetype, state);
282        }
283    }
284
285    fn for_each_borrow(f: impl FnMut(TypeId, bool)) {
286        T::for_each_borrow(f);
287    }
288}
289
290/// Holds an `L`, or an `R`, or both
291#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
292pub enum Or<L, R> {
293    /// Just an `L`
294    Left(L),
295    /// Just an `R`
296    Right(R),
297    /// Both an `L` and an `R`
298    Both(L, R),
299}
300
301impl<L, R> Or<L, R> {
302    /// Construct an `Or<L, R>` if at least one argument is `Some`
303    pub fn new(l: Option<L>, r: Option<R>) -> Option<Self> {
304        match (l, r) {
305            (None, None) => None,
306            (Some(l), None) => Some(Or::Left(l)),
307            (None, Some(r)) => Some(Or::Right(r)),
308            (Some(l), Some(r)) => Some(Or::Both(l, r)),
309        }
310    }
311
312    /// Destructure into two `Option`s, where either or both are `Some`
313    pub fn split(self) -> (Option<L>, Option<R>) {
314        match self {
315            Or::Left(l) => (Some(l), None),
316            Or::Right(r) => (None, Some(r)),
317            Or::Both(l, r) => (Some(l), Some(r)),
318        }
319    }
320
321    /// Extract `L` regardless of whether `R` is present
322    pub fn left(self) -> Option<L> {
323        match self {
324            Or::Left(l) => Some(l),
325            Or::Both(l, _) => Some(l),
326            _ => None,
327        }
328    }
329
330    /// Extract `R` regardless of whether `L` is present
331    pub fn right(self) -> Option<R> {
332        match self {
333            Or::Right(r) => Some(r),
334            Or::Both(_, r) => Some(r),
335            _ => None,
336        }
337    }
338
339    /// Transform `L` with `f` and `R` with `g`
340    pub fn map<L1, R1, F, G>(self, f: F, g: G) -> Or<L1, R1>
341    where
342        F: FnOnce(L) -> L1,
343        G: FnOnce(R) -> R1,
344    {
345        match self {
346            Or::Left(l) => Or::Left(f(l)),
347            Or::Right(r) => Or::Right(g(r)),
348            Or::Both(l, r) => Or::Both(f(l), g(r)),
349        }
350    }
351
352    /// Convert from `&Or<L, R>` to `Or<&L, &R>`
353    pub fn as_ref(&self) -> Or<&L, &R> {
354        match *self {
355            Or::Left(ref l) => Or::Left(l),
356            Or::Right(ref r) => Or::Right(r),
357            Or::Both(ref l, ref r) => Or::Both(l, r),
358        }
359    }
360
361    /// Convert from `&mut Or<L, R>` to `Or<&mut L, &mut R>`
362    pub fn as_mut(&mut self) -> Or<&mut L, &mut R> {
363        match *self {
364            Or::Left(ref mut l) => Or::Left(l),
365            Or::Right(ref mut r) => Or::Right(r),
366            Or::Both(ref mut l, ref mut r) => Or::Both(l, r),
367        }
368    }
369}
370
371impl<L, R> Or<&'_ L, &'_ R>
372where
373    L: Clone,
374    R: Clone,
375{
376    /// Maps an `Or<&L, &R>` to an `Or<L, R>` by cloning its contents
377    pub fn cloned(self) -> Or<L, R> {
378        self.map(Clone::clone, Clone::clone)
379    }
380}
381
382impl<L: Query, R: Query> Query for Or<L, R> {
383    type Item<'q> = Or<L::Item<'q>, R::Item<'q>>;
384
385    type Fetch = FetchOr<L::Fetch, R::Fetch>;
386
387    unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
388        fetch
389            .0
390            .as_ref()
391            .map(|l| L::get(meta, l, n), |r| R::get(meta, r, n))
392    }
393}
394
395unsafe impl<L: QueryShared, R: QueryShared> QueryShared for Or<L, R> {}
396
397#[doc(hidden)]
398#[derive(Clone)]
399pub struct FetchOr<L, R>(Or<L, R>);
400
401unsafe impl<L: Fetch, R: Fetch> Fetch for FetchOr<L, R> {
402    type State = Or<L::State, R::State>;
403
404    fn dangling() -> Self {
405        Self(Or::Left(L::dangling()))
406    }
407
408    fn access(archetype: &Archetype) -> Option<Access> {
409        L::access(archetype).max(R::access(archetype))
410    }
411
412    fn borrow(archetype: &Archetype, state: Self::State) {
413        state.map(|l| L::borrow(archetype, l), |r| R::borrow(archetype, r));
414    }
415
416    fn prepare(archetype: &Archetype) -> Option<Self::State> {
417        Or::new(L::prepare(archetype), R::prepare(archetype))
418    }
419
420    fn execute(archetype: &Archetype, state: Self::State) -> Self {
421        Self(state.map(|l| L::execute(archetype, l), |r| R::execute(archetype, r)))
422    }
423
424    fn release(archetype: &Archetype, state: Self::State) {
425        state.map(|l| L::release(archetype, l), |r| R::release(archetype, r));
426    }
427
428    fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
429        L::for_each_borrow(&mut f);
430        R::for_each_borrow(&mut f);
431    }
432}
433
434/// Transforms query `Q` by skipping entities satisfying query `R`
435///
436/// See also `QueryBorrow::without`.
437///
438/// # Example
439/// ```
440/// # use hecs::*;
441/// let mut world = World::new();
442/// let a = world.spawn((123, true, "abc"));
443/// let b = world.spawn((456, false));
444/// let c = world.spawn((42, "def"));
445/// let entities = world.query::<Without<(Entity, &i32), &bool>>()
446///     .iter()
447///     .map(|(e, &i)| (e, i))
448///     .collect::<Vec<_>>();
449/// assert_eq!(entities, &[(c, 42)]);
450/// ```
451pub struct Without<Q, R>(PhantomData<(Q, fn(R))>);
452
453impl<Q: Query, R: Query> Query for Without<Q, R> {
454    type Item<'q> = Q::Item<'q>;
455
456    type Fetch = FetchWithout<Q::Fetch, R::Fetch>;
457
458    unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
459        Q::get(meta, &fetch.0, n)
460    }
461}
462
463unsafe impl<Q: QueryShared, R> QueryShared for Without<Q, R> {}
464
465#[doc(hidden)]
466pub struct FetchWithout<F, G>(F, PhantomData<fn(G)>);
467
468unsafe impl<F: Fetch, G: Fetch> Fetch for FetchWithout<F, G> {
469    type State = F::State;
470
471    fn dangling() -> Self {
472        Self(F::dangling(), PhantomData)
473    }
474
475    fn access(archetype: &Archetype) -> Option<Access> {
476        if G::access(archetype).is_some() {
477            None
478        } else {
479            F::access(archetype)
480        }
481    }
482
483    fn borrow(archetype: &Archetype, state: Self::State) {
484        F::borrow(archetype, state)
485    }
486    fn prepare(archetype: &Archetype) -> Option<Self::State> {
487        if G::access(archetype).is_some() {
488            return None;
489        }
490        F::prepare(archetype)
491    }
492    fn execute(archetype: &Archetype, state: Self::State) -> Self {
493        Self(F::execute(archetype, state), PhantomData)
494    }
495    fn release(archetype: &Archetype, state: Self::State) {
496        F::release(archetype, state)
497    }
498
499    fn for_each_borrow(f: impl FnMut(TypeId, bool)) {
500        F::for_each_borrow(f);
501    }
502}
503
504impl<F: Clone, G> Clone for FetchWithout<F, G> {
505    #[inline]
506    fn clone(&self) -> Self {
507        Self(self.0.clone(), PhantomData)
508    }
509}
510
511/// Transforms query `Q` by skipping entities not satisfying query `R`
512///
513/// See also `QueryBorrow::with`.
514///
515/// # Example
516/// ```
517/// # use hecs::*;
518/// let mut world = World::new();
519/// let a = world.spawn((123, true, "abc"));
520/// let b = world.spawn((456, false));
521/// let c = world.spawn((42, "def"));
522/// let entities = world.query::<With<(Entity, &i32), &bool>>()
523///     .iter()
524///     .map(|(e, &i)| (e, i))
525///     .collect::<Vec<_>>();
526/// assert_eq!(entities.len(), 2);
527/// assert!(entities.contains(&(a, 123)));
528/// assert!(entities.contains(&(b, 456)));
529/// ```
530pub struct With<Q, R>(PhantomData<(Q, fn(R))>);
531
532impl<Q: Query, R: Query> Query for With<Q, R> {
533    type Item<'q> = Q::Item<'q>;
534
535    type Fetch = FetchWith<Q::Fetch, R::Fetch>;
536
537    unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
538        Q::get(meta, &fetch.0, n)
539    }
540}
541
542unsafe impl<Q: QueryShared, R> QueryShared for With<Q, R> {}
543
544#[doc(hidden)]
545pub struct FetchWith<F, G>(F, PhantomData<fn(G)>);
546
547unsafe impl<F: Fetch, G: Fetch> Fetch for FetchWith<F, G> {
548    type State = F::State;
549
550    fn dangling() -> Self {
551        Self(F::dangling(), PhantomData)
552    }
553
554    fn access(archetype: &Archetype) -> Option<Access> {
555        if G::access(archetype).is_some() {
556            F::access(archetype)
557        } else {
558            None
559        }
560    }
561
562    fn borrow(archetype: &Archetype, state: Self::State) {
563        F::borrow(archetype, state)
564    }
565    fn prepare(archetype: &Archetype) -> Option<Self::State> {
566        G::access(archetype)?;
567        F::prepare(archetype)
568    }
569    fn execute(archetype: &Archetype, state: Self::State) -> Self {
570        Self(F::execute(archetype, state), PhantomData)
571    }
572    fn release(archetype: &Archetype, state: Self::State) {
573        F::release(archetype, state)
574    }
575
576    fn for_each_borrow(f: impl FnMut(TypeId, bool)) {
577        F::for_each_borrow(f);
578    }
579}
580
581impl<F: Clone, G> Clone for FetchWith<F, G> {
582    #[inline]
583    fn clone(&self) -> Self {
584        Self(self.0.clone(), PhantomData)
585    }
586}
587
588/// A query that matches all entities, yielding `bool`s indicating whether each satisfies query `Q`
589///
590/// Does not borrow any components, making it faster and more concurrency-friendly than `Option<Q>`.
591///
592/// # Example
593/// ```
594/// # use hecs::*;
595/// let mut world = World::new();
596/// let a = world.spawn((123, true, "abc"));
597/// let b = world.spawn((456, false));
598/// let c = world.spawn((42, "def"));
599/// let entities = world.query::<(Entity, Satisfies<&bool>)>()
600///     .iter()
601///     .collect::<Vec<_>>();
602/// assert_eq!(entities.len(), 3);
603/// assert!(entities.contains(&(a, true)));
604/// assert!(entities.contains(&(b, true)));
605/// assert!(entities.contains(&(c, false)));
606/// ```
607pub struct Satisfies<Q>(PhantomData<Q>);
608
609impl<Q: Query> Query for Satisfies<Q> {
610    type Item<'q> = bool;
611
612    type Fetch = FetchSatisfies<Q::Fetch>;
613
614    unsafe fn get<'q>(_: &[EntityMeta], fetch: &Self::Fetch, _: usize) -> Self::Item<'q> {
615        fetch.0
616    }
617}
618
619unsafe impl<Q> QueryShared for Satisfies<Q> {}
620
621#[doc(hidden)]
622pub struct FetchSatisfies<F>(bool, PhantomData<F>);
623
624unsafe impl<F: Fetch> Fetch for FetchSatisfies<F> {
625    type State = bool;
626
627    fn dangling() -> Self {
628        Self(false, PhantomData)
629    }
630
631    fn access(_archetype: &Archetype) -> Option<Access> {
632        Some(Access::Iterate)
633    }
634
635    fn borrow(_archetype: &Archetype, _state: Self::State) {}
636    fn prepare(archetype: &Archetype) -> Option<Self::State> {
637        Some(F::prepare(archetype).is_some())
638    }
639    fn execute(_archetype: &Archetype, state: Self::State) -> Self {
640        Self(state, PhantomData)
641    }
642    fn release(_archetype: &Archetype, _state: Self::State) {}
643
644    fn for_each_borrow(_: impl FnMut(TypeId, bool)) {}
645}
646
647impl<T> Clone for FetchSatisfies<T> {
648    #[inline]
649    fn clone(&self) -> Self {
650        Self(self.0, PhantomData)
651    }
652}
653
654/// A borrow of a [`World`](crate::World) sufficient to execute the query `Q`
655///
656/// Note that borrows are not released until this object is dropped.
657pub struct QueryBorrow<'w, Q: Query> {
658    world: &'w World,
659    cache: Option<CachedQuery<Q::Fetch>>,
660}
661
662impl<'w, Q: Query> QueryBorrow<'w, Q> {
663    pub(crate) fn new(world: &'w World) -> Self {
664        Self { world, cache: None }
665    }
666
667    /// Execute the query
668    // The lifetime narrowing here is required for soundness.
669    pub fn iter(&mut self) -> QueryIter<'_, Q> {
670        let cache = self.borrow().clone();
671        unsafe { QueryIter::new(self.world, cache) }
672    }
673
674    /// Provide random access to the query results
675    pub fn view(&mut self) -> View<'_, Q> {
676        let cache = self.borrow().clone();
677        unsafe {
678            View::new(
679                self.world.entities_meta(),
680                self.world.archetypes_inner(),
681                cache,
682            )
683        }
684    }
685
686    /// Like `iter`, but returns child iterators of at most `batch_size` elements
687    ///
688    /// Useful for distributing work over a threadpool.
689    // The lifetime narrowing here is required for soundness.
690    pub fn iter_batched(&mut self, batch_size: u32) -> BatchedIter<'_, Q> {
691        let cache = self.borrow().clone();
692        unsafe {
693            BatchedIter::new(
694                self.world.entities_meta(),
695                self.world.archetypes_inner(),
696                batch_size,
697                cache,
698            )
699        }
700    }
701
702    fn borrow(&mut self) -> &CachedQuery<Q::Fetch> {
703        self.cache.get_or_insert_with(|| {
704            let cache = CachedQuery::get(self.world);
705            cache.borrow(self.world.archetypes_inner());
706            cache
707        })
708    }
709
710    /// Transform the query into one that requires another query be satisfied
711    ///
712    /// Convenient when the values of the components in the other query are not of interest.
713    ///
714    /// Equivalent to using a query type wrapped in `With`.
715    ///
716    /// # Example
717    /// ```
718    /// # use hecs::*;
719    /// let mut world = World::new();
720    /// let a = world.spawn((123, true, "abc"));
721    /// let b = world.spawn((456, false));
722    /// let c = world.spawn((42, "def"));
723    /// let entities = world.query::<(Entity, &i32)>()
724    ///     .with::<&bool>()
725    ///     .iter()
726    ///     .map(|(e, &i)| (e, i)) // Copy out of the world
727    ///     .collect::<Vec<_>>();
728    /// assert_eq!(entities.len(), 2);
729    /// assert!(entities.contains(&(a, 123)));
730    /// assert!(entities.contains(&(b, 456)));
731    /// ```
732    pub fn with<R: Query>(self) -> QueryBorrow<'w, With<Q, R>> {
733        self.transform()
734    }
735
736    /// Transform the query into one that skips entities satisfying another
737    ///
738    /// Equivalent to using a query type wrapped in `Without`.
739    ///
740    /// # Example
741    /// ```
742    /// # use hecs::*;
743    /// let mut world = World::new();
744    /// let a = world.spawn((123, true, "abc"));
745    /// let b = world.spawn((456, false));
746    /// let c = world.spawn((42, "def"));
747    /// let entities = world.query::<(Entity, &i32)>()
748    ///     .without::<&bool>()
749    ///     .iter()
750    ///     .map(|(e, &i)| (e, i)) // Copy out of the world
751    ///     .collect::<Vec<_>>();
752    /// assert_eq!(entities, &[(c, 42)]);
753    /// ```
754    pub fn without<R: Query>(self) -> QueryBorrow<'w, Without<Q, R>> {
755        self.transform()
756    }
757
758    /// Helper to change the type of the query
759    fn transform<R: Query>(self) -> QueryBorrow<'w, R> {
760        QueryBorrow {
761            world: self.world,
762            cache: None,
763        }
764    }
765}
766
767unsafe impl<Q: Query> Send for QueryBorrow<'_, Q> where for<'a> Q::Item<'a>: Send {}
768unsafe impl<Q: Query> Sync for QueryBorrow<'_, Q> where for<'a> Q::Item<'a>: Send {}
769
770impl<Q: Query> Drop for QueryBorrow<'_, Q> {
771    fn drop(&mut self) {
772        if let Some(cache) = &self.cache {
773            cache.release_borrow(self.world.archetypes_inner());
774        }
775    }
776}
777
778impl<'q, Q: Query> IntoIterator for &'q mut QueryBorrow<'_, Q> {
779    type Item = Q::Item<'q>;
780    type IntoIter = QueryIter<'q, Q>;
781
782    fn into_iter(self) -> Self::IntoIter {
783        self.iter()
784    }
785}
786
787/// Iterator over the set of entities with the components in `Q`
788pub struct QueryIter<'q, Q: Query> {
789    world: &'q World,
790    archetypes: ArchetypeIter<Q>,
791    iter: ChunkIter<Q>,
792}
793
794impl<'q, Q: Query> QueryIter<'q, Q> {
795    /// # Safety
796    ///
797    /// `'q` must be sufficient to guarantee that `Q` cannot violate borrow safety, either with
798    /// dynamic borrow checks or by representing exclusive access to the `World`. `cache` must be
799    /// from `world`.
800    unsafe fn new(world: &'q World, cache: CachedQuery<Q::Fetch>) -> Self {
801        Self {
802            world,
803            archetypes: ArchetypeIter::new(world, cache),
804            iter: ChunkIter::empty(),
805        }
806    }
807}
808
809unsafe impl<Q: Query> Send for QueryIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
810unsafe impl<Q: Query> Sync for QueryIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
811
812impl<'q, Q: Query> Iterator for QueryIter<'q, Q> {
813    type Item = Q::Item<'q>;
814
815    #[inline(always)]
816    fn next(&mut self) -> Option<Self::Item> {
817        loop {
818            match unsafe { self.iter.next(self.world.entities_meta()) } {
819                None => {
820                    // Safety: `self.world` is the same one we passed to `ArchetypeIter::new` just above
821                    unsafe {
822                        self.iter = self.archetypes.next(self.world)?;
823                    }
824                    continue;
825                }
826                Some(components) => {
827                    return Some(components);
828                }
829            }
830        }
831    }
832
833    fn size_hint(&self) -> (usize, Option<usize>) {
834        let n = self.len();
835        (n, Some(n))
836    }
837}
838
839impl<Q: Query> ExactSizeIterator for QueryIter<'_, Q> {
840    fn len(&self) -> usize {
841        self.archetypes.entity_len(self.world) + self.iter.remaining()
842    }
843}
844
845/// A query builder that's convertible directly into an iterator
846pub struct QueryMut<'q, Q: Query> {
847    world: &'q mut World,
848    _marker: PhantomData<fn() -> Q>,
849}
850
851impl<'q, Q: Query> QueryMut<'q, Q> {
852    pub(crate) fn new(world: &'q mut World) -> Self {
853        assert_borrow::<Q>();
854        Self {
855            world,
856            _marker: PhantomData,
857        }
858    }
859
860    /// Provide random access to the query results
861    pub fn view(&mut self) -> View<'_, Q> {
862        let cache = CachedQuery::get(self.world);
863        unsafe {
864            View::new(
865                self.world.entities_meta(),
866                self.world.archetypes_inner(),
867                cache,
868            )
869        }
870    }
871
872    /// Transform the query into one that requires another query be satisfied
873    ///
874    /// See `QueryBorrow::with`
875    pub fn with<R: Query>(self) -> QueryMut<'q, With<Q, R>> {
876        self.transform()
877    }
878
879    /// Transform the query into one that skips entities satisfying another
880    ///
881    /// See `QueryBorrow::without`
882    pub fn without<R: Query>(self) -> QueryMut<'q, Without<Q, R>> {
883        self.transform()
884    }
885
886    /// Helper to change the type of the query
887    fn transform<R: Query>(self) -> QueryMut<'q, R> {
888        QueryMut {
889            world: self.world,
890            _marker: PhantomData,
891        }
892    }
893
894    /// Like `into_iter`, but returns child iterators of at most `batch_size` elements
895    ///
896    /// Useful for distributing work over a threadpool.
897    pub fn into_iter_batched(self, batch_size: u32) -> BatchedIter<'q, Q> {
898        let cache = CachedQuery::get(self.world);
899        unsafe {
900            BatchedIter::new(
901                self.world.entities_meta(),
902                self.world.archetypes_inner(),
903                batch_size,
904                cache,
905            )
906        }
907    }
908}
909
910impl<'q, Q: Query> IntoIterator for QueryMut<'q, Q> {
911    type Item = <QueryIter<'q, Q> as Iterator>::Item;
912    type IntoIter = QueryIter<'q, Q>;
913
914    #[inline]
915    fn into_iter(self) -> Self::IntoIter {
916        let cache = CachedQuery::get(self.world);
917        unsafe { QueryIter::new(self.world, cache) }
918    }
919}
920
921/// Check that Q doesn't alias a `&mut T` on its own. Currently over-conservative for `Or` queries.
922pub(crate) fn assert_borrow<Q: Query>() {
923    // This looks like an ugly O(n^2) loop, but everything's constant after inlining, so in
924    // practice LLVM optimizes it out entirely.
925    let mut i = 0;
926    Q::Fetch::for_each_borrow(|a, unique| {
927        if unique {
928            let mut j = 0;
929            Q::Fetch::for_each_borrow(|b, _| {
930                if i != j {
931                    core::assert!(a != b, "query violates a unique borrow");
932                }
933                j += 1;
934            })
935        }
936        i += 1;
937    });
938}
939
940struct ChunkIter<Q: Query> {
941    fetch: Q::Fetch,
942    position: usize,
943    len: usize,
944}
945
946impl<Q: Query> ChunkIter<Q> {
947    fn new(archetype: &Archetype, fetch: Q::Fetch) -> Self {
948        Self {
949            fetch,
950            position: 0,
951            len: archetype.len() as usize,
952        }
953    }
954
955    fn empty() -> Self {
956        Self {
957            fetch: Q::Fetch::dangling(),
958            position: 0,
959            len: 0,
960        }
961    }
962
963    #[inline]
964    unsafe fn next<'a>(&mut self, meta: &[EntityMeta]) -> Option<Q::Item<'a>> {
965        if self.position == self.len {
966            return None;
967        }
968        let item = Q::get(meta, &self.fetch, self.position);
969        self.position += 1;
970        Some(item)
971    }
972
973    fn remaining(&self) -> usize {
974        self.len - self.position
975    }
976}
977
978/// Batched version of [`QueryIter`]
979pub struct BatchedIter<'q, Q: Query> {
980    _marker: PhantomData<&'q Q>,
981    meta: &'q [EntityMeta],
982    archetypes: &'q [Archetype],
983    index_iter: core::ops::Range<usize>,
984    batch_size: u32,
985    cache: CachedQuery<Q::Fetch>,
986    batch: u32,
987}
988
989impl<'q, Q: Query> BatchedIter<'q, Q> {
990    /// # Safety
991    ///
992    /// `'q` must be sufficient to guarantee that `Q` cannot violate borrow safety, either with
993    /// dynamic borrow checks or by representing exclusive access to the `World`.
994    unsafe fn new(
995        meta: &'q [EntityMeta],
996        archetypes: &'q [Archetype],
997        batch_size: u32,
998        cache: CachedQuery<Q::Fetch>,
999    ) -> Self {
1000        Self {
1001            _marker: PhantomData,
1002            meta,
1003            archetypes,
1004            index_iter: (0..cache.archetype_count(archetypes)),
1005            batch_size,
1006            cache,
1007            batch: 0,
1008        }
1009    }
1010}
1011
1012unsafe impl<Q: Query> Send for BatchedIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
1013unsafe impl<Q: Query> Sync for BatchedIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
1014
1015impl<'q, Q: Query> Iterator for BatchedIter<'q, Q> {
1016    type Item = Batch<'q, Q>;
1017
1018    fn next(&mut self) -> Option<Self::Item> {
1019        loop {
1020            let mut indices = self.index_iter.clone();
1021            let index = indices.next()?;
1022            let Some((archetype, state)) =
1023                (unsafe { self.cache.get_state(self.archetypes, index) })
1024            else {
1025                // Skip this archetype entirely
1026                self.index_iter = indices;
1027                continue;
1028            };
1029            let offset = self.batch_size * self.batch;
1030            if offset >= archetype.len() {
1031                // We've yielded the contents of this archetype already
1032                self.index_iter = indices;
1033                self.batch = 0;
1034                continue;
1035            }
1036            let fetch = Q::Fetch::execute(archetype, state);
1037            self.batch += 1;
1038            let mut state = ChunkIter::new(archetype, fetch);
1039            state.position = offset as usize;
1040            state.len = (offset + self.batch_size.min(archetype.len() - offset)) as usize;
1041            return Some(Batch {
1042                meta: self.meta,
1043                state,
1044            });
1045        }
1046    }
1047}
1048
1049/// A sequence of entities yielded by [`BatchedIter`]
1050pub struct Batch<'q, Q: Query> {
1051    meta: &'q [EntityMeta],
1052    state: ChunkIter<Q>,
1053}
1054
1055impl<'q, Q: Query> Iterator for Batch<'q, Q> {
1056    type Item = Q::Item<'q>;
1057
1058    fn next(&mut self) -> Option<Self::Item> {
1059        unsafe { self.state.next(self.meta) }
1060    }
1061}
1062
1063unsafe impl<Q: Query> Send for Batch<'_, Q> where for<'a> Q::Item<'a>: Send {}
1064unsafe impl<Q: Query> Sync for Batch<'_, Q> where for<'a> Q::Item<'a>: Send {}
1065
1066macro_rules! tuple_impl {
1067    ($($name: ident),*) => {
1068        unsafe impl<$($name: Fetch),*> Fetch for ($($name,)*) {
1069            type State = ($($name::State,)*);
1070
1071            #[allow(clippy::unused_unit)]
1072            fn dangling() -> Self {
1073                ($($name::dangling(),)*)
1074            }
1075
1076            #[allow(unused_variables, unused_mut)]
1077            fn access(archetype: &Archetype) -> Option<Access> {
1078                let mut access = Access::Iterate;
1079                $(
1080                    access = access.max($name::access(archetype)?);
1081                )*
1082                Some(access)
1083            }
1084
1085            #[allow(unused_variables, non_snake_case, clippy::unused_unit)]
1086            fn borrow(archetype: &Archetype, state: Self::State) {
1087                let ($($name,)*) = state;
1088                $($name::borrow(archetype, $name);)*
1089            }
1090            #[allow(unused_variables)]
1091            #[cold]
1092            fn prepare(archetype: &Archetype) -> Option<Self::State> {
1093                Some(($($name::prepare(archetype)?,)*))
1094            }
1095            #[allow(unused_variables, non_snake_case, clippy::unused_unit)]
1096            #[inline(always)]
1097            fn execute(archetype: &Archetype, state: Self::State) -> Self {
1098                let ($($name,)*) = state;
1099                ($($name::execute(archetype, $name),)*)
1100            }
1101            #[allow(unused_variables, non_snake_case, clippy::unused_unit)]
1102            fn release(archetype: &Archetype, state: Self::State) {
1103                let ($($name,)*) = state;
1104                $($name::release(archetype, $name);)*
1105            }
1106
1107            #[allow(unused_variables, unused_mut, clippy::unused_unit)]
1108            fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
1109                $($name::for_each_borrow(&mut f);)*
1110            }
1111        }
1112
1113        impl<$($name: Query),*> Query for ($($name,)*) {
1114            type Item<'q> = ($($name::Item<'q>,)*);
1115
1116            type Fetch = ($($name::Fetch,)*);
1117
1118            #[allow(unused_variables, clippy::unused_unit)]
1119            unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
1120                #[allow(non_snake_case)]
1121                let ($(ref $name,)*) = *fetch;
1122                ($($name::get(meta, $name, n),)*)
1123            }
1124        }
1125
1126        unsafe impl<$($name: QueryShared),*> QueryShared for ($($name,)*) {}
1127    };
1128}
1129
1130//smaller_tuples_too!(tuple_impl, B, A);
1131smaller_tuples_too!(tuple_impl, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A);
1132
1133/// A prepared query can be stored independently of the [`World`] to fractionally reduce query
1134/// set-up costs.
1135///
1136/// Prepared queries are less convenient and usually do not measurably impact performance. Regular
1137/// queries should be preferred unless end-to-end performance measurements clearly indicate
1138/// otherwise.
1139pub struct PreparedQuery<Q: Query> {
1140    memo: (u64, u32),
1141    state: Box<[(usize, <Q::Fetch as Fetch>::State)]>,
1142    fetch: Box<[Option<Q::Fetch>]>,
1143}
1144
1145impl<Q: Query> Default for PreparedQuery<Q> {
1146    fn default() -> Self {
1147        Self::new()
1148    }
1149}
1150
1151impl<Q: Query> PreparedQuery<Q> {
1152    /// Create a prepared query which is not yet attached to any world
1153    pub fn new() -> Self {
1154        Self {
1155            // This memo will not match any world as the first ID will be 1.
1156            memo: (0, 0),
1157            state: Default::default(),
1158            fetch: Default::default(),
1159        }
1160    }
1161
1162    #[cold]
1163    fn prepare(world: &World) -> Self {
1164        let memo = world.memo();
1165
1166        let state = world
1167            .archetypes()
1168            .enumerate()
1169            .filter_map(|(idx, x)| Q::Fetch::prepare(x).map(|state| (idx, state)))
1170            .collect();
1171
1172        let fetch = world.archetypes().map(|_| None).collect();
1173
1174        Self { memo, state, fetch }
1175    }
1176
1177    /// Query `world`, using dynamic borrow checking
1178    ///
1179    /// This will panic if it would violate an existing unique reference
1180    /// or construct an invalid unique reference.
1181    pub fn query<'q>(&'q mut self, world: &'q World) -> PreparedQueryBorrow<'q, Q> {
1182        if self.memo != world.memo() {
1183            *self = Self::prepare(world);
1184        }
1185
1186        let meta = world.entities_meta();
1187        let archetypes = world.archetypes_inner();
1188
1189        PreparedQueryBorrow::new(meta, archetypes, &self.state, &mut self.fetch)
1190    }
1191
1192    /// Query a uniquely borrowed world
1193    ///
1194    /// Avoids the cost of the dynamic borrow checking performed by [`query`][Self::query].
1195    pub fn query_mut<'q>(&'q mut self, world: &'q mut World) -> PreparedQueryIter<'q, Q> {
1196        assert_borrow::<Q>();
1197
1198        if self.memo != world.memo() {
1199            *self = Self::prepare(world);
1200        }
1201
1202        let meta = world.entities_meta();
1203        let archetypes = world.archetypes_inner();
1204
1205        unsafe { PreparedQueryIter::new(meta, archetypes, self.state.iter()) }
1206    }
1207
1208    /// Provide random access to query results for a uniquely borrow world
1209    pub fn view_mut<'q>(&'q mut self, world: &'q mut World) -> PreparedView<'q, Q> {
1210        assert_borrow::<Q>();
1211
1212        if self.memo != world.memo() {
1213            *self = Self::prepare(world);
1214        }
1215
1216        let meta = world.entities_meta();
1217        let archetypes = world.archetypes_inner();
1218
1219        unsafe { PreparedView::new(meta, archetypes, self.state.iter(), &mut self.fetch) }
1220    }
1221}
1222
1223/// Combined borrow of a [`PreparedQuery`] and a [`World`]
1224pub struct PreparedQueryBorrow<'q, Q: Query> {
1225    meta: &'q [EntityMeta],
1226    archetypes: &'q [Archetype],
1227    state: &'q [(usize, <Q::Fetch as Fetch>::State)],
1228    fetch: &'q mut [Option<Q::Fetch>],
1229}
1230
1231impl<'q, Q: Query> PreparedQueryBorrow<'q, Q> {
1232    fn new(
1233        meta: &'q [EntityMeta],
1234        archetypes: &'q [Archetype],
1235        state: &'q [(usize, <Q::Fetch as Fetch>::State)],
1236        fetch: &'q mut [Option<Q::Fetch>],
1237    ) -> Self {
1238        for (idx, state) in state {
1239            if archetypes[*idx].is_empty() {
1240                continue;
1241            }
1242            Q::Fetch::borrow(&archetypes[*idx], *state);
1243        }
1244
1245        Self {
1246            meta,
1247            archetypes,
1248            state,
1249            fetch,
1250        }
1251    }
1252
1253    /// Execute the prepared query
1254    // The lifetime narrowing here is required for soundness.
1255    pub fn iter(&mut self) -> PreparedQueryIter<'_, Q> {
1256        unsafe { PreparedQueryIter::new(self.meta, self.archetypes, self.state.iter()) }
1257    }
1258
1259    /// Provides random access to the results of the prepared query
1260    pub fn view(&mut self) -> PreparedView<'_, Q> {
1261        unsafe { PreparedView::new(self.meta, self.archetypes, self.state.iter(), self.fetch) }
1262    }
1263}
1264
1265impl<Q: Query> Drop for PreparedQueryBorrow<'_, Q> {
1266    fn drop(&mut self) {
1267        for (idx, state) in self.state {
1268            if self.archetypes[*idx].is_empty() {
1269                continue;
1270            }
1271            Q::Fetch::release(&self.archetypes[*idx], *state);
1272        }
1273    }
1274}
1275
1276/// Iterates over all entities matching a [`PreparedQuery`]
1277pub struct PreparedQueryIter<'q, Q: Query> {
1278    meta: &'q [EntityMeta],
1279    archetypes: &'q [Archetype],
1280    state: SliceIter<'q, (usize, <Q::Fetch as Fetch>::State)>,
1281    iter: ChunkIter<Q>,
1282}
1283
1284impl<'q, Q: Query> PreparedQueryIter<'q, Q> {
1285    /// # Safety
1286    ///
1287    /// `'q` must be sufficient to guarantee that `Q` cannot violate borrow safety, either with
1288    /// dynamic borrow checks or by representing exclusive access to the `World`.
1289    unsafe fn new(
1290        meta: &'q [EntityMeta],
1291        archetypes: &'q [Archetype],
1292        state: SliceIter<'q, (usize, <Q::Fetch as Fetch>::State)>,
1293    ) -> Self {
1294        Self {
1295            meta,
1296            archetypes,
1297            state,
1298            iter: ChunkIter::empty(),
1299        }
1300    }
1301}
1302
1303unsafe impl<Q: Query> Send for PreparedQueryIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
1304unsafe impl<Q: Query> Sync for PreparedQueryIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
1305
1306impl<'q, Q: Query> Iterator for PreparedQueryIter<'q, Q> {
1307    type Item = Q::Item<'q>;
1308
1309    #[inline(always)]
1310    fn next(&mut self) -> Option<Self::Item> {
1311        loop {
1312            match unsafe { self.iter.next(self.meta) } {
1313                None => {
1314                    let (idx, state) = self.state.next()?;
1315                    let archetype = &self.archetypes[*idx];
1316                    self.iter = ChunkIter::new(archetype, Q::Fetch::execute(archetype, *state));
1317                    continue;
1318                }
1319                Some(components) => {
1320                    return Some(components);
1321                }
1322            }
1323        }
1324    }
1325
1326    fn size_hint(&self) -> (usize, Option<usize>) {
1327        let n = self.len();
1328        (n, Some(n))
1329    }
1330}
1331
1332impl<Q: Query> ExactSizeIterator for PreparedQueryIter<'_, Q> {
1333    fn len(&self) -> usize {
1334        self.state
1335            .clone()
1336            .map(|(idx, _)| self.archetypes[*idx].len() as usize)
1337            .sum::<usize>()
1338            + self.iter.remaining()
1339    }
1340}
1341
1342/// Provides random access to the results of a query
1343///
1344/// Views borrow all components that they expose, from when the view is created until it's
1345/// dropped. As with any borrowing pattern, they should usually be short-lived to avoid conflicts
1346/// with distant code that might want to borrow the same components.
1347pub struct View<'q, Q: Query> {
1348    meta: &'q [EntityMeta],
1349    archetypes: &'q [Archetype],
1350    fetch: Box<[Option<Q::Fetch>]>,
1351}
1352
1353unsafe impl<Q: Query> Send for View<'_, Q> where for<'a> Q::Item<'a>: Send {}
1354unsafe impl<Q: Query> Sync for View<'_, Q> where for<'a> Q::Item<'a>: Send {}
1355
1356impl<'q, Q: Query> View<'q, Q> {
1357    /// # Safety
1358    ///
1359    /// `'q` must be sufficient to guarantee that `Q` cannot violate borrow safety, either with
1360    /// dynamic borrow checks or by representing exclusive access to the `World`.
1361    pub(crate) unsafe fn new(
1362        meta: &'q [EntityMeta],
1363        archetypes: &'q [Archetype],
1364        cache: CachedQuery<Q::Fetch>,
1365    ) -> Self {
1366        Self {
1367            meta,
1368            archetypes,
1369            fetch: cache.fetch_all(archetypes),
1370        }
1371    }
1372
1373    /// Retrieve the query results corresponding to `entity`
1374    ///
1375    /// Will yield `None` if the entity does not exist or does not match the query.
1376    ///
1377    /// Does not require exclusive access to the map, but is defined only for queries yielding only shared references.
1378    pub fn get(&self, entity: Entity) -> Option<Q::Item<'_>>
1379    where
1380        Q: QueryShared,
1381    {
1382        let meta = self.meta.get(entity.id as usize)?;
1383        if meta.generation != entity.generation {
1384            return None;
1385        }
1386
1387        self.fetch[meta.location.archetype as usize]
1388            .as_ref()
1389            .map(|fetch| unsafe { Q::get(self.meta, fetch, meta.location.index as usize) })
1390    }
1391
1392    /// Retrieve the query results corresponding to `entity`
1393    ///
1394    /// Will yield `None` if the entity does not exist or does not match the query.
1395    pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1396        unsafe { self.get_unchecked(entity) }
1397    }
1398
1399    /// Equivalent to `get(entity).is_some()`, but does not require `Q: QueryShared`
1400    pub fn contains(&self, entity: Entity) -> bool {
1401        let Some(meta) = self.meta.get(entity.id as usize) else {
1402            return false;
1403        };
1404        if meta.generation != entity.generation {
1405            return false;
1406        }
1407        self.fetch[meta.location.archetype as usize].is_some()
1408    }
1409
1410    /// Like `get_mut`, but allows simultaneous access to multiple entities
1411    ///
1412    /// # Safety
1413    ///
1414    /// Must not be invoked while any unique borrow of the fetched components of `entity` is live.
1415    pub unsafe fn get_unchecked(&self, entity: Entity) -> Option<Q::Item<'_>> {
1416        let meta = self.meta.get(entity.id as usize)?;
1417        if meta.generation != entity.generation {
1418            return None;
1419        }
1420
1421        self.fetch[meta.location.archetype as usize]
1422            .as_ref()
1423            .map(|fetch| Q::get(self.meta, fetch, meta.location.index as usize))
1424    }
1425
1426    /// Like `get_mut`, but allows checked simultaneous access to multiple entities
1427    ///
1428    /// For N > 3, the check for distinct entities will clone the array and take O(N log N) time.
1429    ///
1430    /// # Examples
1431    ///
1432    /// ```
1433    /// # use hecs::World;
1434    /// let mut world = World::new();
1435    ///
1436    /// let a = world.spawn((1, 1.0));
1437    /// let b = world.spawn((2, 4.0));
1438    /// let c = world.spawn((3, 9.0));
1439    ///
1440    /// let mut query = world.query_mut::<&mut i32>();
1441    /// let mut view = query.view();
1442    /// let [a,b,c] = view.get_disjoint_mut([a, b, c]);
1443    ///
1444    /// assert_eq!(*a.unwrap(), 1);
1445    /// assert_eq!(*b.unwrap(), 2);
1446    /// assert_eq!(*c.unwrap(), 3);
1447    /// ```
1448    pub fn get_disjoint_mut<const N: usize>(
1449        &mut self,
1450        entities: [Entity; N],
1451    ) -> [Option<Q::Item<'_>>; N] {
1452        assert_distinct(&entities);
1453
1454        let mut items = [(); N].map(|()| None);
1455
1456        for (item, entity) in items.iter_mut().zip(entities) {
1457            unsafe {
1458                *item = self.get_unchecked(entity);
1459            }
1460        }
1461
1462        items
1463    }
1464
1465    #[doc(hidden)]
1466    #[deprecated(since = "0.11.0", note = "renamed to `get_disjoint_mut`")]
1467    pub fn get_many_mut<const N: usize>(
1468        &mut self,
1469        entities: [Entity; N],
1470    ) -> [Option<Q::Item<'_>>; N] {
1471        self.get_disjoint_mut(entities)
1472    }
1473
1474    /// Iterate over all entities satisfying `Q`
1475    ///
1476    /// Equivalent to [`QueryBorrow::iter`].
1477    pub fn iter_mut(&mut self) -> ViewIter<'_, Q> {
1478        ViewIter {
1479            meta: self.meta,
1480            archetypes: self.archetypes.iter(),
1481            fetches: self.fetch.iter(),
1482            iter: ChunkIter::empty(),
1483        }
1484    }
1485}
1486
1487impl<'a, Q: Query> IntoIterator for &'a mut View<'_, Q> {
1488    type IntoIter = ViewIter<'a, Q>;
1489    type Item = Q::Item<'a>;
1490
1491    #[inline]
1492    fn into_iter(self) -> Self::IntoIter {
1493        self.iter_mut()
1494    }
1495}
1496
1497pub struct ViewIter<'a, Q: Query> {
1498    meta: &'a [EntityMeta],
1499    archetypes: SliceIter<'a, Archetype>,
1500    fetches: SliceIter<'a, Option<Q::Fetch>>,
1501    iter: ChunkIter<Q>,
1502}
1503
1504impl<'a, Q: Query> Iterator for ViewIter<'a, Q> {
1505    type Item = Q::Item<'a>;
1506
1507    #[inline(always)]
1508    fn next(&mut self) -> Option<Self::Item> {
1509        loop {
1510            match unsafe { self.iter.next(self.meta) } {
1511                None => {
1512                    let archetype = self.archetypes.next()?;
1513                    let fetch = self.fetches.next()?;
1514                    self.iter = fetch
1515                        .clone()
1516                        .map_or(ChunkIter::empty(), |fetch| ChunkIter::new(archetype, fetch));
1517                    continue;
1518                }
1519                Some(components) => {
1520                    return Some(components);
1521                }
1522            }
1523        }
1524    }
1525}
1526
1527/// Provides random access to the results of a prepared query
1528pub struct PreparedView<'q, Q: Query> {
1529    meta: &'q [EntityMeta],
1530    archetypes: &'q [Archetype],
1531    fetch: &'q mut [Option<Q::Fetch>],
1532}
1533
1534unsafe impl<Q: Query> Send for PreparedView<'_, Q> where for<'a> Q::Item<'a>: Send {}
1535unsafe impl<Q: Query> Sync for PreparedView<'_, Q> where for<'a> Q::Item<'a>: Send {}
1536
1537impl<'q, Q: Query> PreparedView<'q, Q> {
1538    /// # Safety
1539    ///
1540    /// `'q` must be sufficient to guarantee that `Q` cannot violate borrow safety, either with
1541    /// dynamic borrow checks or by representing exclusive access to the `World`.
1542    unsafe fn new(
1543        meta: &'q [EntityMeta],
1544        archetypes: &'q [Archetype],
1545        state: SliceIter<'q, (usize, <Q::Fetch as Fetch>::State)>,
1546        fetch: &'q mut [Option<Q::Fetch>],
1547    ) -> Self {
1548        fetch.iter_mut().for_each(|fetch| *fetch = None);
1549
1550        for (idx, state) in state {
1551            let archetype = &archetypes[*idx];
1552            fetch[*idx] = Some(Q::Fetch::execute(archetype, *state));
1553        }
1554
1555        Self {
1556            meta,
1557            archetypes,
1558            fetch,
1559        }
1560    }
1561
1562    /// Retrieve the query results corresponding to `entity`
1563    ///
1564    /// Will yield `None` if the entity does not exist or does not match the query.
1565    ///
1566    /// Does not require exclusive access to the map, but is defined only for queries yielding only shared references.
1567    pub fn get(&self, entity: Entity) -> Option<Q::Item<'_>>
1568    where
1569        Q: QueryShared,
1570    {
1571        let meta = self.meta.get(entity.id as usize)?;
1572        if meta.generation != entity.generation {
1573            return None;
1574        }
1575
1576        self.fetch[meta.location.archetype as usize]
1577            .as_ref()
1578            .map(|fetch| unsafe { Q::get(self.meta, fetch, meta.location.index as usize) })
1579    }
1580
1581    /// Retrieve the query results corresponding to `entity`
1582    ///
1583    /// Will yield `None` if the entity does not exist or does not match the query.
1584    pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1585        unsafe { self.get_unchecked(entity) }
1586    }
1587
1588    /// Equivalent to `get(entity).is_some()`, but does not require `Q: QueryShared`
1589    pub fn contains(&self, entity: Entity) -> bool {
1590        let Some(meta) = self.meta.get(entity.id as usize) else {
1591            return false;
1592        };
1593        if meta.generation != entity.generation {
1594            return false;
1595        }
1596        self.fetch[meta.location.archetype as usize].is_some()
1597    }
1598
1599    /// Like `get_mut`, but allows simultaneous access to multiple entities
1600    ///
1601    /// # Safety
1602    ///
1603    /// Must not be invoked while any unique borrow of the fetched components of `entity` is live.
1604    pub unsafe fn get_unchecked(&self, entity: Entity) -> Option<Q::Item<'_>> {
1605        let meta = self.meta.get(entity.id as usize)?;
1606        if meta.generation != entity.generation {
1607            return None;
1608        }
1609
1610        self.fetch[meta.location.archetype as usize]
1611            .as_ref()
1612            .map(|fetch| Q::get(self.meta, fetch, meta.location.index as usize))
1613    }
1614
1615    /// Like `get_mut`, but allows checked simultaneous access to multiple entities
1616    ///
1617    /// See [`View::get_disjoint_mut`] for details.
1618    pub fn get_disjoint_mut<const N: usize>(
1619        &mut self,
1620        entities: [Entity; N],
1621    ) -> [Option<Q::Item<'_>>; N] {
1622        assert_distinct(&entities);
1623
1624        let mut items = [(); N].map(|()| None);
1625
1626        for (item, entity) in items.iter_mut().zip(entities) {
1627            unsafe {
1628                *item = self.get_unchecked(entity);
1629            }
1630        }
1631
1632        items
1633    }
1634
1635    #[doc(hidden)]
1636    #[deprecated(since = "0.11.0", note = "renamed to `get_disjoint_mut`")]
1637    pub fn get_many_mut<const N: usize>(
1638        &mut self,
1639        entities: [Entity; N],
1640    ) -> [Option<Q::Item<'_>>; N] {
1641        self.get_disjoint_mut(entities)
1642    }
1643
1644    /// Iterate over all entities satisfying `Q`
1645    ///
1646    /// Equivalent to [`PreparedQueryBorrow::iter`].
1647    pub fn iter_mut(&mut self) -> ViewIter<'_, Q> {
1648        ViewIter {
1649            meta: self.meta,
1650            archetypes: self.archetypes.iter(),
1651            fetches: self.fetch.iter(),
1652            iter: ChunkIter::empty(),
1653        }
1654    }
1655}
1656
1657impl<'a, Q: Query> IntoIterator for &'a mut PreparedView<'_, Q> {
1658    type IntoIter = ViewIter<'a, Q>;
1659    type Item = Q::Item<'a>;
1660
1661    #[inline]
1662    fn into_iter(self) -> Self::IntoIter {
1663        self.iter_mut()
1664    }
1665}
1666
1667/// A borrow of a [`World`](crate::World) sufficient to random-access the results of the query `Q`.
1668///
1669/// Note that borrows are not released until this object is dropped.
1670///
1671/// This struct is a thin wrapper around [`View`]. See it for more documentation.
1672pub struct ViewBorrow<'w, Q: Query> {
1673    view: View<'w, Q>,
1674    cache: CachedQuery<Q::Fetch>,
1675}
1676
1677impl<'w, Q: Query> ViewBorrow<'w, Q> {
1678    pub(crate) fn new(world: &'w World) -> Self {
1679        let cache = CachedQuery::get(world);
1680        cache.borrow(world.archetypes_inner());
1681        let view = unsafe {
1682            View::<Q>::new(
1683                world.entities_meta(),
1684                world.archetypes_inner(),
1685                cache.clone(),
1686            )
1687        };
1688
1689        Self { view, cache }
1690    }
1691
1692    /// Retrieve the query results corresponding to `entity`
1693    ///
1694    /// Will yield `None` if the entity does not exist or does not match the query.
1695    ///
1696    /// Does not require exclusive access to the map, but is defined only for queries yielding only shared references.
1697    ///
1698    /// See [`View::get``].
1699    pub fn get(&self, entity: Entity) -> Option<Q::Item<'_>>
1700    where
1701        Q: QueryShared,
1702    {
1703        self.view.get(entity)
1704    }
1705
1706    /// Retrieve the query results corresponding to `entity`
1707    ///
1708    /// Will yield `None` if the entity does not exist or does not match the query.
1709    ///
1710    /// See [`View::get_mut``].
1711    pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1712        self.view.get_mut(entity)
1713    }
1714
1715    /// Equivalent to `get(entity).is_some()`, but does not require `Q: QueryShared`
1716    ///
1717    /// See [`View::contains``].
1718    pub fn contains(&self, entity: Entity) -> bool {
1719        self.view.contains(entity)
1720    }
1721
1722    /// Like `get_mut`, but allows simultaneous access to multiple entities
1723    ///
1724    /// See [`View::get_unchecked``].
1725    ///
1726    /// # Safety
1727    ///
1728    /// Must not be invoked while any unique borrow of the fetched components of `entity` is live.
1729    pub unsafe fn get_unchecked(&self, entity: Entity) -> Option<Q::Item<'_>> {
1730        self.view.get_unchecked(entity)
1731    }
1732
1733    /// Like `get_mut`, but allows checked simultaneous access to multiple entities
1734    ///
1735    /// For N > 3, the check for distinct entities will clone the array and take O(N log N) time.
1736    ///
1737    /// See [`View::get_disjoint_mut``].
1738    ///
1739    /// # Examples
1740    ///
1741    /// ```
1742    /// # use hecs::World;
1743    /// let mut world = World::new();
1744    ///
1745    /// let a = world.spawn((1, 1.0));
1746    /// let b = world.spawn((2, 4.0));
1747    /// let c = world.spawn((3, 9.0));
1748    ///
1749    /// let mut view = world.view_mut::<&mut i32>();
1750    /// let [a, b, c] = view.get_disjoint_mut([a, b, c]);
1751    ///
1752    /// assert_eq!(*a.unwrap(), 1);
1753    /// assert_eq!(*b.unwrap(), 2);
1754    /// assert_eq!(*c.unwrap(), 3);
1755    /// ```
1756    pub fn get_disjoint_mut<const N: usize>(
1757        &mut self,
1758        entities: [Entity; N],
1759    ) -> [Option<Q::Item<'_>>; N] {
1760        self.view.get_disjoint_mut(entities)
1761    }
1762
1763    #[doc(hidden)]
1764    #[deprecated(since = "0.11.0", note = "renamed to `get_disjoint_mut`")]
1765    pub fn get_many_mut<const N: usize>(
1766        &mut self,
1767        entities: [Entity; N],
1768    ) -> [Option<Q::Item<'_>>; N] {
1769        self.view.get_disjoint_mut(entities)
1770    }
1771
1772    /// Iterate over all entities satisfying `Q`
1773    ///
1774    /// See [`View::iter_mut``]
1775    pub fn iter_mut(&mut self) -> ViewIter<'_, Q> {
1776        self.view.iter_mut()
1777    }
1778}
1779
1780impl<Q: Query> Drop for ViewBorrow<'_, Q> {
1781    fn drop(&mut self) {
1782        self.cache.release_borrow(self.view.archetypes);
1783    }
1784}
1785
1786impl<'a, Q: Query> IntoIterator for &'a mut ViewBorrow<'_, Q> {
1787    type IntoIter = ViewIter<'a, Q>;
1788    type Item = Q::Item<'a>;
1789
1790    #[inline]
1791    fn into_iter(self) -> Self::IntoIter {
1792        self.iter_mut()
1793    }
1794}
1795
1796pub(crate) fn assert_distinct<const N: usize>(entities: &[Entity; N]) {
1797    match N {
1798        1 => (),
1799        2 => assert_ne!(entities[0], entities[1]),
1800        3 => {
1801            assert_ne!(entities[0], entities[1]);
1802            assert_ne!(entities[1], entities[2]);
1803            assert_ne!(entities[2], entities[0]);
1804        }
1805        _ => {
1806            let mut entities = *entities;
1807            entities.sort_unstable();
1808            for index in 0..N - 1 {
1809                assert_ne!(entities[index], entities[index + 1]);
1810            }
1811        }
1812    }
1813}
1814
1815#[cfg(feature = "std")]
1816pub(crate) type QueryCache = RwLock<TypeIdMap<Arc<dyn Any + Send + Sync>>>;
1817
1818#[cfg(feature = "std")]
1819struct CachedQueryInner<F: Fetch> {
1820    state: Box<[(usize, F::State)]>,
1821    // In theory we could drop the cache eagerly when invalidated rather than tracking this, but
1822    // this is harder to screw up.
1823    archetypes_generation: crate::ArchetypesGeneration,
1824}
1825
1826#[cfg(feature = "std")]
1827impl<F: Fetch> CachedQueryInner<F> {
1828    fn new(world: &World) -> Self {
1829        Self {
1830            state: world
1831                .archetypes()
1832                .enumerate()
1833                .filter_map(|(idx, x)| F::prepare(x).map(|state| (idx, state)))
1834                .collect(),
1835            archetypes_generation: world.archetypes_generation(),
1836        }
1837    }
1838}
1839
1840pub(crate) struct CachedQuery<F: Fetch> {
1841    #[cfg(feature = "std")]
1842    inner: Arc<CachedQueryInner<F>>,
1843    #[cfg(not(feature = "std"))]
1844    _marker: PhantomData<F>,
1845}
1846
1847impl<F: Fetch> CachedQuery<F> {
1848    pub(crate) fn get(world: &World) -> Self {
1849        #[cfg(feature = "std")]
1850        {
1851            let existing_cache = world
1852                .query_cache()
1853                .read()
1854                .unwrap()
1855                .get(&TypeId::of::<F>())
1856                .map(|x| Arc::downcast::<CachedQueryInner<F>>(x.clone()).unwrap())
1857                .filter(|x| x.archetypes_generation == world.archetypes_generation());
1858            let inner = existing_cache.unwrap_or_else(
1859                #[cold]
1860                || {
1861                    let mut cache = world.query_cache().write().unwrap();
1862                    let entry = cache.entry(TypeId::of::<F>());
1863                    let cached = match entry {
1864                        hash_map::Entry::Vacant(e) => {
1865                            let fresh = Arc::new(CachedQueryInner::<F>::new(world));
1866                            e.insert(fresh.clone());
1867                            fresh
1868                        }
1869                        hash_map::Entry::Occupied(mut e) => {
1870                            let value =
1871                                Arc::downcast::<CachedQueryInner<F>>(e.get().clone()).unwrap();
1872                            match value.archetypes_generation == world.archetypes_generation() {
1873                                false => {
1874                                    let fresh = Arc::new(CachedQueryInner::<F>::new(world));
1875                                    e.insert(fresh.clone());
1876                                    fresh
1877                                }
1878                                true => value,
1879                            }
1880                        }
1881                    };
1882                    cached
1883                },
1884            );
1885            Self { inner }
1886        }
1887        #[cfg(not(feature = "std"))]
1888        {
1889            _ = world;
1890            Self {
1891                _marker: PhantomData,
1892            }
1893        }
1894    }
1895
1896    fn archetype_count(&self, archetypes: &[Archetype]) -> usize {
1897        #[cfg(feature = "std")]
1898        {
1899            _ = archetypes;
1900            self.inner.state.len()
1901        }
1902        #[cfg(not(feature = "std"))]
1903        {
1904            archetypes.len()
1905        }
1906    }
1907
1908    /// Returns `None` if this index should be skipped.
1909    ///
1910    /// # Safety
1911    /// - `index` must be <= the value returned by `archetype_count`
1912    /// - `archetypes` must match that passed to `archetype_count` and the world passed to `get`
1913    unsafe fn get_state<'a>(
1914        &self,
1915        archetypes: &'a [Archetype],
1916        index: usize,
1917    ) -> Option<(&'a Archetype, F::State)> {
1918        #[cfg(feature = "std")]
1919        unsafe {
1920            let &(archetype, state) = self.inner.state.get_unchecked(index);
1921            let archetype = archetypes.get_unchecked(archetype);
1922            Some((archetype, state))
1923        }
1924        #[cfg(not(feature = "std"))]
1925        {
1926            let archetype = unsafe { archetypes.get_unchecked(index) };
1927            let state = F::prepare(archetype)?;
1928            Some((archetype, state))
1929        }
1930    }
1931
1932    /// Returns `None` if this index should be skipped.
1933    ///
1934    /// # Safety
1935    /// - `index` must be <= the value returned by `archetype_count`
1936    /// - `archetypes` must match that passed to `archetype_count` and the world passed to `get`
1937    unsafe fn get_archetype<'a>(
1938        &self,
1939        archetypes: &'a [Archetype],
1940        index: usize,
1941    ) -> Option<&'a Archetype> {
1942        #[cfg(feature = "std")]
1943        unsafe {
1944            let &(archetype, _) = self.inner.state.get_unchecked(index);
1945            let archetype = archetypes.get_unchecked(archetype);
1946            Some(archetype)
1947        }
1948        #[cfg(not(feature = "std"))]
1949        {
1950            let x = unsafe { archetypes.get_unchecked(index) };
1951            if F::access(x).is_none() {
1952                return None;
1953            }
1954            Some(x)
1955        }
1956    }
1957
1958    fn borrow(&self, archetypes: &[Archetype]) {
1959        #[cfg(feature = "std")]
1960        {
1961            for &(archetype, state) in &self.inner.state {
1962                let archetype = unsafe { archetypes.get_unchecked(archetype) };
1963                if archetype.is_empty() {
1964                    continue;
1965                }
1966                F::borrow(archetype, state);
1967            }
1968        }
1969
1970        #[cfg(not(feature = "std"))]
1971        {
1972            for x in archetypes {
1973                if x.is_empty() {
1974                    continue;
1975                }
1976                // TODO: Release prior borrows on failure?
1977                if let Some(state) = F::prepare(x) {
1978                    F::borrow(x, state);
1979                }
1980            }
1981        }
1982    }
1983
1984    fn release_borrow(&self, archetypes: &[Archetype]) {
1985        #[cfg(feature = "std")]
1986        {
1987            for &(archetype, state) in &self.inner.state {
1988                let archetype = unsafe { archetypes.get_unchecked(archetype) };
1989                if archetype.is_empty() {
1990                    continue;
1991                }
1992                F::release(archetype, state);
1993            }
1994        }
1995
1996        #[cfg(not(feature = "std"))]
1997        {
1998            for x in archetypes {
1999                if x.is_empty() {
2000                    continue;
2001                }
2002                if let Some(state) = F::prepare(x) {
2003                    F::release(x, state);
2004                }
2005            }
2006        }
2007    }
2008
2009    fn fetch_all(&self, archetypes: &[Archetype]) -> Box<[Option<F>]> {
2010        #[cfg(feature = "std")]
2011        {
2012            let mut fetch = (0..archetypes.len()).map(|_| None).collect::<Box<[_]>>();
2013            for &(archetype_index, state) in &self.inner.state {
2014                let archetype = &archetypes[archetype_index];
2015                fetch[archetype_index] = Some(F::execute(archetype, state));
2016            }
2017            fetch
2018        }
2019        #[cfg(not(feature = "std"))]
2020        {
2021            archetypes
2022                .iter()
2023                .map(|archetype| F::prepare(archetype).map(|state| F::execute(archetype, state)))
2024                .collect()
2025        }
2026    }
2027}
2028
2029impl<F: Fetch> Clone for CachedQuery<F> {
2030    fn clone(&self) -> Self {
2031        Self {
2032            #[cfg(feature = "std")]
2033            inner: self.inner.clone(),
2034            #[cfg(not(feature = "std"))]
2035            _marker: PhantomData,
2036        }
2037    }
2038}
2039
2040struct ArchetypeIter<Q: Query> {
2041    archetypes: core::ops::Range<usize>,
2042    cache: CachedQuery<Q::Fetch>,
2043}
2044
2045impl<Q: Query> ArchetypeIter<Q> {
2046    fn new(world: &World, cache: CachedQuery<Q::Fetch>) -> Self {
2047        Self {
2048            archetypes: 0..cache.archetype_count(world.archetypes_inner()),
2049            cache,
2050        }
2051    }
2052
2053    /// Safety: `world` must be the same as passed to `new`
2054    unsafe fn next(&mut self, world: &World) -> Option<ChunkIter<Q>> {
2055        loop {
2056            let Some((archetype, state)) = self
2057                .cache
2058                .get_state(world.archetypes_inner(), self.archetypes.next()?)
2059            else {
2060                continue;
2061            };
2062            let fetch = Q::Fetch::execute(archetype, state);
2063            return Some(ChunkIter::new(archetype, fetch));
2064        }
2065    }
2066
2067    fn entity_len(&self, world: &World) -> usize {
2068        self.archetypes
2069            .clone()
2070            .filter_map(|x| unsafe { self.cache.get_archetype(world.archetypes_inner(), x) })
2071            .map(|x| x.len() as usize)
2072            .sum()
2073    }
2074}
2075
2076#[cfg(test)]
2077mod tests {
2078    use super::*;
2079
2080    #[test]
2081    fn access_order() {
2082        assert!(Access::Write > Access::Read);
2083        assert!(Access::Read > Access::Iterate);
2084        assert!(Some(Access::Iterate) > None);
2085    }
2086}