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
20pub trait Query {
24 type Item<'a>;
28
29 #[doc(hidden)]
30 type Fetch: Fetch;
31
32 #[doc(hidden)]
33 unsafe fn get<'a>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'a>;
41}
42
43#[allow(clippy::missing_safety_doc)]
45pub unsafe trait QueryShared {}
46
47#[allow(clippy::missing_safety_doc)]
49pub unsafe trait Fetch: Clone + Sized + 'static {
50 type State: Copy + Send + Sync;
53
54 fn dangling() -> Self;
56
57 fn access(archetype: &Archetype) -> Option<Access>;
59
60 fn borrow(archetype: &Archetype, state: Self::State);
62 fn prepare(archetype: &Archetype) -> Option<Self::State>;
64 fn execute(archetype: &Archetype, state: Self::State) -> Self;
66 fn release(archetype: &Archetype, state: Self::State);
68
69 fn for_each_borrow(f: impl FnMut(TypeId, bool));
71}
72
73#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
75pub enum Access {
76 Iterate,
78 Read,
80 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#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
292pub enum Or<L, R> {
293 Left(L),
295 Right(R),
297 Both(L, R),
299}
300
301impl<L, R> Or<L, R> {
302 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 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 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 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 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 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 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 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
434pub 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
511pub 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
588pub 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
654pub 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 pub fn iter(&mut self) -> QueryIter<'_, Q> {
670 let cache = self.borrow().clone();
671 unsafe { QueryIter::new(self.world, cache) }
672 }
673
674 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 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 pub fn with<R: Query>(self) -> QueryBorrow<'w, With<Q, R>> {
733 self.transform()
734 }
735
736 pub fn without<R: Query>(self) -> QueryBorrow<'w, Without<Q, R>> {
755 self.transform()
756 }
757
758 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
787pub 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 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 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
845pub 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 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 pub fn with<R: Query>(self) -> QueryMut<'q, With<Q, R>> {
876 self.transform()
877 }
878
879 pub fn without<R: Query>(self) -> QueryMut<'q, Without<Q, R>> {
883 self.transform()
884 }
885
886 fn transform<R: Query>(self) -> QueryMut<'q, R> {
888 QueryMut {
889 world: self.world,
890 _marker: PhantomData,
891 }
892 }
893
894 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
921pub(crate) fn assert_borrow<Q: Query>() {
923 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
978pub 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 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 self.index_iter = indices;
1027 continue;
1028 };
1029 let offset = self.batch_size * self.batch;
1030 if offset >= archetype.len() {
1031 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
1049pub 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
1130smaller_tuples_too!(tuple_impl, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A);
1132
1133pub 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 pub fn new() -> Self {
1154 Self {
1155 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 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 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 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
1223pub 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 pub fn iter(&mut self) -> PreparedQueryIter<'_, Q> {
1256 unsafe { PreparedQueryIter::new(self.meta, self.archetypes, self.state.iter()) }
1257 }
1258
1259 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
1276pub 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 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
1342pub 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 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 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 pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1396 unsafe { self.get_unchecked(entity) }
1397 }
1398
1399 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 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 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 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
1527pub 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 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 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 pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1585 unsafe { self.get_unchecked(entity) }
1586 }
1587
1588 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 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 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 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
1667pub 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 pub fn get(&self, entity: Entity) -> Option<Q::Item<'_>>
1700 where
1701 Q: QueryShared,
1702 {
1703 self.view.get(entity)
1704 }
1705
1706 pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1712 self.view.get_mut(entity)
1713 }
1714
1715 pub fn contains(&self, entity: Entity) -> bool {
1719 self.view.contains(entity)
1720 }
1721
1722 pub unsafe fn get_unchecked(&self, entity: Entity) -> Option<Q::Item<'_>> {
1730 self.view.get_unchecked(entity)
1731 }
1732
1733 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 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 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 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 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 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 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}