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
14#[cfg(feature = "std")]
15use crate::TypeIdMap;
16use crate::archetype::Archetype;
17use crate::entities::EntityMeta;
18use crate::{Component, Entity, Substrate};
19
20pub trait Query {
26 type Item<'a>;
30
31 #[doc(hidden)]
32 type Fetch: Fetch;
33
34 #[doc(hidden)]
35 unsafe fn get<'a>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'a>;
43}
44
45#[allow(clippy::missing_safety_doc)]
47pub unsafe trait QueryShared {}
48
49#[allow(clippy::missing_safety_doc)]
51pub unsafe trait Fetch: Clone + Sized + 'static {
52 type State: Copy + Send + Sync;
55
56 fn dangling() -> Self;
58
59 fn access(archetype: &Archetype) -> Option<Access>;
61
62 fn borrow(archetype: &Archetype, state: Self::State);
64 fn prepare(archetype: &Archetype) -> Option<Self::State>;
66 fn execute(archetype: &Archetype, state: Self::State) -> Self;
68 fn release(archetype: &Archetype, state: Self::State);
70
71 fn for_each_borrow(f: impl FnMut(TypeId, bool));
73}
74
75#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
77pub enum Access {
78 Iterate,
80 Read,
82 Write,
84}
85
86impl Query for Entity {
87 type Item<'q> = Entity;
88 type Fetch = FetchEntity;
89
90 unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
91 let id = fetch.0.as_ptr().add(n).read();
92 Entity {
93 id,
94 generation: meta.get_unchecked(id as usize).generation,
95 }
96 }
97}
98unsafe impl QueryShared for Entity {}
99
100#[doc(hidden)]
101#[derive(Clone)]
102pub struct FetchEntity(NonNull<u32>);
103
104unsafe impl Fetch for FetchEntity {
105 type State = ();
106
107 fn dangling() -> Self {
108 Self(NonNull::dangling())
109 }
110
111 fn access(_: &Archetype) -> Option<Access> {
112 Some(Access::Iterate)
113 }
114
115 fn borrow(_: &Archetype, (): Self::State) {}
116
117 fn prepare(_: &Archetype) -> Option<Self::State> {
118 Some(())
119 }
120
121 fn execute(archetype: &Archetype, (): Self::State) -> Self {
122 Self(archetype.entities())
123 }
124
125 fn release(_: &Archetype, (): Self::State) {}
126
127 fn for_each_borrow(_: impl FnMut(TypeId, bool)) {}
128}
129
130impl<T: Component> Query for &'_ T {
131 type Item<'q> = &'q T;
132
133 type Fetch = FetchRead<T>;
134
135 unsafe fn get<'q>(_: &[EntityMeta], fetch: &FetchRead<T>, n: usize) -> &'q T {
136 &*fetch.0.as_ptr().add(n)
137 }
138}
139
140unsafe impl<T> QueryShared for &'_ T {}
141
142#[doc(hidden)]
143pub struct FetchRead<T>(NonNull<T>);
144
145unsafe impl<T: Component> Fetch for FetchRead<T> {
146 type State = usize;
147
148 fn dangling() -> Self {
149 Self(NonNull::dangling())
150 }
151
152 fn access(archetype: &Archetype) -> Option<Access> {
153 if archetype.has::<T>() {
154 Some(Access::Read)
155 } else {
156 None
157 }
158 }
159
160 fn borrow(archetype: &Archetype, state: Self::State) {
161 archetype.borrow::<T>(state);
162 }
163 fn prepare(archetype: &Archetype) -> Option<Self::State> {
164 archetype.get_state::<T>()
165 }
166 fn execute(archetype: &Archetype, state: Self::State) -> Self {
167 unsafe { Self(archetype.get_base(state)) }
168 }
169 fn release(archetype: &Archetype, state: Self::State) {
170 archetype.release::<T>(state);
171 }
172
173 fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
174 f(TypeId::of::<T>(), false);
175 }
176}
177
178impl<T> Clone for FetchRead<T> {
179 #[inline]
180 fn clone(&self) -> Self {
181 Self(self.0)
182 }
183}
184
185impl<T: Component> Query for &'_ mut T {
186 type Item<'q> = &'q mut T;
187
188 type Fetch = FetchWrite<T>;
189
190 unsafe fn get<'q>(_: &[EntityMeta], fetch: &FetchWrite<T>, n: usize) -> &'q mut T {
191 &mut *fetch.0.as_ptr().add(n)
192 }
193}
194
195#[doc(hidden)]
196pub struct FetchWrite<T>(NonNull<T>);
197
198unsafe impl<T: Component> Fetch for FetchWrite<T> {
199 type State = usize;
200
201 fn dangling() -> Self {
202 Self(NonNull::dangling())
203 }
204
205 fn access(archetype: &Archetype) -> Option<Access> {
206 if archetype.has::<T>() {
207 Some(Access::Write)
208 } else {
209 None
210 }
211 }
212
213 fn borrow(archetype: &Archetype, state: Self::State) {
214 archetype.borrow_mut::<T>(state);
215 }
216 #[allow(clippy::needless_question_mark)]
217 fn prepare(archetype: &Archetype) -> Option<Self::State> {
218 Some(archetype.get_state::<T>()?)
219 }
220 fn execute(archetype: &Archetype, state: Self::State) -> Self {
221 unsafe { Self(archetype.get_base::<T>(state)) }
222 }
223 fn release(archetype: &Archetype, state: Self::State) {
224 archetype.release_mut::<T>(state);
225 }
226
227 fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
228 f(TypeId::of::<T>(), true);
229 }
230}
231
232impl<T> Clone for FetchWrite<T> {
233 #[inline]
234 fn clone(&self) -> Self {
235 Self(self.0)
236 }
237}
238
239impl<T: Query> Query for Option<T> {
240 type Item<'q> = Option<T::Item<'q>>;
241
242 type Fetch = TryFetch<T::Fetch>;
243
244 unsafe fn get<'q>(
245 meta: &[EntityMeta],
246 fetch: &TryFetch<T::Fetch>,
247 n: usize,
248 ) -> Option<T::Item<'q>> {
249 Some(T::get(meta, fetch.0.as_ref()?, n))
250 }
251}
252
253unsafe impl<T: QueryShared> QueryShared for Option<T> {}
254
255#[doc(hidden)]
256#[derive(Clone)]
257pub struct TryFetch<T>(Option<T>);
258
259unsafe impl<T: Fetch> Fetch for TryFetch<T> {
260 type State = Option<T::State>;
261
262 fn dangling() -> Self {
263 Self(None)
264 }
265
266 fn access(archetype: &Archetype) -> Option<Access> {
267 Some(T::access(archetype).unwrap_or(Access::Iterate))
268 }
269
270 fn borrow(archetype: &Archetype, state: Self::State) {
271 if let Some(state) = state {
272 T::borrow(archetype, state);
273 }
274 }
275 fn prepare(archetype: &Archetype) -> Option<Self::State> {
276 Some(T::prepare(archetype))
277 }
278 fn execute(archetype: &Archetype, state: Self::State) -> Self {
279 Self(state.map(|state| T::execute(archetype, state)))
280 }
281 fn release(archetype: &Archetype, state: Self::State) {
282 if let Some(state) = state {
283 T::release(archetype, state);
284 }
285 }
286
287 fn for_each_borrow(f: impl FnMut(TypeId, bool)) {
288 T::for_each_borrow(f);
289 }
290}
291
292#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
294pub enum Or<L, R> {
295 Left(L),
297 Right(R),
299 Both(L, R),
301}
302
303impl<L, R> Or<L, R> {
304 pub fn new(l: Option<L>, r: Option<R>) -> Option<Self> {
306 match (l, r) {
307 (None, None) => None,
308 (Some(l), None) => Some(Or::Left(l)),
309 (None, Some(r)) => Some(Or::Right(r)),
310 (Some(l), Some(r)) => Some(Or::Both(l, r)),
311 }
312 }
313
314 pub fn split(self) -> (Option<L>, Option<R>) {
316 match self {
317 Or::Left(l) => (Some(l), None),
318 Or::Right(r) => (None, Some(r)),
319 Or::Both(l, r) => (Some(l), Some(r)),
320 }
321 }
322
323 pub fn left(self) -> Option<L> {
325 match self {
326 Or::Left(l) => Some(l),
327 Or::Both(l, _) => Some(l),
328 _ => None,
329 }
330 }
331
332 pub fn right(self) -> Option<R> {
334 match self {
335 Or::Right(r) => Some(r),
336 Or::Both(_, r) => Some(r),
337 _ => None,
338 }
339 }
340
341 pub fn map<L1, R1, F, G>(self, f: F, g: G) -> Or<L1, R1>
343 where
344 F: FnOnce(L) -> L1,
345 G: FnOnce(R) -> R1,
346 {
347 match self {
348 Or::Left(l) => Or::Left(f(l)),
349 Or::Right(r) => Or::Right(g(r)),
350 Or::Both(l, r) => Or::Both(f(l), g(r)),
351 }
352 }
353
354 pub fn as_ref(&self) -> Or<&L, &R> {
356 match *self {
357 Or::Left(ref l) => Or::Left(l),
358 Or::Right(ref r) => Or::Right(r),
359 Or::Both(ref l, ref r) => Or::Both(l, r),
360 }
361 }
362
363 pub fn as_mut(&mut self) -> Or<&mut L, &mut R> {
365 match *self {
366 Or::Left(ref mut l) => Or::Left(l),
367 Or::Right(ref mut r) => Or::Right(r),
368 Or::Both(ref mut l, ref mut r) => Or::Both(l, r),
369 }
370 }
371}
372
373impl<L, R> Or<&'_ L, &'_ R>
374where
375 L: Clone,
376 R: Clone,
377{
378 pub fn cloned(self) -> Or<L, R> {
380 self.map(Clone::clone, Clone::clone)
381 }
382}
383
384impl<L: Query, R: Query> Query for Or<L, R> {
385 type Item<'q> = Or<L::Item<'q>, R::Item<'q>>;
386
387 type Fetch = FetchOr<L::Fetch, R::Fetch>;
388
389 unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
390 fetch
391 .0
392 .as_ref()
393 .map(|l| L::get(meta, l, n), |r| R::get(meta, r, n))
394 }
395}
396
397unsafe impl<L: QueryShared, R: QueryShared> QueryShared for Or<L, R> {}
398
399#[doc(hidden)]
400#[derive(Clone)]
401pub struct FetchOr<L, R>(Or<L, R>);
402
403unsafe impl<L: Fetch, R: Fetch> Fetch for FetchOr<L, R> {
404 type State = Or<L::State, R::State>;
405
406 fn dangling() -> Self {
407 Self(Or::Left(L::dangling()))
408 }
409
410 fn access(archetype: &Archetype) -> Option<Access> {
411 L::access(archetype).max(R::access(archetype))
412 }
413
414 fn borrow(archetype: &Archetype, state: Self::State) {
415 state.map(|l| L::borrow(archetype, l), |r| R::borrow(archetype, r));
416 }
417
418 fn prepare(archetype: &Archetype) -> Option<Self::State> {
419 Or::new(L::prepare(archetype), R::prepare(archetype))
420 }
421
422 fn execute(archetype: &Archetype, state: Self::State) -> Self {
423 Self(state.map(|l| L::execute(archetype, l), |r| R::execute(archetype, r)))
424 }
425
426 fn release(archetype: &Archetype, state: Self::State) {
427 state.map(|l| L::release(archetype, l), |r| R::release(archetype, r));
428 }
429
430 fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
431 L::for_each_borrow(&mut f);
432 R::for_each_borrow(&mut f);
433 }
434}
435
436pub struct Without<Q, R>(PhantomData<(Q, fn(R))>);
454
455impl<Q: Query, R: Query> Query for Without<Q, R> {
456 type Item<'q> = Q::Item<'q>;
457
458 type Fetch = FetchWithout<Q::Fetch, R::Fetch>;
459
460 unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
461 Q::get(meta, &fetch.0, n)
462 }
463}
464
465unsafe impl<Q: QueryShared, R> QueryShared for Without<Q, R> {}
466
467#[doc(hidden)]
468pub struct FetchWithout<F, G>(F, PhantomData<fn(G)>);
469
470unsafe impl<F: Fetch, G: Fetch> Fetch for FetchWithout<F, G> {
471 type State = F::State;
472
473 fn dangling() -> Self {
474 Self(F::dangling(), PhantomData)
475 }
476
477 fn access(archetype: &Archetype) -> Option<Access> {
478 if G::access(archetype).is_some() {
479 None
480 } else {
481 F::access(archetype)
482 }
483 }
484
485 fn borrow(archetype: &Archetype, state: Self::State) {
486 F::borrow(archetype, state)
487 }
488 fn prepare(archetype: &Archetype) -> Option<Self::State> {
489 if G::access(archetype).is_some() {
490 return None;
491 }
492 F::prepare(archetype)
493 }
494 fn execute(archetype: &Archetype, state: Self::State) -> Self {
495 Self(F::execute(archetype, state), PhantomData)
496 }
497 fn release(archetype: &Archetype, state: Self::State) {
498 F::release(archetype, state)
499 }
500
501 fn for_each_borrow(f: impl FnMut(TypeId, bool)) {
502 F::for_each_borrow(f);
503 }
504}
505
506impl<F: Clone, G> Clone for FetchWithout<F, G> {
507 #[inline]
508 fn clone(&self) -> Self {
509 Self(self.0.clone(), PhantomData)
510 }
511}
512
513pub struct With<Q, R>(PhantomData<(Q, fn(R))>);
533
534impl<Q: Query, R: Query> Query for With<Q, R> {
535 type Item<'q> = Q::Item<'q>;
536
537 type Fetch = FetchWith<Q::Fetch, R::Fetch>;
538
539 unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
540 Q::get(meta, &fetch.0, n)
541 }
542}
543
544unsafe impl<Q: QueryShared, R> QueryShared for With<Q, R> {}
545
546#[doc(hidden)]
547pub struct FetchWith<F, G>(F, PhantomData<fn(G)>);
548
549unsafe impl<F: Fetch, G: Fetch> Fetch for FetchWith<F, G> {
550 type State = F::State;
551
552 fn dangling() -> Self {
553 Self(F::dangling(), PhantomData)
554 }
555
556 fn access(archetype: &Archetype) -> Option<Access> {
557 if G::access(archetype).is_some() {
558 F::access(archetype)
559 } else {
560 None
561 }
562 }
563
564 fn borrow(archetype: &Archetype, state: Self::State) {
565 F::borrow(archetype, state)
566 }
567 fn prepare(archetype: &Archetype) -> Option<Self::State> {
568 G::access(archetype)?;
569 F::prepare(archetype)
570 }
571 fn execute(archetype: &Archetype, state: Self::State) -> Self {
572 Self(F::execute(archetype, state), PhantomData)
573 }
574 fn release(archetype: &Archetype, state: Self::State) {
575 F::release(archetype, state)
576 }
577
578 fn for_each_borrow(f: impl FnMut(TypeId, bool)) {
579 F::for_each_borrow(f);
580 }
581}
582
583impl<F: Clone, G> Clone for FetchWith<F, G> {
584 #[inline]
585 fn clone(&self) -> Self {
586 Self(self.0.clone(), PhantomData)
587 }
588}
589
590pub struct Satisfies<Q>(PhantomData<Q>);
610
611impl<Q: Query> Query for Satisfies<Q> {
612 type Item<'q> = bool;
613
614 type Fetch = FetchSatisfies<Q::Fetch>;
615
616 unsafe fn get<'q>(_: &[EntityMeta], fetch: &Self::Fetch, _: usize) -> Self::Item<'q> {
617 fetch.0
618 }
619}
620
621unsafe impl<Q> QueryShared for Satisfies<Q> {}
622
623#[doc(hidden)]
624pub struct FetchSatisfies<F>(bool, PhantomData<F>);
625
626unsafe impl<F: Fetch> Fetch for FetchSatisfies<F> {
627 type State = bool;
628
629 fn dangling() -> Self {
630 Self(false, PhantomData)
631 }
632
633 fn access(_archetype: &Archetype) -> Option<Access> {
634 Some(Access::Iterate)
635 }
636
637 fn borrow(_archetype: &Archetype, _state: Self::State) {}
638 fn prepare(archetype: &Archetype) -> Option<Self::State> {
639 Some(F::prepare(archetype).is_some())
640 }
641 fn execute(_archetype: &Archetype, state: Self::State) -> Self {
642 Self(state, PhantomData)
643 }
644 fn release(_archetype: &Archetype, _state: Self::State) {}
645
646 fn for_each_borrow(_: impl FnMut(TypeId, bool)) {}
647}
648
649impl<T> Clone for FetchSatisfies<T> {
650 #[inline]
651 fn clone(&self) -> Self {
652 Self(self.0, PhantomData)
653 }
654}
655
656pub struct QueryBorrow<'w, Q: Query> {
660 world: &'w Substrate,
661 cache: Option<CachedQuery<Q::Fetch>>,
662}
663
664impl<'w, Q: Query> QueryBorrow<'w, Q> {
665 pub(crate) fn new(world: &'w Substrate) -> Self {
666 Self { world, cache: None }
667 }
668
669 pub fn iter(&mut self) -> QueryIter<'_, Q> {
672 let cache = self.borrow().clone();
673 unsafe { QueryIter::new(self.world, cache) }
674 }
675
676 pub fn view(&mut self) -> View<'_, Q> {
678 let cache = self.borrow().clone();
679 unsafe {
680 View::new(
681 self.world.entities_meta(),
682 self.world.archetypes_inner(),
683 cache,
684 )
685 }
686 }
687
688 pub fn iter_batched(&mut self, batch_size: u32) -> BatchedIter<'_, Q> {
693 let cache = self.borrow().clone();
694 unsafe {
695 BatchedIter::new(
696 self.world.entities_meta(),
697 self.world.archetypes_inner(),
698 batch_size,
699 cache,
700 )
701 }
702 }
703
704 fn borrow(&mut self) -> &CachedQuery<Q::Fetch> {
705 if self.cache.is_none() {
706 let cache = CachedQuery::get(self.world);
707 cache.borrow(self.world.archetypes_inner());
708 self.cache = Some(cache);
709 }
710
711 self.cache.as_ref().unwrap()
712 }
713
714 pub fn with<R: Query>(self) -> QueryBorrow<'w, With<Q, R>> {
737 self.transform()
738 }
739
740 pub fn without<R: Query>(self) -> QueryBorrow<'w, Without<Q, R>> {
759 self.transform()
760 }
761
762 fn transform<R: Query>(self) -> QueryBorrow<'w, R> {
764 QueryBorrow {
765 world: self.world,
766 cache: None,
767 }
768 }
769}
770
771unsafe impl<Q: Query> Send for QueryBorrow<'_, Q> where for<'a> Q::Item<'a>: Send {}
772unsafe impl<Q: Query> Sync for QueryBorrow<'_, Q> where for<'a> Q::Item<'a>: Send {}
773
774impl<Q: Query> Drop for QueryBorrow<'_, Q> {
775 fn drop(&mut self) {
776 if let Some(cache) = &self.cache {
777 cache.release_borrow(self.world.archetypes_inner());
778 }
779 }
780}
781
782impl<'q, Q: Query> IntoIterator for &'q mut QueryBorrow<'_, Q> {
783 type Item = Q::Item<'q>;
784 type IntoIter = QueryIter<'q, Q>;
785
786 fn into_iter(self) -> Self::IntoIter {
787 self.iter()
788 }
789}
790
791pub struct QueryIter<'q, Q: Query> {
793 world: &'q Substrate,
794 archetypes: ArchetypeIter<Q>,
795 iter: ChunkIter<Q>,
796}
797
798impl<'q, Q: Query> QueryIter<'q, Q> {
799 unsafe fn new(world: &'q Substrate, cache: CachedQuery<Q::Fetch>) -> Self {
805 Self {
806 world,
807 archetypes: ArchetypeIter::new(world, cache),
808 iter: ChunkIter::empty(),
809 }
810 }
811}
812
813unsafe impl<Q: Query> Send for QueryIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
814unsafe impl<Q: Query> Sync for QueryIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
815
816impl<'q, Q: Query> Iterator for QueryIter<'q, Q> {
817 type Item = Q::Item<'q>;
818
819 #[inline(always)]
820 fn next(&mut self) -> Option<Self::Item> {
821 loop {
822 match unsafe { self.iter.next(self.world.entities_meta()) } {
823 None => {
824 unsafe {
826 self.iter = self.archetypes.next(self.world)?;
827 }
828 continue;
829 }
830 Some(components) => {
831 return Some(components);
832 }
833 }
834 }
835 }
836
837 fn size_hint(&self) -> (usize, Option<usize>) {
838 let n = self.len();
839 (n, Some(n))
840 }
841
842 fn fold<B, F>(mut self, mut init: B, mut f: F) -> B
851 where
852 Self: Sized,
853 F: FnMut(B, Self::Item) -> B,
854 {
855 loop {
856 while let Some(components) = unsafe { self.iter.next(self.world.entities_meta()) } {
857 init = f(init, components);
858 }
859
860 if let Some(iter) = unsafe { self.archetypes.next(self.world) } {
861 self.iter = iter;
862 } else {
863 break init;
864 }
865 }
866 }
867}
868
869impl<Q: Query> ExactSizeIterator for QueryIter<'_, Q> {
870 fn len(&self) -> usize {
871 self.archetypes.entity_len(self.world) + self.iter.remaining()
872 }
873}
874
875pub struct QueryMut<'q, Q: Query> {
877 world: &'q mut Substrate,
878 _marker: PhantomData<fn() -> Q>,
879}
880
881impl<'q, Q: Query> QueryMut<'q, Q> {
882 pub(crate) fn new(world: &'q mut Substrate) -> Self {
883 assert_borrow::<Q>();
884 Self {
885 world,
886 _marker: PhantomData,
887 }
888 }
889
890 pub fn view(&mut self) -> View<'_, Q> {
892 let cache = CachedQuery::get(self.world);
893 unsafe {
894 View::new(
895 self.world.entities_meta(),
896 self.world.archetypes_inner(),
897 cache,
898 )
899 }
900 }
901
902 pub fn with<R: Query>(self) -> QueryMut<'q, With<Q, R>> {
906 self.transform()
907 }
908
909 pub fn without<R: Query>(self) -> QueryMut<'q, Without<Q, R>> {
913 self.transform()
914 }
915
916 fn transform<R: Query>(self) -> QueryMut<'q, R> {
918 QueryMut {
919 world: self.world,
920 _marker: PhantomData,
921 }
922 }
923
924 pub fn into_iter_batched(self, batch_size: u32) -> BatchedIter<'q, Q> {
928 let cache = CachedQuery::get(self.world);
929 unsafe {
930 BatchedIter::new(
931 self.world.entities_meta(),
932 self.world.archetypes_inner(),
933 batch_size,
934 cache,
935 )
936 }
937 }
938}
939
940impl<'q, Q: Query> IntoIterator for QueryMut<'q, Q> {
941 type Item = <QueryIter<'q, Q> as Iterator>::Item;
942 type IntoIter = QueryIter<'q, Q>;
943
944 #[inline]
945 fn into_iter(self) -> Self::IntoIter {
946 let cache = CachedQuery::get(self.world);
947 unsafe { QueryIter::new(self.world, cache) }
948 }
949}
950
951pub(crate) fn assert_borrow<Q: Query>() {
953 let mut i = 0;
956 Q::Fetch::for_each_borrow(|a, unique| {
957 if unique {
958 let mut j = 0;
959 Q::Fetch::for_each_borrow(|b, _| {
960 if i != j {
961 core::assert!(a != b, "query violates a unique borrow");
962 }
963 j += 1;
964 })
965 }
966 i += 1;
967 });
968}
969
970struct ChunkIter<Q: Query> {
971 fetch: Q::Fetch,
972 position: usize,
973 len: usize,
974}
975
976impl<Q: Query> ChunkIter<Q> {
977 fn new(archetype: &Archetype, fetch: Q::Fetch) -> Self {
978 Self {
979 fetch,
980 position: 0,
981 len: archetype.len() as usize,
982 }
983 }
984
985 fn empty() -> Self {
986 Self {
987 fetch: Q::Fetch::dangling(),
988 position: 0,
989 len: 0,
990 }
991 }
992
993 #[inline]
994 unsafe fn next<'a>(&mut self, meta: &[EntityMeta]) -> Option<Q::Item<'a>> {
995 if self.position == self.len {
996 return None;
997 }
998 let item = Q::get(meta, &self.fetch, self.position);
999 self.position += 1;
1000 Some(item)
1001 }
1002
1003 fn remaining(&self) -> usize {
1004 self.len - self.position
1005 }
1006}
1007
1008pub struct BatchedIter<'q, Q: Query> {
1010 _marker: PhantomData<&'q Q>,
1011 meta: &'q [EntityMeta],
1012 archetypes: &'q [Archetype],
1013 index_iter: core::ops::Range<usize>,
1014 batch_size: u32,
1015 cache: CachedQuery<Q::Fetch>,
1016 batch: u32,
1017}
1018
1019impl<'q, Q: Query> BatchedIter<'q, Q> {
1020 unsafe fn new(
1025 meta: &'q [EntityMeta],
1026 archetypes: &'q [Archetype],
1027 batch_size: u32,
1028 cache: CachedQuery<Q::Fetch>,
1029 ) -> Self {
1030 Self {
1031 _marker: PhantomData,
1032 meta,
1033 archetypes,
1034 index_iter: (0..cache.archetype_count(archetypes)),
1035 batch_size,
1036 cache,
1037 batch: 0,
1038 }
1039 }
1040}
1041
1042unsafe impl<Q: Query> Send for BatchedIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
1043unsafe impl<Q: Query> Sync for BatchedIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
1044
1045impl<'q, Q: Query> Iterator for BatchedIter<'q, Q> {
1046 type Item = Batch<'q, Q>;
1047
1048 fn next(&mut self) -> Option<Self::Item> {
1049 loop {
1050 let mut indices = self.index_iter.clone();
1051 let index = indices.next()?;
1052 let Some((archetype, state)) =
1053 (unsafe { self.cache.get_state(self.archetypes, index) })
1054 else {
1055 self.index_iter = indices;
1057 continue;
1058 };
1059 let offset = self.batch_size * self.batch;
1060 if offset >= archetype.len() {
1061 self.index_iter = indices;
1063 self.batch = 0;
1064 continue;
1065 }
1066 let fetch = Q::Fetch::execute(archetype, state);
1067 self.batch += 1;
1068 let mut state = ChunkIter::new(archetype, fetch);
1069 state.position = offset as usize;
1070 state.len = (offset + self.batch_size.min(archetype.len() - offset)) as usize;
1071 return Some(Batch {
1072 meta: self.meta,
1073 state,
1074 });
1075 }
1076 }
1077}
1078
1079pub struct Batch<'q, Q: Query> {
1081 meta: &'q [EntityMeta],
1082 state: ChunkIter<Q>,
1083}
1084
1085impl<'q, Q: Query> Iterator for Batch<'q, Q> {
1086 type Item = Q::Item<'q>;
1087
1088 fn next(&mut self) -> Option<Self::Item> {
1089 unsafe { self.state.next(self.meta) }
1090 }
1091}
1092
1093unsafe impl<Q: Query> Send for Batch<'_, Q> where for<'a> Q::Item<'a>: Send {}
1094unsafe impl<Q: Query> Sync for Batch<'_, Q> where for<'a> Q::Item<'a>: Send {}
1095
1096macro_rules! tuple_impl {
1097 ($($name: ident),*) => {
1098 unsafe impl<$($name: Fetch),*> Fetch for ($($name,)*) {
1099 type State = ($($name::State,)*);
1100
1101 #[allow(clippy::unused_unit)]
1102 fn dangling() -> Self {
1103 ($($name::dangling(),)*)
1104 }
1105
1106 #[allow(unused_variables, unused_mut)]
1107 fn access(archetype: &Archetype) -> Option<Access> {
1108 let mut access = Access::Iterate;
1109 $(
1110 access = access.max($name::access(archetype)?);
1111 )*
1112 Some(access)
1113 }
1114
1115 #[allow(unused_variables, non_snake_case, clippy::unused_unit)]
1116 fn borrow(archetype: &Archetype, state: Self::State) {
1117 let ($($name,)*) = state;
1118 $($name::borrow(archetype, $name);)*
1119 }
1120 #[allow(unused_variables)]
1121 #[cold]
1122 fn prepare(archetype: &Archetype) -> Option<Self::State> {
1123 Some(($($name::prepare(archetype)?,)*))
1124 }
1125 #[allow(unused_variables, non_snake_case, clippy::unused_unit)]
1126 #[inline(always)]
1127 fn execute(archetype: &Archetype, state: Self::State) -> Self {
1128 let ($($name,)*) = state;
1129 ($($name::execute(archetype, $name),)*)
1130 }
1131 #[allow(unused_variables, non_snake_case, clippy::unused_unit)]
1132 fn release(archetype: &Archetype, state: Self::State) {
1133 let ($($name,)*) = state;
1134 $($name::release(archetype, $name);)*
1135 }
1136
1137 #[allow(unused_variables, unused_mut, clippy::unused_unit)]
1138 fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
1139 $($name::for_each_borrow(&mut f);)*
1140 }
1141 }
1142
1143 impl<$($name: Query),*> Query for ($($name,)*) {
1144 type Item<'q> = ($($name::Item<'q>,)*);
1145
1146 type Fetch = ($($name::Fetch,)*);
1147
1148 #[allow(unused_variables, clippy::unused_unit)]
1149 unsafe fn get<'q>(meta: &[EntityMeta], fetch: &Self::Fetch, n: usize) -> Self::Item<'q> {
1150 #[allow(non_snake_case)]
1151 let ($(ref $name,)*) = *fetch;
1152 ($($name::get(meta, $name, n),)*)
1153 }
1154 }
1155
1156 unsafe impl<$($name: QueryShared),*> QueryShared for ($($name,)*) {}
1157 };
1158}
1159
1160smaller_tuples_too!(tuple_impl, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A);
1162
1163pub struct PreparedQuery<Q: Query> {
1170 memo: (u64, u32),
1171 state: Box<[(usize, <Q::Fetch as Fetch>::State)]>,
1172 fetch: Box<[Option<Q::Fetch>]>,
1173}
1174
1175impl<Q: Query> Default for PreparedQuery<Q> {
1176 fn default() -> Self {
1177 Self::new()
1178 }
1179}
1180
1181impl<Q: Query> PreparedQuery<Q> {
1182 pub fn new() -> Self {
1184 Self {
1185 memo: (0, 0),
1187 state: Default::default(),
1188 fetch: Default::default(),
1189 }
1190 }
1191
1192 #[cold]
1193 fn prepare(world: &Substrate) -> Self {
1194 let memo = world.memo();
1195
1196 let state = world
1197 .archetypes()
1198 .enumerate()
1199 .filter_map(|(idx, x)| Q::Fetch::prepare(x).map(|state| (idx, state)))
1200 .collect();
1201
1202 let fetch = world.archetypes().map(|_| None).collect();
1203
1204 Self { memo, state, fetch }
1205 }
1206
1207 pub fn query<'q>(&'q mut self, world: &'q Substrate) -> PreparedQueryBorrow<'q, Q> {
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 PreparedQueryBorrow::new(meta, archetypes, &self.state, &mut self.fetch)
1220 }
1221
1222 pub fn query_mut<'q>(&'q mut self, world: &'q mut Substrate) -> PreparedQueryIter<'q, Q> {
1226 assert_borrow::<Q>();
1227
1228 if self.memo != world.memo() {
1229 *self = Self::prepare(world);
1230 }
1231
1232 let meta = world.entities_meta();
1233 let archetypes = world.archetypes_inner();
1234
1235 unsafe { PreparedQueryIter::new(meta, archetypes, self.state.iter()) }
1236 }
1237
1238 pub fn view_mut<'q>(&'q mut self, world: &'q mut Substrate) -> PreparedView<'q, Q> {
1240 assert_borrow::<Q>();
1241
1242 if self.memo != world.memo() {
1243 *self = Self::prepare(world);
1244 }
1245
1246 let meta = world.entities_meta();
1247 let archetypes = world.archetypes_inner();
1248
1249 unsafe { PreparedView::new(meta, archetypes, self.state.iter(), &mut self.fetch) }
1250 }
1251}
1252
1253pub struct PreparedQueryBorrow<'q, Q: Query> {
1255 meta: &'q [EntityMeta],
1256 archetypes: &'q [Archetype],
1257 state: &'q [(usize, <Q::Fetch as Fetch>::State)],
1258 fetch: &'q mut [Option<Q::Fetch>],
1259}
1260
1261impl<'q, Q: Query> PreparedQueryBorrow<'q, Q> {
1262 fn new(
1263 meta: &'q [EntityMeta],
1264 archetypes: &'q [Archetype],
1265 state: &'q [(usize, <Q::Fetch as Fetch>::State)],
1266 fetch: &'q mut [Option<Q::Fetch>],
1267 ) -> Self {
1268 for (idx, state) in state {
1269 if archetypes[*idx].is_empty() {
1270 continue;
1271 }
1272 Q::Fetch::borrow(&archetypes[*idx], *state);
1273 }
1274
1275 Self {
1276 meta,
1277 archetypes,
1278 state,
1279 fetch,
1280 }
1281 }
1282
1283 pub fn iter(&mut self) -> PreparedQueryIter<'_, Q> {
1286 unsafe { PreparedQueryIter::new(self.meta, self.archetypes, self.state.iter()) }
1287 }
1288
1289 pub fn view(&mut self) -> PreparedView<'_, Q> {
1291 unsafe { PreparedView::new(self.meta, self.archetypes, self.state.iter(), self.fetch) }
1292 }
1293}
1294
1295impl<Q: Query> Drop for PreparedQueryBorrow<'_, Q> {
1296 fn drop(&mut self) {
1297 for (idx, state) in self.state {
1298 if self.archetypes[*idx].is_empty() {
1299 continue;
1300 }
1301 Q::Fetch::release(&self.archetypes[*idx], *state);
1302 }
1303 }
1304}
1305
1306pub struct PreparedQueryIter<'q, Q: Query> {
1308 meta: &'q [EntityMeta],
1309 archetypes: &'q [Archetype],
1310 state: SliceIter<'q, (usize, <Q::Fetch as Fetch>::State)>,
1311 iter: ChunkIter<Q>,
1312}
1313
1314impl<'q, Q: Query> PreparedQueryIter<'q, Q> {
1315 unsafe fn new(
1320 meta: &'q [EntityMeta],
1321 archetypes: &'q [Archetype],
1322 state: SliceIter<'q, (usize, <Q::Fetch as Fetch>::State)>,
1323 ) -> Self {
1324 Self {
1325 meta,
1326 archetypes,
1327 state,
1328 iter: ChunkIter::empty(),
1329 }
1330 }
1331}
1332
1333unsafe impl<Q: Query> Send for PreparedQueryIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
1334unsafe impl<Q: Query> Sync for PreparedQueryIter<'_, Q> where for<'a> Q::Item<'a>: Send {}
1335
1336impl<'q, Q: Query> Iterator for PreparedQueryIter<'q, Q> {
1337 type Item = Q::Item<'q>;
1338
1339 #[inline(always)]
1340 fn next(&mut self) -> Option<Self::Item> {
1341 loop {
1342 match unsafe { self.iter.next(self.meta) } {
1343 None => {
1344 let (idx, state) = self.state.next()?;
1345 let archetype = &self.archetypes[*idx];
1346 self.iter = ChunkIter::new(archetype, Q::Fetch::execute(archetype, *state));
1347 continue;
1348 }
1349 Some(components) => {
1350 return Some(components);
1351 }
1352 }
1353 }
1354 }
1355
1356 fn size_hint(&self) -> (usize, Option<usize>) {
1357 let n = self.len();
1358 (n, Some(n))
1359 }
1360}
1361
1362impl<Q: Query> ExactSizeIterator for PreparedQueryIter<'_, Q> {
1363 fn len(&self) -> usize {
1364 self.state
1365 .clone()
1366 .map(|(idx, _)| self.archetypes[*idx].len() as usize)
1367 .sum::<usize>()
1368 + self.iter.remaining()
1369 }
1370}
1371
1372pub struct View<'q, Q: Query> {
1378 meta: &'q [EntityMeta],
1379 archetypes: &'q [Archetype],
1380 fetch: Box<[Option<Q::Fetch>]>,
1381}
1382
1383unsafe impl<Q: Query> Send for View<'_, Q> where for<'a> Q::Item<'a>: Send {}
1384unsafe impl<Q: Query> Sync for View<'_, Q> where for<'a> Q::Item<'a>: Send {}
1385
1386impl<'q, Q: Query> View<'q, Q> {
1387 pub(crate) unsafe fn new(
1392 meta: &'q [EntityMeta],
1393 archetypes: &'q [Archetype],
1394 cache: CachedQuery<Q::Fetch>,
1395 ) -> Self {
1396 Self {
1397 meta,
1398 archetypes,
1399 fetch: cache.fetch_all(archetypes),
1400 }
1401 }
1402
1403 pub fn get(&self, entity: Entity) -> Option<Q::Item<'_>>
1409 where
1410 Q: QueryShared,
1411 {
1412 let meta = self.meta.get(entity.id as usize)?;
1413 if meta.generation != entity.generation {
1414 return None;
1415 }
1416
1417 self.fetch[meta.location.archetype as usize]
1418 .as_ref()
1419 .map(|fetch| unsafe { Q::get(self.meta, fetch, meta.location.index as usize) })
1420 }
1421
1422 pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1426 unsafe { self.get_unchecked(entity) }
1427 }
1428
1429 pub fn contains(&self, entity: Entity) -> bool {
1431 let Some(meta) = self.meta.get(entity.id as usize) else {
1432 return false;
1433 };
1434 if meta.generation != entity.generation {
1435 return false;
1436 }
1437 self.fetch[meta.location.archetype as usize].is_some()
1438 }
1439
1440 pub unsafe fn get_unchecked(&self, entity: Entity) -> Option<Q::Item<'_>> {
1446 let meta = self.meta.get(entity.id as usize)?;
1447 if meta.generation != entity.generation {
1448 return None;
1449 }
1450
1451 self.fetch[meta.location.archetype as usize]
1452 .as_ref()
1453 .map(|fetch| Q::get(self.meta, fetch, meta.location.index as usize))
1454 }
1455
1456 pub fn get_disjoint_mut<const N: usize>(
1479 &mut self,
1480 entities: [Entity; N],
1481 ) -> [Option<Q::Item<'_>>; N] {
1482 assert_distinct(&entities);
1483
1484 let mut items = [(); N].map(|()| None);
1485
1486 for (item, entity) in items.iter_mut().zip(entities) {
1487 unsafe {
1488 *item = self.get_unchecked(entity);
1489 }
1490 }
1491
1492 items
1493 }
1494
1495 #[doc(hidden)]
1496 #[deprecated(since = "0.11.0", note = "renamed to `get_disjoint_mut`")]
1497 pub fn get_many_mut<const N: usize>(
1498 &mut self,
1499 entities: [Entity; N],
1500 ) -> [Option<Q::Item<'_>>; N] {
1501 self.get_disjoint_mut(entities)
1502 }
1503
1504 pub fn iter_mut(&mut self) -> ViewIter<'_, Q> {
1508 ViewIter {
1509 meta: self.meta,
1510 archetypes: self.archetypes.iter(),
1511 fetches: self.fetch.iter(),
1512 iter: ChunkIter::empty(),
1513 }
1514 }
1515}
1516
1517impl<'a, Q: Query> IntoIterator for &'a mut View<'_, Q> {
1518 type IntoIter = ViewIter<'a, Q>;
1519 type Item = Q::Item<'a>;
1520
1521 #[inline]
1522 fn into_iter(self) -> Self::IntoIter {
1523 self.iter_mut()
1524 }
1525}
1526
1527pub struct ViewIter<'a, Q: Query> {
1528 meta: &'a [EntityMeta],
1529 archetypes: SliceIter<'a, Archetype>,
1530 fetches: SliceIter<'a, Option<Q::Fetch>>,
1531 iter: ChunkIter<Q>,
1532}
1533
1534impl<'a, Q: Query> Iterator for ViewIter<'a, Q> {
1535 type Item = Q::Item<'a>;
1536
1537 #[inline(always)]
1538 fn next(&mut self) -> Option<Self::Item> {
1539 loop {
1540 match unsafe { self.iter.next(self.meta) } {
1541 None => {
1542 let archetype = self.archetypes.next()?;
1543 let fetch = self.fetches.next()?;
1544 self.iter = fetch
1545 .clone()
1546 .map_or(ChunkIter::empty(), |fetch| ChunkIter::new(archetype, fetch));
1547 continue;
1548 }
1549 Some(components) => {
1550 return Some(components);
1551 }
1552 }
1553 }
1554 }
1555}
1556
1557pub struct PreparedView<'q, Q: Query> {
1559 meta: &'q [EntityMeta],
1560 archetypes: &'q [Archetype],
1561 fetch: &'q mut [Option<Q::Fetch>],
1562}
1563
1564unsafe impl<Q: Query> Send for PreparedView<'_, Q> where for<'a> Q::Item<'a>: Send {}
1565unsafe impl<Q: Query> Sync for PreparedView<'_, Q> where for<'a> Q::Item<'a>: Send {}
1566
1567impl<'q, Q: Query> PreparedView<'q, Q> {
1568 unsafe fn new(
1573 meta: &'q [EntityMeta],
1574 archetypes: &'q [Archetype],
1575 state: SliceIter<'q, (usize, <Q::Fetch as Fetch>::State)>,
1576 fetch: &'q mut [Option<Q::Fetch>],
1577 ) -> Self {
1578 fetch.iter_mut().for_each(|fetch| *fetch = None);
1579
1580 for (idx, state) in state {
1581 let archetype = &archetypes[*idx];
1582 fetch[*idx] = Some(Q::Fetch::execute(archetype, *state));
1583 }
1584
1585 Self {
1586 meta,
1587 archetypes,
1588 fetch,
1589 }
1590 }
1591
1592 pub fn get(&self, entity: Entity) -> Option<Q::Item<'_>>
1598 where
1599 Q: QueryShared,
1600 {
1601 let meta = self.meta.get(entity.id as usize)?;
1602 if meta.generation != entity.generation {
1603 return None;
1604 }
1605
1606 self.fetch[meta.location.archetype as usize]
1607 .as_ref()
1608 .map(|fetch| unsafe { Q::get(self.meta, fetch, meta.location.index as usize) })
1609 }
1610
1611 pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1615 unsafe { self.get_unchecked(entity) }
1616 }
1617
1618 pub fn contains(&self, entity: Entity) -> bool {
1620 let Some(meta) = self.meta.get(entity.id as usize) else {
1621 return false;
1622 };
1623 if meta.generation != entity.generation {
1624 return false;
1625 }
1626 self.fetch[meta.location.archetype as usize].is_some()
1627 }
1628
1629 pub unsafe fn get_unchecked(&self, entity: Entity) -> Option<Q::Item<'_>> {
1635 let meta = self.meta.get(entity.id as usize)?;
1636 if meta.generation != entity.generation {
1637 return None;
1638 }
1639
1640 self.fetch[meta.location.archetype as usize]
1641 .as_ref()
1642 .map(|fetch| Q::get(self.meta, fetch, meta.location.index as usize))
1643 }
1644
1645 pub fn get_disjoint_mut<const N: usize>(
1649 &mut self,
1650 entities: [Entity; N],
1651 ) -> [Option<Q::Item<'_>>; N] {
1652 assert_distinct(&entities);
1653
1654 let mut items = [(); N].map(|()| None);
1655
1656 for (item, entity) in items.iter_mut().zip(entities) {
1657 unsafe {
1658 *item = self.get_unchecked(entity);
1659 }
1660 }
1661
1662 items
1663 }
1664
1665 #[doc(hidden)]
1666 #[deprecated(since = "0.11.0", note = "renamed to `get_disjoint_mut`")]
1667 pub fn get_many_mut<const N: usize>(
1668 &mut self,
1669 entities: [Entity; N],
1670 ) -> [Option<Q::Item<'_>>; N] {
1671 self.get_disjoint_mut(entities)
1672 }
1673
1674 pub fn iter_mut(&mut self) -> ViewIter<'_, Q> {
1678 ViewIter {
1679 meta: self.meta,
1680 archetypes: self.archetypes.iter(),
1681 fetches: self.fetch.iter(),
1682 iter: ChunkIter::empty(),
1683 }
1684 }
1685}
1686
1687impl<'a, Q: Query> IntoIterator for &'a mut PreparedView<'_, Q> {
1688 type IntoIter = ViewIter<'a, Q>;
1689 type Item = Q::Item<'a>;
1690
1691 #[inline]
1692 fn into_iter(self) -> Self::IntoIter {
1693 self.iter_mut()
1694 }
1695}
1696
1697pub struct ViewBorrow<'w, Q: Query> {
1703 view: View<'w, Q>,
1704 cache: CachedQuery<Q::Fetch>,
1705}
1706
1707impl<'w, Q: Query> ViewBorrow<'w, Q> {
1708 pub(crate) fn new(world: &'w Substrate) -> Self {
1709 let cache = CachedQuery::get(world);
1710 cache.borrow(world.archetypes_inner());
1711 let view = unsafe {
1712 View::<Q>::new(
1713 world.entities_meta(),
1714 world.archetypes_inner(),
1715 cache.clone(),
1716 )
1717 };
1718
1719 Self { view, cache }
1720 }
1721
1722 pub fn get(&self, entity: Entity) -> Option<Q::Item<'_>>
1730 where
1731 Q: QueryShared,
1732 {
1733 self.view.get(entity)
1734 }
1735
1736 pub fn get_mut(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
1742 self.view.get_mut(entity)
1743 }
1744
1745 pub fn contains(&self, entity: Entity) -> bool {
1749 self.view.contains(entity)
1750 }
1751
1752 pub unsafe fn get_unchecked(&self, entity: Entity) -> Option<Q::Item<'_>> {
1760 self.view.get_unchecked(entity)
1761 }
1762
1763 pub fn get_disjoint_mut<const N: usize>(
1787 &mut self,
1788 entities: [Entity; N],
1789 ) -> [Option<Q::Item<'_>>; N] {
1790 self.view.get_disjoint_mut(entities)
1791 }
1792
1793 #[doc(hidden)]
1794 #[deprecated(since = "0.11.0", note = "renamed to `get_disjoint_mut`")]
1795 pub fn get_many_mut<const N: usize>(
1796 &mut self,
1797 entities: [Entity; N],
1798 ) -> [Option<Q::Item<'_>>; N] {
1799 self.view.get_disjoint_mut(entities)
1800 }
1801
1802 pub fn iter_mut(&mut self) -> ViewIter<'_, Q> {
1806 self.view.iter_mut()
1807 }
1808}
1809
1810impl<Q: Query> Drop for ViewBorrow<'_, Q> {
1811 fn drop(&mut self) {
1812 self.cache.release_borrow(self.view.archetypes);
1813 }
1814}
1815
1816impl<'a, Q: Query> IntoIterator for &'a mut ViewBorrow<'_, Q> {
1817 type IntoIter = ViewIter<'a, Q>;
1818 type Item = Q::Item<'a>;
1819
1820 #[inline]
1821 fn into_iter(self) -> Self::IntoIter {
1822 self.iter_mut()
1823 }
1824}
1825
1826pub(crate) fn assert_distinct<const N: usize>(entities: &[Entity; N]) {
1827 match N {
1828 1 => (),
1829 2 => assert_ne!(entities[0], entities[1]),
1830 3 => {
1831 assert_ne!(entities[0], entities[1]);
1832 assert_ne!(entities[1], entities[2]);
1833 assert_ne!(entities[2], entities[0]);
1834 }
1835 _ => {
1836 let mut entities = *entities;
1837 entities.sort_unstable();
1838 for index in 0..N - 1 {
1839 assert_ne!(entities[index], entities[index + 1]);
1840 }
1841 }
1842 }
1843}
1844
1845#[cfg(feature = "std")]
1846pub(crate) type QueryCache = RwLock<TypeIdMap<Arc<dyn Any + Send + Sync>>>;
1847
1848#[cfg(feature = "std")]
1849struct CachedQueryInner<F: Fetch> {
1850 state: Box<[(usize, F::State)]>,
1851 archetypes_generation: crate::ArchetypesGeneration,
1854}
1855
1856#[cfg(feature = "std")]
1857impl<F: Fetch> CachedQueryInner<F> {
1858 fn new(world: &Substrate) -> Self {
1859 Self {
1860 state: world
1861 .archetypes()
1862 .enumerate()
1863 .filter_map(|(idx, x)| F::prepare(x).map(|state| (idx, state)))
1864 .collect(),
1865 archetypes_generation: world.archetypes_generation(),
1866 }
1867 }
1868}
1869
1870pub(crate) struct CachedQuery<F: Fetch> {
1871 #[cfg(feature = "std")]
1872 inner: Arc<CachedQueryInner<F>>,
1873 #[cfg(not(feature = "std"))]
1874 _marker: PhantomData<F>,
1875}
1876
1877impl<F: Fetch> CachedQuery<F> {
1878 pub(crate) fn get(world: &Substrate) -> Self {
1879 #[cfg(feature = "std")]
1880 {
1881 let existing_cache = world
1882 .query_cache()
1883 .read()
1884 .unwrap()
1885 .get(&TypeId::of::<F>())
1886 .map(|x| Arc::downcast::<CachedQueryInner<F>>(x.clone()).unwrap())
1887 .filter(|x| x.archetypes_generation == world.archetypes_generation());
1888 let inner = existing_cache.unwrap_or_else(
1889 #[cold]
1890 || {
1891 let mut cache = world.query_cache().write().unwrap();
1892 let entry = cache.entry(TypeId::of::<F>());
1893 let cached = match entry {
1894 hash_map::Entry::Vacant(e) => {
1895 let fresh = Arc::new(CachedQueryInner::<F>::new(world));
1896 e.insert(fresh.clone());
1897 fresh
1898 }
1899 hash_map::Entry::Occupied(mut e) => {
1900 let value =
1901 Arc::downcast::<CachedQueryInner<F>>(e.get().clone()).unwrap();
1902 match value.archetypes_generation == world.archetypes_generation() {
1903 false => {
1904 let fresh = Arc::new(CachedQueryInner::<F>::new(world));
1905 e.insert(fresh.clone());
1906 fresh
1907 }
1908 true => value,
1909 }
1910 }
1911 };
1912 cached
1913 },
1914 );
1915 Self { inner }
1916 }
1917 #[cfg(not(feature = "std"))]
1918 {
1919 _ = world;
1920 Self {
1921 _marker: PhantomData,
1922 }
1923 }
1924 }
1925
1926 fn archetype_count(&self, archetypes: &[Archetype]) -> usize {
1927 #[cfg(feature = "std")]
1928 {
1929 _ = archetypes;
1930 self.inner.state.len()
1931 }
1932 #[cfg(not(feature = "std"))]
1933 {
1934 archetypes.len()
1935 }
1936 }
1937
1938 unsafe fn get_state<'a>(
1944 &self,
1945 archetypes: &'a [Archetype],
1946 index: usize,
1947 ) -> Option<(&'a Archetype, F::State)> {
1948 #[cfg(feature = "std")]
1949 unsafe {
1950 let &(archetype, state) = self.inner.state.get_unchecked(index);
1951 let archetype = archetypes.get_unchecked(archetype);
1952 Some((archetype, state))
1953 }
1954 #[cfg(not(feature = "std"))]
1955 {
1956 let archetype = unsafe { archetypes.get_unchecked(index) };
1957 let state = F::prepare(archetype)?;
1958 Some((archetype, state))
1959 }
1960 }
1961
1962 unsafe fn get_archetype<'a>(
1968 &self,
1969 archetypes: &'a [Archetype],
1970 index: usize,
1971 ) -> Option<&'a Archetype> {
1972 #[cfg(feature = "std")]
1973 unsafe {
1974 let &(archetype, _) = self.inner.state.get_unchecked(index);
1975 let archetype = archetypes.get_unchecked(archetype);
1976 Some(archetype)
1977 }
1978 #[cfg(not(feature = "std"))]
1979 {
1980 let x = unsafe { archetypes.get_unchecked(index) };
1981 if F::access(x).is_none() {
1982 return None;
1983 }
1984 Some(x)
1985 }
1986 }
1987
1988 fn borrow(&self, archetypes: &[Archetype]) {
1989 #[cfg(feature = "std")]
1990 {
1991 for &(archetype, state) in &self.inner.state {
1992 let archetype = unsafe { archetypes.get_unchecked(archetype) };
1993 if archetype.is_empty() {
1994 continue;
1995 }
1996 F::borrow(archetype, state);
1997 }
1998 }
1999
2000 #[cfg(not(feature = "std"))]
2001 {
2002 for x in archetypes {
2003 if x.is_empty() {
2004 continue;
2005 }
2006 if let Some(state) = F::prepare(x) {
2008 F::borrow(x, state);
2009 }
2010 }
2011 }
2012 }
2013
2014 fn release_borrow(&self, archetypes: &[Archetype]) {
2015 #[cfg(feature = "std")]
2016 {
2017 for &(archetype, state) in &self.inner.state {
2018 let archetype = unsafe { archetypes.get_unchecked(archetype) };
2019 if archetype.is_empty() {
2020 continue;
2021 }
2022 F::release(archetype, state);
2023 }
2024 }
2025
2026 #[cfg(not(feature = "std"))]
2027 {
2028 for x in archetypes {
2029 if x.is_empty() {
2030 continue;
2031 }
2032 if let Some(state) = F::prepare(x) {
2033 F::release(x, state);
2034 }
2035 }
2036 }
2037 }
2038
2039 fn fetch_all(&self, archetypes: &[Archetype]) -> Box<[Option<F>]> {
2040 #[cfg(feature = "std")]
2041 {
2042 let mut fetch = (0..archetypes.len()).map(|_| None).collect::<Box<[_]>>();
2043 for &(archetype_index, state) in &self.inner.state {
2044 let archetype = &archetypes[archetype_index];
2045 fetch[archetype_index] = Some(F::execute(archetype, state));
2046 }
2047 fetch
2048 }
2049 #[cfg(not(feature = "std"))]
2050 {
2051 archetypes
2052 .iter()
2053 .map(|archetype| F::prepare(archetype).map(|state| F::execute(archetype, state)))
2054 .collect()
2055 }
2056 }
2057}
2058
2059impl<F: Fetch> Clone for CachedQuery<F> {
2060 fn clone(&self) -> Self {
2061 Self {
2062 #[cfg(feature = "std")]
2063 inner: self.inner.clone(),
2064 #[cfg(not(feature = "std"))]
2065 _marker: PhantomData,
2066 }
2067 }
2068}
2069
2070struct ArchetypeIter<Q: Query> {
2071 archetypes: core::ops::Range<usize>,
2072 cache: CachedQuery<Q::Fetch>,
2073}
2074
2075impl<Q: Query> ArchetypeIter<Q> {
2076 fn new(world: &Substrate, cache: CachedQuery<Q::Fetch>) -> Self {
2077 Self {
2078 archetypes: 0..cache.archetype_count(world.archetypes_inner()),
2079 cache,
2080 }
2081 }
2082
2083 unsafe fn next(&mut self, world: &Substrate) -> Option<ChunkIter<Q>> {
2085 loop {
2086 let Some((archetype, state)) = self
2087 .cache
2088 .get_state(world.archetypes_inner(), self.archetypes.next()?)
2089 else {
2090 continue;
2091 };
2092 let fetch = Q::Fetch::execute(archetype, state);
2093 return Some(ChunkIter::new(archetype, fetch));
2094 }
2095 }
2096
2097 fn entity_len(&self, world: &Substrate) -> usize {
2098 self.archetypes
2099 .clone()
2100 .filter_map(|x| unsafe { self.cache.get_archetype(world.archetypes_inner(), x) })
2101 .map(|x| x.len() as usize)
2102 .sum()
2103 }
2104}
2105
2106#[cfg(test)]
2107mod tests;