1pub mod filters;
4pub mod resource_query;
5
6#[cfg(test)]
7mod query_tests;
8
9use crate::{
10 Component, RowIndex, World,
11 entity_id::EntityId,
12 systems::SystemDescriptor,
13 table::{ArchetypeHash, EntityTable},
14};
15use filters::Filter;
16use std::{any::TypeId, collections::HashSet, marker::PhantomData, ops::RangeBounds, slice};
17
18pub unsafe trait WorldQuery<'a> {
22 fn new(db: &'a World, system_idx: usize) -> Self;
23
24 fn components_mut(_set: &mut HashSet<TypeId>) {}
26 fn components_const(_set: &mut HashSet<TypeId>) {}
28 fn resources_mut(_set: &mut HashSet<TypeId>) {}
30 fn resources_const(_set: &mut HashSet<TypeId>) {}
32 fn exclusive() -> bool {
34 false
35 }
36
37 fn read_only() -> bool {
38 false
39 }
40}
41
42unsafe impl<'a> WorldQuery<'a> for () {
43 fn new(_db: &'a World, _system_idx: usize) -> Self {}
44 fn read_only() -> bool {
45 true
46 }
47}
48
49#[derive(Default)]
50pub struct QueryProperties {
51 pub exclusive: bool,
52 pub comp_mut: HashSet<TypeId>,
53 pub comp_const: HashSet<TypeId>,
54 pub res_mut: HashSet<TypeId>,
55 pub res_const: HashSet<TypeId>,
56}
57
58impl QueryProperties {
59 pub fn is_disjoint(&self, other: &QueryProperties) -> bool {
60 !self.exclusive
61 && !other.exclusive
62 && self.comp_mut.is_disjoint(&other.comp_const)
63 && self.res_mut.is_disjoint(&other.res_const)
64 && self.comp_mut.is_disjoint(&other.comp_mut)
65 && self.res_mut.is_disjoint(&other.res_mut)
66 && self.comp_const.is_disjoint(&other.comp_mut)
67 && self.res_const.is_disjoint(&other.res_mut)
68 }
69
70 pub fn extend(&mut self, props: QueryProperties) {
71 self.exclusive = self.exclusive || props.exclusive;
72 self.comp_mut.extend(props.comp_mut.into_iter());
73 self.res_mut.extend(props.res_mut.into_iter());
74 self.comp_const.extend(props.comp_const.into_iter());
75 self.res_const.extend(props.res_const.into_iter());
76 }
77
78 pub fn is_empty(&self) -> bool {
79 !self.exclusive
80 && self.comp_mut.is_empty()
81 && self.res_mut.is_empty()
82 && self.res_const.is_empty()
83 && self.comp_const.is_empty()
84 }
85
86 pub fn from_system<T>(desc: &SystemDescriptor<T>) -> Self {
87 Self {
88 exclusive: (desc.exclusive)(),
89 comp_mut: (desc.components_mut)(),
90 res_mut: (desc.resources_mut)(),
91 comp_const: (desc.components_const)(),
92 res_const: (desc.resources_const)(),
93 }
94 }
95}
96
97#[inline]
99#[allow(unused)]
100pub(crate) fn ensure_query_valid<'a, T: WorldQuery<'a>>() -> QueryProperties {
101 let mut comp_mut = HashSet::new();
102 let mut comp_const = HashSet::new();
103
104 T::components_mut(&mut comp_mut);
105 T::components_const(&mut comp_const);
106
107 assert!(
108 comp_mut.is_disjoint(&comp_const),
109 "A query may not borrow the same type as both mutable and immutable,
110{}",
111 std::any::type_name::<T>()
112 );
113
114 let mut res_mut = HashSet::new();
116 let mut res_const = HashSet::new();
117 T::resources_mut(&mut res_mut);
118 T::resources_const(&mut res_const);
119 QueryProperties {
120 comp_mut,
121 comp_const,
122 res_mut,
123 res_const,
124 exclusive: T::exclusive(),
125 }
126}
127
128pub struct Query<'a, T, F = ()> {
129 world: std::ptr::NonNull<crate::World>,
130 _m: PhantomData<(T, F)>,
131 _l: PhantomData<&'a ()>,
132}
133
134unsafe impl<T, F> Send for Query<'_, T, F> {}
135unsafe impl<T, F> Sync for Query<'_, T, F> {}
136
137unsafe impl<'a, T, F> WorldQuery<'a> for Query<'a, T, F>
138where
139 T: QueryFragment,
140 F: Filter,
141{
142 fn new(db: &'a World, _system_idx: usize) -> Self {
143 Self::new(db)
144 }
145
146 fn components_mut(set: &mut HashSet<TypeId>) {
147 <T as QueryFragment>::types_mut(set);
148 }
149
150 fn components_const(set: &mut HashSet<TypeId>) {
151 <T as QueryFragment>::types_const(set);
152 }
153
154 fn read_only() -> bool {
155 <T as QueryFragment>::read_only()
156 }
157}
158
159impl<'a, T, F> Query<'a, T, F>
160where
161 T: QueryFragment,
162 F: Filter,
163{
164 pub fn new(world: &'a crate::World) -> Self {
165 Query {
166 world: std::ptr::NonNull::from(world),
167 _m: PhantomData,
168 _l: PhantomData,
169 }
170 }
171
172 pub fn subset<'b, T1>(&'b mut self) -> Query<'b, T1, F>
216 where
217 T1: QueryFragment,
218 'a: 'b,
219 {
220 #[cfg(debug_assertions)]
221 {
222 let p = ensure_query_valid::<Query<T1, F>>();
223
224 let mut rhs = HashSet::new();
225 Self::components_mut(&mut rhs);
226 let lhs = p.comp_mut;
227
228 assert!(lhs.is_subset(&rhs));
229
230 Self::components_const(&mut rhs);
232
233 let lhs = p.comp_const;
234 assert!(lhs.is_subset(&rhs));
235 }
236 unsafe { Query::<'b, T1, F>::new(self.world.as_ref()) }
237 }
238
239 pub fn with_filter<'b, F1>(&'b mut self) -> Query<'b, T, (F, F1)>
265 where
266 F1: Filter,
267 'a: 'b,
268 {
269 unsafe { Query::<'b, T, (F, F1)>::new(self.world.as_ref()) }
270 }
271
272 pub fn count(&self) -> usize {
274 unsafe {
275 self.world
276 .as_ref()
277 .archetypes
278 .iter()
279 .filter(|(_, arch)| F::filter(arch) && T::contains(arch))
280 .map(|(_, arch)| arch.len())
281 .sum::<usize>()
282 }
283 }
284
285 pub fn is_empty(&self) -> bool {
286 unsafe {
287 self.world
288 .as_ref()
289 .archetypes
290 .iter()
291 .filter(|(_, arch)| F::filter(arch) && T::contains(arch))
292 .all(|(_, arch)| arch.is_empty())
293 }
294 }
295
296 pub fn any(&self) -> bool {
297 unsafe {
298 self.world
299 .as_ref()
300 .archetypes
301 .iter()
302 .filter(|(_, arch)| F::filter(arch) && T::contains(arch))
303 .any(|(_, arch)| !arch.is_empty())
304 }
305 }
306
307 pub fn single<'b>(&'b self) -> Option<<T as QueryFragment>::Item<'a>>
308 where
309 'a: 'b,
310 {
311 self.iter().next()
312 }
313
314 pub fn single_mut<'b>(&'b mut self) -> Option<<T as QueryFragment>::ItemMut<'a>>
315 where
316 'a: 'b,
317 {
318 self.iter_mut().next()
319 }
320
321 pub fn iter<'b>(&'b self) -> impl Iterator<Item = <T as QueryFragment>::Item<'a>> + 'b {
322 unsafe {
323 self.world
324 .as_ref()
325 .archetypes
326 .iter()
327 .filter(|(_, arch)| F::filter(arch))
328 .flat_map(|(_, arch)| T::iter(arch))
329 }
330 }
331
332 pub fn iter_mut<'b>(
333 &'b mut self,
334 ) -> impl Iterator<Item = <T as QueryFragment>::ItemMut<'a>> + 'b {
335 unsafe {
336 self.world
337 .as_ref()
338 .archetypes
339 .iter()
340 .filter(|(_, arch)| F::filter(arch))
341 .flat_map(|(_, arch)| T::iter_mut(arch))
342 }
343 }
344
345 pub unsafe fn iter_unsafe(
350 &'a self,
351 ) -> impl Iterator<Item = <T as QueryFragment>::ItemUnsafe<'a>> {
352 unsafe {
353 self.world
354 .as_ref()
355 .archetypes
356 .iter()
357 .filter(|(_, arch)| F::filter(arch))
358 .flat_map(|(_, arch)| T::iter_unsafe(arch))
359 }
360 }
361
362 pub fn fetch<'b>(&'b self, id: EntityId) -> Option<<T as QueryFragment>::Item<'b>>
363 where
364 'a: 'b,
365 {
366 unsafe {
367 let (arch, index) = self.world.as_ref().entity_ids().read(id).ok()?;
368 if !F::filter(arch.as_ref()) {
369 return None;
370 }
371
372 T::fetch(arch.as_ref(), index)
373 }
374 }
375
376 pub fn fetch_mut<'b>(&'b mut self, id: EntityId) -> Option<<T as QueryFragment>::ItemMut<'b>>
377 where
378 'a: 'b,
379 {
380 unsafe {
381 let (arch, index) = self.world.as_ref().entity_ids().read(id).ok()?;
382 if !F::filter(arch.as_ref()) {
383 return None;
384 }
385
386 T::fetch_mut(arch.as_ref(), index)
387 }
388 }
389
390 pub unsafe fn fetch_unsafe(
391 &'a self,
392 id: EntityId,
393 ) -> Option<<T as QueryFragment>::ItemUnsafe<'a>> {
394 unsafe {
395 let (arch, index) = self.world.as_ref().entity_ids().read(id).ok()?;
396 if !F::filter(arch.as_ref()) {
397 return None;
398 }
399
400 T::fetch_unsafe(arch.as_ref(), index)
401 }
402 }
403
404 pub fn contains(&self, id: EntityId) -> bool {
405 unsafe {
406 let (arch, _index) = match self.world.as_ref().entity_ids().read(id).ok() {
407 None => return false,
408 Some(x) => x,
409 };
410 if !F::filter(arch.as_ref()) {
411 return false;
412 }
413
414 T::contains(arch.as_ref())
415 }
416 }
417
418 pub fn one(&'a self) -> <T as QueryFragment>::Item<'a> {
421 self.iter().next().unwrap()
422 }
423
424 #[cfg(feature = "parallel")]
425 pub fn par_for_each<'b>(&'b self, f: impl Fn(<T as QueryFragment>::Item<'a>) + Sync + 'b)
426 where
427 T: Send + Sync,
428 {
429 unsafe {
430 let world = self.world.as_ref();
431 let pool = &world.job_system;
432 pool.scope(|s| {
433 let f = &f;
434 world
435 .archetypes
436 .iter()
437 .filter(|(_, arch)| !arch.is_empty() && F::filter(arch))
441 .for_each(|(_, arch)| {
442 let batch_size = arch.len() / pool.parallelism() + 1;
443 for range in batches(arch.len(), batch_size) {
445 s.spawn(move |_s| {
446 for t in T::iter_range(arch, range) {
447 f(t);
448 }
449 })
450 }
451 });
452 });
453 }
454 }
455
456 #[cfg(feature = "parallel")]
457 pub fn par_for_each_mut<'b>(
458 &'b mut self,
459 f: impl Fn(<T as QueryFragment>::ItemMut<'a>) + Sync + 'b,
460 ) where
461 T: Send + Sync,
462 {
463 unsafe {
464 let world = self.world.as_ref();
465 let pool = &world.job_system;
466 pool.scope(|s| {
467 let f = &f;
468 world
469 .archetypes
470 .iter()
471 .filter(|(_, arch)| !arch.is_empty() && F::filter(arch))
475 .for_each(|(_, arch)| {
476 let batch_size = arch.len() / pool.parallelism() + 1;
478
479 for range in batches(arch.len(), batch_size) {
481 s.spawn(move |_s| {
482 for t in T::iter_range_mut(arch, range) {
483 f(t);
484 }
485 })
486 }
487 });
488 });
489 }
490 }
491
492 #[cfg(not(feature = "parallel"))]
493 pub fn par_for_each<'b>(&'b self, f: impl Fn(<T as QueryFragment>::Item<'a>) + 'b) {
494 self.iter().for_each(f);
495 }
496
497 #[cfg(not(feature = "parallel"))]
498 pub fn par_for_each_mut<'b>(&'b mut self, f: impl Fn(<T as QueryFragment>::ItemMut<'a>) + 'b) {
499 self.iter_mut().for_each(f);
500 }
501}
502
503#[allow(unused)]
504fn batches(len: usize, batch_size: usize) -> impl Iterator<Item = impl RangeBounds<usize> + Clone> {
505 (0..len / batch_size)
506 .map(move |i| {
507 let s = i * batch_size;
508 s..s + batch_size
509 })
510 .chain(std::iter::once((len - (len % batch_size))..len))
513}
514
515pub trait QueryFragment {
516 type ItemUnsafe<'a>;
517 type ItUnsafe<'a>: Iterator<Item = Self::ItemUnsafe<'a>>;
518 type Item<'a>;
519 type It<'a>: Iterator<Item = Self::Item<'a>>;
520 type ItemMut<'a>;
521 type ItMut<'a>: Iterator<Item = Self::ItemMut<'a>>;
522
523 unsafe fn iter_unsafe(archetype: &EntityTable) -> Self::ItUnsafe<'_>;
524 unsafe fn fetch_unsafe(
525 archetype: &EntityTable,
526 index: RowIndex,
527 ) -> Option<Self::ItemUnsafe<'_>>;
528 fn iter(archetype: &EntityTable) -> Self::It<'_>;
529 fn iter_mut(archetype: &EntityTable) -> Self::ItMut<'_>;
530 fn fetch(archetype: &EntityTable, index: RowIndex) -> Option<Self::Item<'_>>;
531 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>>;
532 fn types_mut(set: &mut HashSet<TypeId>);
533 fn types_const(set: &mut HashSet<TypeId>);
534 fn contains(archetype: &EntityTable) -> bool;
535 fn read_only() -> bool;
536 fn iter_range(archetype: &EntityTable, range: impl RangeBounds<usize> + Clone) -> Self::It<'_>;
537 fn iter_range_mut(
538 archetype: &EntityTable,
539 range: impl RangeBounds<usize> + Clone,
540 ) -> Self::ItMut<'_>;
541}
542
543pub struct Has<T>(PhantomData<T>);
571
572impl<T: Component> QueryFragment for Has<T> {
573 type ItemUnsafe<'a> = bool;
574 type ItUnsafe<'a> = Self::It<'a>;
575 type Item<'a> = bool;
576 type It<'a> = std::iter::Take<std::iter::Repeat<bool>>;
577 type ItemMut<'a> = bool;
578 type ItMut<'a> = Self::It<'a>;
579
580 unsafe fn iter_unsafe<'a>(archetype: &'a EntityTable) -> Self::ItUnsafe<'a> {
581 Self::iter(archetype)
582 }
583
584 unsafe fn fetch_unsafe(
585 archetype: &EntityTable,
586 index: RowIndex,
587 ) -> Option<Self::ItemUnsafe<'_>> {
588 Self::fetch(archetype, index)
589 }
590
591 fn iter<'a>(archetype: &'a EntityTable) -> Self::It<'a> {
592 std::iter::repeat(archetype.contains_column::<T>()).take(archetype.len())
593 }
594
595 fn iter_mut<'a>(archetype: &'a EntityTable) -> Self::ItMut<'a> {
596 Self::iter(archetype)
597 }
598
599 fn fetch(archetype: &EntityTable, _index: RowIndex) -> Option<Self::Item<'_>> {
600 Some(archetype.contains_column::<T>())
601 }
602
603 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>> {
604 Self::fetch(archetype, index)
605 }
606
607 fn contains(_archetype: &EntityTable) -> bool {
608 true
609 }
610
611 fn types_mut(_set: &mut HashSet<TypeId>) {
612 }
614
615 fn types_const(_set: &mut HashSet<TypeId>) {
616 }
619
620 fn read_only() -> bool {
621 true
622 }
623
624 fn iter_range(archetype: &EntityTable, range: impl RangeBounds<usize>) -> Self::It<'_> {
625 let len = archetype.entities.len();
626 let range = slice::range(range, ..len);
627 let len = range.len();
628 std::iter::repeat(archetype.contains_column::<T>()).take(len)
629 }
630
631 fn iter_range_mut(
632 archetype: &EntityTable,
633 range: impl RangeBounds<usize> + Clone,
634 ) -> Self::ItMut<'_> {
635 Self::iter_range(archetype, range)
636 }
637}
638
639impl QueryFragment for EntityId {
640 type ItemUnsafe<'a> = EntityId;
641 type ItUnsafe<'a> = std::iter::Copied<std::slice::Iter<'a, EntityId>>;
642 type Item<'a> = EntityId;
643 type It<'a> = std::iter::Copied<std::slice::Iter<'a, EntityId>>;
644 type ItemMut<'a> = EntityId;
645 type ItMut<'a> = std::iter::Copied<std::slice::Iter<'a, EntityId>>;
646
647 unsafe fn iter_unsafe<'a>(archetype: &'a EntityTable) -> Self::ItUnsafe<'a> {
648 archetype.entities.iter().copied()
649 }
650
651 unsafe fn fetch_unsafe(
652 archetype: &EntityTable,
653 index: RowIndex,
654 ) -> Option<Self::ItemUnsafe<'_>> {
655 archetype.entities.get(index as usize).copied()
656 }
657
658 fn iter<'a>(archetype: &'a EntityTable) -> Self::It<'a> {
659 archetype.entities.iter().copied()
660 }
661
662 fn iter_mut<'a>(archetype: &'a EntityTable) -> Self::ItMut<'a> {
663 Self::iter(archetype)
664 }
665
666 fn fetch(archetype: &EntityTable, index: RowIndex) -> Option<Self::Item<'_>> {
667 archetype.entities.get(index as usize).copied()
668 }
669
670 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>> {
671 Self::fetch(archetype, index)
672 }
673
674 fn contains(_archetype: &EntityTable) -> bool {
675 true
676 }
677
678 fn types_mut(_set: &mut HashSet<TypeId>) {
679 }
681
682 fn types_const(_set: &mut HashSet<TypeId>) {
683 }
686
687 fn read_only() -> bool {
688 true
689 }
690
691 fn iter_range(archetype: &EntityTable, range: impl RangeBounds<usize>) -> Self::It<'_> {
692 let len = archetype.entities.len();
693 let range = slice::range(range, ..len);
694 archetype.entities[range].iter().copied()
695 }
696
697 fn iter_range_mut(
698 archetype: &EntityTable,
699 range: impl RangeBounds<usize> + Clone,
700 ) -> Self::ItMut<'_> {
701 Self::iter_range(archetype, range)
702 }
703}
704
705impl QueryFragment for ArchetypeHash {
706 type ItemUnsafe<'a> = ArchetypeHash;
707 type Item<'a> = ArchetypeHash;
708 type ItemMut<'a> = ArchetypeHash;
709 type It<'a> = Box<dyn Iterator<Item = Self::Item<'a>> + 'a>;
710 type ItUnsafe<'a> = Self::It<'a>;
711 type ItMut<'a> = Self::It<'a>;
712
713 unsafe fn iter_unsafe<'a>(archetype: &'a EntityTable) -> Self::ItUnsafe<'a> {
714 Self::iter(archetype)
715 }
716
717 unsafe fn fetch_unsafe(
718 archetype: &EntityTable,
719 index: RowIndex,
720 ) -> Option<Self::ItemUnsafe<'_>> {
721 Self::fetch(archetype, index)
722 }
723
724 fn iter<'a>(archetype: &'a EntityTable) -> Self::It<'a> {
725 let hash = archetype.ty;
726 Box::new((0..archetype.rows).map(move |_| ArchetypeHash(hash)))
727 }
728
729 fn iter_mut<'a>(archetype: &'a EntityTable) -> Self::ItMut<'a> {
730 Self::iter(archetype)
731 }
732
733 fn fetch(archetype: &EntityTable, index: RowIndex) -> Option<Self::Item<'_>> {
734 archetype
735 .entities
736 .get(index as usize)
737 .map(|_| ArchetypeHash(archetype.ty))
738 }
739
740 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>> {
741 Self::fetch(archetype, index)
742 }
743
744 fn contains(_archetype: &EntityTable) -> bool {
745 true
746 }
747
748 fn types_mut(_set: &mut HashSet<TypeId>) {
749 }
751
752 fn types_const(_set: &mut HashSet<TypeId>) {
753 }
755
756 fn read_only() -> bool {
757 true
758 }
759
760 fn iter_range(archetype: &EntityTable, range: impl RangeBounds<usize>) -> Self::It<'_> {
761 let len = archetype.entities.len();
762 let range = slice::range(range, ..len);
763 let hash = archetype.ty;
764 Box::new(
765 archetype.entities[range]
766 .iter()
767 .map(move |_| ArchetypeHash(hash)),
768 )
769 }
770
771 fn iter_range_mut(
772 archetype: &EntityTable,
773 range: impl RangeBounds<usize> + Clone,
774 ) -> Self::ItMut<'_> {
775 Self::iter_range(archetype, range)
776 }
777}
778
779impl<'a, T: Component> QueryFragment for Option<&'a T> {
783 type ItemUnsafe<'b> = Option<*mut T>;
784 type ItUnsafe<'b> = Box<dyn Iterator<Item = Self::ItemUnsafe<'b>> + 'b>;
785 type Item<'b> = Option<&'b T>;
786 type It<'b> = Box<dyn Iterator<Item = Self::Item<'b>> + 'b>;
787 type ItemMut<'b> = Option<&'b T>;
788 type ItMut<'b> = Box<dyn Iterator<Item = Self::ItemMut<'b>> + 'b>;
789
790 fn iter(archetype: &EntityTable) -> Self::It<'_> {
791 match archetype.components.get(&TypeId::of::<T>()) {
792 Some(columns) => {
793 Box::new(unsafe { (&*columns.get()).as_slice::<T>().iter() }.map(Some))
794 }
795 None => Box::new((0..archetype.rows).map(|_| None)),
796 }
797 }
798
799 fn iter_mut(archetype: &EntityTable) -> Self::ItMut<'_> {
800 <Self as QueryFragment>::iter(archetype)
801 }
802
803 unsafe fn iter_unsafe(archetype: &EntityTable) -> Self::ItUnsafe<'_> {
804 match archetype.components.get(&TypeId::of::<T>()) {
805 Some(columns) => Box::new(
806 unsafe { (&mut *columns.get()).as_slice_mut::<T>().iter_mut() }
807 .map(|x| x as *mut _)
808 .map(Some),
809 ),
810 None => Box::new((0..archetype.rows).map(|_| None)),
811 }
812 }
813
814 fn fetch(archetype: &EntityTable, index: RowIndex) -> Option<Self::Item<'_>> {
815 Some(archetype.get_component::<T>(index))
816 }
817
818 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>> {
819 Self::fetch(archetype, index)
820 }
821
822 unsafe fn fetch_unsafe(
823 archetype: &EntityTable,
824 index: RowIndex,
825 ) -> Option<Self::ItemUnsafe<'_>> {
826 unsafe { Some(archetype.get_component_mut::<T>(index).map(|x| x as *mut _)) }
827 }
828
829 fn types_mut(_set: &mut HashSet<TypeId>) {
830 }
832
833 fn types_const(set: &mut HashSet<TypeId>) {
834 set.insert(TypeId::of::<T>());
835 }
836
837 fn contains(_archetype: &EntityTable) -> bool {
838 true
839 }
840
841 fn read_only() -> bool {
842 true
843 }
844
845 fn iter_range(archetype: &EntityTable, range: impl RangeBounds<usize>) -> Self::It<'_> {
846 let len = archetype.len();
847 let range = slice::range(range, ..len);
848 match archetype.components.get(&TypeId::of::<T>()) {
849 Some(columns) => unsafe {
850 let col = (&*columns.get()).as_slice::<T>();
851 Box::new(col[range].iter().map(Some))
852 },
853 None => Box::new(range.into_iter().map(|_| None)),
854 }
855 }
856
857 fn iter_range_mut(
858 archetype: &EntityTable,
859 range: impl RangeBounds<usize> + Clone,
860 ) -> Self::ItMut<'_> {
861 Self::iter_range(archetype, range)
862 }
863}
864
865impl<'a, T: Component> QueryFragment for Option<&'a mut T> {
866 type ItemUnsafe<'b> = Option<*mut T>;
867 type ItUnsafe<'b> = Box<dyn Iterator<Item = Self::ItemUnsafe<'b>> + 'b>;
868 type Item<'b> = Option<&'b T>;
869 type It<'b> = Box<dyn Iterator<Item = Self::Item<'b>> + 'b>;
870 type ItemMut<'b> = Option<&'b mut T>;
871 type ItMut<'b> = Box<dyn Iterator<Item = Self::ItemMut<'b>> + 'b>;
872
873 fn iter(archetype: &EntityTable) -> Self::It<'_> {
874 match archetype.components.get(&TypeId::of::<T>()) {
875 Some(columns) => {
876 Box::new(unsafe { (&*columns.get()).as_slice::<T>().iter() }.map(Some))
877 }
878 None => Box::new((0..archetype.rows).map(|_| None)),
879 }
880 }
881
882 fn iter_mut(archetype: &EntityTable) -> Self::ItMut<'_> {
883 match archetype.components.get(&TypeId::of::<T>()) {
884 Some(columns) => {
885 Box::new(unsafe { (&mut *columns.get()).as_slice_mut::<T>().iter_mut() }.map(Some))
886 }
887 None => Box::new((0..archetype.rows).map(|_| None)),
888 }
889 }
890
891 unsafe fn iter_unsafe(archetype: &EntityTable) -> Self::ItUnsafe<'_> {
892 match archetype.components.get(&TypeId::of::<T>()) {
893 Some(columns) => Box::new(
894 unsafe { (&mut *columns.get()).as_slice_mut::<T>().iter_mut() }
895 .map(|x| x as *mut _)
896 .map(Some),
897 ),
898 None => Box::new((0..archetype.rows).map(|_| None)),
899 }
900 }
901
902 fn fetch(archetype: &EntityTable, index: RowIndex) -> Option<Self::Item<'_>> {
903 Some(archetype.get_component::<T>(index))
904 }
905
906 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>> {
907 Some(unsafe { archetype.get_component_mut::<T>(index) })
908 }
909
910 unsafe fn fetch_unsafe(
911 archetype: &EntityTable,
912 index: RowIndex,
913 ) -> Option<Self::ItemUnsafe<'_>> {
914 unsafe { Some(archetype.get_component_mut::<T>(index).map(|x| x as *mut _)) }
915 }
916
917 fn types_mut(set: &mut HashSet<TypeId>) {
918 set.insert(TypeId::of::<T>());
919 }
920
921 fn types_const(_set: &mut HashSet<TypeId>) {
922 }
924
925 fn contains(_archetype: &EntityTable) -> bool {
926 true
927 }
928
929 fn read_only() -> bool {
930 false
931 }
932
933 fn iter_range(archetype: &EntityTable, range: impl RangeBounds<usize>) -> Self::It<'_> {
934 let len = archetype.len();
935 let range = slice::range(range, ..len);
936 match archetype.components.get(&TypeId::of::<T>()) {
937 Some(columns) => unsafe {
938 let col = (&*columns.get()).as_slice::<T>();
939 Box::new(col[range].iter().map(Some))
940 },
941 None => Box::new(range.into_iter().map(|_| None)),
942 }
943 }
944
945 fn iter_range_mut(
946 archetype: &EntityTable,
947 range: impl RangeBounds<usize> + Clone,
948 ) -> Self::ItMut<'_> {
949 let len = archetype.len();
950 let range = slice::range(range, ..len);
951 match archetype.components.get(&TypeId::of::<T>()) {
952 Some(columns) => unsafe {
953 let col = (&mut *columns.get()).as_slice_mut::<T>();
954 Box::new(col[range].iter_mut().map(Some))
955 },
956 None => Box::new(range.into_iter().map(|_| None)),
957 }
958 }
959}
960
961impl<'a, T: Component> QueryFragment for &'a T {
962 type ItemUnsafe<'b> = *mut T;
963 type ItUnsafe<'b> = Box<dyn Iterator<Item = Self::ItemUnsafe<'b>>>;
964 type Item<'b> = &'b T;
965 type It<'b> = std::iter::Flatten<std::option::IntoIter<std::slice::Iter<'b, T>>>;
966 type ItemMut<'b> = &'b T;
967 type ItMut<'b> = std::iter::Flatten<std::option::IntoIter<std::slice::Iter<'b, T>>>;
968
969 fn fetch(archetype: &EntityTable, index: RowIndex) -> Option<Self::Item<'_>> {
970 archetype.get_component::<T>(index)
971 }
972
973 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>> {
974 Self::fetch(archetype, index)
975 }
976
977 unsafe fn fetch_unsafe(
978 archetype: &EntityTable,
979 index: RowIndex,
980 ) -> Option<Self::ItemUnsafe<'_>> {
981 unsafe { archetype.get_component_mut::<T>(index).map(|x| x as *mut _) }
982 }
983
984 fn contains(archetype: &EntityTable) -> bool {
985 archetype.contains_column::<T>()
986 }
987
988 fn types_mut(_set: &mut HashSet<TypeId>) {
989 }
991
992 fn types_const(set: &mut HashSet<TypeId>) {
993 set.insert(TypeId::of::<T>());
994 }
995
996 fn iter(archetype: &EntityTable) -> Self::It<'_> {
997 archetype
998 .components
999 .get(&TypeId::of::<T>())
1000 .map(|columns| unsafe { (&*columns.get()).as_slice::<T>().iter() })
1001 .into_iter()
1002 .flatten()
1003 }
1004
1005 fn iter_mut(archetype: &EntityTable) -> Self::ItMut<'_> {
1006 Self::iter(archetype)
1007 }
1008
1009 unsafe fn iter_unsafe(archetype: &EntityTable) -> Self::ItUnsafe<'_> {
1010 Box::new(
1011 archetype
1012 .components
1013 .get(&TypeId::of::<T>())
1014 .map(|columns| unsafe {
1015 let slice = (&mut *columns.get()).as_slice_mut::<T>();
1016 let ptr = slice.as_mut_ptr();
1017 let len = slice.len();
1018 (0..len).map(move |i| ptr.add(i))
1019 })
1020 .into_iter()
1021 .flatten(),
1022 )
1023 }
1024
1025 fn read_only() -> bool {
1026 true
1027 }
1028
1029 fn iter_range(archetype: &EntityTable, range: impl RangeBounds<usize>) -> Self::ItMut<'_> {
1030 archetype
1031 .components
1032 .get(&TypeId::of::<T>())
1033 .map(|columns| unsafe {
1034 let col = (&*columns.get()).as_slice::<T>();
1035 let len = col.len();
1036 let range = slice::range(range, ..len);
1037 col[range].iter()
1038 })
1039 .into_iter()
1040 .flatten()
1041 }
1042
1043 fn iter_range_mut(
1044 archetype: &EntityTable,
1045 range: impl RangeBounds<usize> + Clone,
1046 ) -> Self::ItMut<'_> {
1047 Self::iter_range(archetype, range)
1048 }
1049}
1050
1051impl<'a, T: Component> QueryFragment for &'a mut T {
1052 type ItemUnsafe<'b> = *mut T;
1053 type ItUnsafe<'b> = Box<dyn Iterator<Item = *mut T>>;
1054 type Item<'b> = &'b T;
1055 type It<'b> = std::iter::Flatten<std::option::IntoIter<std::slice::Iter<'b, T>>>;
1056 type ItemMut<'b> = &'b mut T;
1057 type ItMut<'b> = std::iter::Flatten<std::option::IntoIter<std::slice::IterMut<'b, T>>>;
1058
1059 fn iter(archetype: &EntityTable) -> Self::It<'_> {
1060 archetype
1061 .components
1062 .get(&TypeId::of::<T>())
1063 .map(|columns| unsafe { (&*columns.get()).as_slice::<T>().iter() })
1064 .into_iter()
1065 .flatten()
1066 }
1067
1068 fn iter_mut(archetype: &EntityTable) -> Self::ItMut<'_> {
1069 archetype
1070 .components
1071 .get(&TypeId::of::<T>())
1072 .map(|columns| unsafe { (&mut *columns.get()).as_slice_mut::<T>().iter_mut() })
1073 .into_iter()
1074 .flatten()
1075 }
1076
1077 unsafe fn iter_unsafe(archetype: &EntityTable) -> Self::ItUnsafe<'_> {
1078 Box::new(
1079 archetype
1080 .components
1081 .get(&TypeId::of::<T>())
1082 .map(|columns| unsafe {
1083 let slice = (&mut *columns.get()).as_slice_mut::<T>();
1084 let ptr = slice.as_mut_ptr();
1085 let len = slice.len();
1086 (0..len).map(move |i| ptr.add(i))
1087 })
1088 .into_iter()
1089 .flatten(),
1090 )
1091 }
1092
1093 fn fetch(archetype: &EntityTable, index: RowIndex) -> Option<Self::Item<'_>> {
1094 archetype.get_component::<T>(index)
1095 }
1096
1097 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>> {
1098 unsafe { archetype.get_component_mut::<T>(index) }
1099 }
1100
1101 unsafe fn fetch_unsafe(
1102 archetype: &EntityTable,
1103 index: RowIndex,
1104 ) -> Option<Self::ItemUnsafe<'_>> {
1105 unsafe { archetype.get_component_mut::<T>(index).map(|x| x as *mut _) }
1106 }
1107
1108 fn contains(archetype: &EntityTable) -> bool {
1109 archetype.contains_column::<T>()
1110 }
1111
1112 fn types_mut(set: &mut HashSet<TypeId>) {
1113 let ty = TypeId::of::<T>();
1114 debug_assert!(!set.contains(&ty), "A query may only borrow a type once");
1115 set.insert(ty);
1116 }
1117
1118 fn types_const(_set: &mut HashSet<TypeId>) {
1119 }
1121
1122 fn read_only() -> bool {
1123 false
1124 }
1125
1126 fn iter_range(archetype: &EntityTable, range: impl RangeBounds<usize>) -> Self::It<'_> {
1127 archetype
1128 .components
1129 .get(&TypeId::of::<T>())
1130 .map(|columns| unsafe {
1131 let col = (&mut *columns.get()).as_slice::<T>();
1132 let len = col.len();
1133 let range = slice::range(range, ..len);
1134 col[range].iter()
1135 })
1136 .into_iter()
1137 .flatten()
1138 }
1139
1140 fn iter_range_mut(
1141 archetype: &EntityTable,
1142 range: impl RangeBounds<usize> + Clone,
1143 ) -> Self::ItMut<'_> {
1144 archetype
1145 .components
1146 .get(&TypeId::of::<T>())
1147 .map(|columns| unsafe {
1148 let col = (&mut *columns.get()).as_slice_mut::<T>();
1149 let len = col.len();
1150 let range = slice::range(range, ..len);
1151 col[range].iter_mut()
1152 })
1153 .into_iter()
1154 .flatten()
1155 }
1156}
1157
1158pub struct TupleIterator<Inner>(Inner);
1162
1163unsafe impl<Inner> Send for TupleIterator<Inner> {}
1164unsafe impl<Inner> Sync for TupleIterator<Inner> {}
1165
1166macro_rules! impl_tuple {
1167 ($($idx: tt : $t: ident),+ $(,)?) => {
1168 impl<$($t,)+> Iterator for TupleIterator<
1169 ($($t),+)
1170 >
1171 where
1172 $( $t: Iterator ),+
1173 {
1174 type Item = ( $( $t::Item ),* );
1175
1176 fn next(&mut self) -> Option<Self::Item> {
1177 Some((
1178 $(
1179 self.0.$idx.next()?
1182 ),+
1183 ))
1184 }
1185 }
1186
1187 impl<$($t,)+> QueryFragment for ($($t,)+)
1188 where
1189 $(
1190 $t: QueryFragment,
1191 )+
1192 {
1193 type ItemUnsafe<'a> = ($(<$t as QueryFragment>::ItemUnsafe<'a>),+);
1194 type ItUnsafe<'a> = TupleIterator<($(<$t as QueryFragment>::ItUnsafe<'a>,)+)>;
1195 type Item<'a> = ($(<$t as QueryFragment>::Item<'a>),+);
1196 type It<'a> = TupleIterator<($(<$t as QueryFragment>::It<'a>,)+)>;
1197 type ItemMut<'a> = ($(<$t as QueryFragment>::ItemMut<'a>),+);
1198 type ItMut<'a> = TupleIterator<($(<$t as QueryFragment>::ItMut<'a>,)+)>;
1199
1200 fn iter(archetype: &EntityTable) -> Self::It<'_>
1201 {
1202 TupleIterator(($( $t::iter(archetype) ),+))
1203 }
1204
1205 fn iter_mut(archetype: &EntityTable) -> Self::ItMut<'_>
1206 {
1207 TupleIterator(($( $t::iter_mut(archetype) ),+))
1208 }
1209
1210 fn iter_range(
1211 archetype: &EntityTable,
1212 range: impl RangeBounds<usize> + Clone,
1213 ) -> Self::It<'_> {
1214 TupleIterator(($( $t::iter_range(archetype, range.clone()) ),+))
1215 }
1216
1217 fn iter_range_mut(
1218 archetype: &EntityTable,
1219 range: impl RangeBounds<usize> + Clone,
1220 ) -> Self::ItMut<'_> {
1221 TupleIterator(($( $t::iter_range_mut(archetype, range.clone()) ),+))
1222 }
1223
1224 unsafe fn iter_unsafe(archetype: &EntityTable) -> Self::ItUnsafe<'_>
1225 {
1226 unsafe {
1227 TupleIterator(($( $t::iter_unsafe(archetype) ),+))
1228 }
1229 }
1230
1231 fn fetch(archetype: &EntityTable, index: RowIndex) -> Option<Self::Item<'_>> {
1232 Some((
1233 $(
1234 $t::fetch(archetype, index)?,
1235 )*
1236 ))
1237 }
1238
1239 fn fetch_mut(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemMut<'_>> {
1240 Some((
1241 $(
1242 $t::fetch_mut(archetype, index)?,
1243 )*
1244 ))
1245 }
1246
1247 unsafe fn fetch_unsafe(archetype: &EntityTable, index: RowIndex) -> Option<Self::ItemUnsafe<'_>> {
1248 unsafe {
1249 Some((
1250 $(
1251 $t::fetch_unsafe(archetype, index)?,
1252 )*
1253 ))
1254 }
1255 }
1256
1257 fn contains(archetype: &EntityTable) -> bool {
1258 $(
1259 $t::contains(archetype)
1260 )&&*
1261 }
1262
1263 fn types_mut(set: &mut HashSet<TypeId>) {
1264 $(<$t as QueryFragment>::types_mut(set));+
1265 }
1266
1267 fn types_const(set: &mut HashSet<TypeId>) {
1268 $(<$t as QueryFragment>::types_const(set));+
1269 }
1270
1271 fn read_only() -> bool {
1272 $(<$t as QueryFragment>::read_only())&&+
1273 }
1274 }
1275
1276 unsafe impl<'a, $($t,)+> WorldQuery<'a> for ($($t,)+)
1277 where
1278 $(
1279 $t: WorldQuery<'a>,
1280 )+
1281 {
1282 fn new(db: &'a World, system_idx: usize) -> Self {
1283 (
1284 $(
1285 <$t as WorldQuery>::new(db, system_idx),
1286 )+
1287 )
1288 }
1289
1290 fn exclusive() -> bool {
1291 $(<$t as WorldQuery>::exclusive())||+
1292 }
1293
1294 fn read_only() -> bool {
1295 $(<$t as WorldQuery>::read_only())&&+
1296 }
1297
1298 fn resources_const(_set: &mut HashSet<TypeId>) {
1299 $(<$t as WorldQuery>::resources_const(_set));+
1300 }
1301 fn resources_mut(_set: &mut HashSet<TypeId>) {
1302 $(<$t as WorldQuery>::resources_mut(_set));+
1303 }
1304 fn components_const(_set: &mut HashSet<TypeId>) {
1305 $(<$t as WorldQuery>::components_const(_set));+
1306 }
1307 fn components_mut(_set: &mut HashSet<TypeId>) {
1308 $(<$t as WorldQuery>::components_mut(_set));+
1309 }
1310 }
1311 };
1312}
1313
1314impl_tuple!(0: T0, 1: T1);
1315impl_tuple!(0: T0, 1: T1, 2: T2);
1316impl_tuple!(0: T0, 1: T1, 2: T2, 3: T3);
1317impl_tuple!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4);
1318impl_tuple!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5);
1319impl_tuple!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6);
1320impl_tuple!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7);
1321impl_tuple!(
1322 0: T0,
1323 1: T1,
1324 2: T2,
1325 3: T3,
1326 4: T4,
1327 5: T5,
1328 6: T6,
1329 7: T7,
1330 8: T8
1331);
1332impl_tuple!(
1333 0: T0,
1334 1: T1,
1335 2: T2,
1336 3: T3,
1337 4: T4,
1338 5: T5,
1339 6: T6,
1340 7: T7,
1341 8: T8,
1342 9: T9
1343);
1344impl_tuple!(
1345 0: T0,
1346 1: T1,
1347 2: T2,
1348 3: T3,
1349 4: T4,
1350 5: T5,
1351 6: T6,
1352 7: T7,
1353 8: T8,
1354 9: T9,
1355 10: T10
1356);
1357impl_tuple!(
1358 0: T0,
1359 1: T1,
1360 2: T2,
1361 3: T3,
1362 4: T4,
1363 5: T5,
1364 6: T6,
1365 7: T7,
1366 8: T8,
1367 9: T9,
1368 10: T10,
1369 11: T11
1370);
1371impl_tuple!(
1372 0: T0,
1373 1: T1,
1374 2: T2,
1375 3: T3,
1376 4: T4,
1377 5: T5,
1378 6: T6,
1379 7: T7,
1380 8: T8,
1381 9: T9,
1382 10: T10,
1383 11: T11,
1384 12: T12
1385);
1386impl_tuple!(
1387 0: T0,
1388 1: T1,
1389 2: T2,
1390 3: T3,
1391 4: T4,
1392 5: T5,
1393 6: T6,
1394 7: T7,
1395 8: T8,
1396 9: T9,
1397 10: T10,
1398 11: T11,
1399 12: T12,
1400 13: T13
1401);
1402impl_tuple!(
1403 0: T0,
1404 1: T1,
1405 2: T2,
1406 3: T3,
1407 4: T4,
1408 5: T5,
1409 6: T6,
1410 7: T7,
1411 8: T8,
1412 9: T9,
1413 10: T10,
1414 11: T11,
1415 12: T12,
1416 13: T13,
1417 14: T14
1418);
1419impl_tuple!(
1420 0: T0,
1421 1: T1,
1422 2: T2,
1423 3: T3,
1424 4: T4,
1425 5: T5,
1426 6: T6,
1427 7: T7,
1428 8: T8,
1429 9: T9,
1430 10: T10,
1431 11: T11,
1432 12: T12,
1433 13: T13,
1434 14: T14,
1435 15: T15
1436);