1use alloc::{
2 boxed::Box,
3 collections::{btree_map, btree_set},
4 rc::Rc,
5};
6use bevy_platform::collections::HashSet;
7
8use core::{
9 array,
10 cmp::Ordering,
11 fmt::{Debug, Formatter},
12 hash::{BuildHasher, Hash},
13 iter::{self, FusedIterator, Product, Sum},
14 option, ptr, result,
15};
16
17use super::{Entity, UniqueEntityEquivalentSlice};
18
19use bevy_platform::sync::Arc;
20
21pub trait ContainsEntity {
29 fn entity(&self) -> Entity;
31}
32
33pub unsafe trait EntityEquivalent: ContainsEntity + Eq {}
70
71impl ContainsEntity for Entity {
72 fn entity(&self) -> Entity {
73 *self
74 }
75}
76
77unsafe impl EntityEquivalent for Entity {}
80
81impl<T: ContainsEntity> ContainsEntity for &T {
82 fn entity(&self) -> Entity {
83 (**self).entity()
84 }
85}
86
87unsafe impl<T: EntityEquivalent> EntityEquivalent for &T {}
92
93impl<T: ContainsEntity> ContainsEntity for &mut T {
94 fn entity(&self) -> Entity {
95 (**self).entity()
96 }
97}
98
99unsafe impl<T: EntityEquivalent> EntityEquivalent for &mut T {}
104
105impl<T: ContainsEntity> ContainsEntity for Box<T> {
106 fn entity(&self) -> Entity {
107 (**self).entity()
108 }
109}
110
111unsafe impl<T: EntityEquivalent> EntityEquivalent for Box<T> {}
116
117impl<T: ContainsEntity> ContainsEntity for Rc<T> {
118 fn entity(&self) -> Entity {
119 (**self).entity()
120 }
121}
122
123unsafe impl<T: EntityEquivalent> EntityEquivalent for Rc<T> {}
128
129impl<T: ContainsEntity> ContainsEntity for Arc<T> {
130 fn entity(&self) -> Entity {
131 (**self).entity()
132 }
133}
134
135unsafe impl<T: EntityEquivalent> EntityEquivalent for Arc<T> {}
140
141pub trait EntitySet: IntoIterator<IntoIter: EntitySetIterator> {}
160
161impl<T: IntoIterator<IntoIter: EntitySetIterator>> EntitySet for T {}
162
163pub unsafe trait EntitySetIterator: Iterator<Item: EntityEquivalent> {
172 fn collect_set<B: FromEntitySetIterator<Self::Item>>(self) -> B
180 where
181 Self: Sized,
182 {
183 FromEntitySetIterator::from_entity_set_iter(self)
184 }
185}
186
187unsafe impl<K: EntityEquivalent, V> EntitySetIterator for btree_map::Keys<'_, K, V> {}
191
192unsafe impl<K: EntityEquivalent, V> EntitySetIterator for btree_map::IntoKeys<K, V> {}
196
197unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::Range<'_, T> {}
202
203unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Intersection<'_, T> {}
208
209unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Union<'_, T> {}
214
215unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Difference<'_, T> {}
220
221unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::SymmetricDifference<'_, T> {}
226
227unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::Iter<'_, T> {}
231
232unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::IntoIter<T> {}
236
237unsafe impl<T: EntityEquivalent> EntitySetIterator for option::Iter<'_, T> {}
239
240unsafe impl<T: EntityEquivalent> EntitySetIterator for option::IntoIter<T> {}
245
246unsafe impl<T: EntityEquivalent> EntitySetIterator for result::Iter<'_, T> {}
248
249unsafe impl<T: EntityEquivalent> EntitySetIterator for result::IntoIter<T> {}
254
255unsafe impl<T: EntityEquivalent> EntitySetIterator for array::IntoIter<T, 1> {}
257
258unsafe impl<T: EntityEquivalent> EntitySetIterator for array::IntoIter<T, 0> {}
260
261unsafe impl<T: EntityEquivalent, F: FnOnce() -> T> EntitySetIterator for iter::OnceWith<F> {}
263
264unsafe impl<T: EntityEquivalent> EntitySetIterator for iter::Once<T> {}
266
267unsafe impl<T: EntityEquivalent> EntitySetIterator for iter::Empty<T> {}
269
270unsafe impl<I: EntitySetIterator + ?Sized> EntitySetIterator for &mut I {}
272
273unsafe impl<I: EntitySetIterator + ?Sized> EntitySetIterator for Box<I> {}
275
276unsafe impl<'a, T: 'a + EntityEquivalent + Copy, I: EntitySetIterator<Item = &'a T>>
278 EntitySetIterator for iter::Copied<I>
279{
280}
281
282unsafe impl<'a, T: 'a + EntityEquivalent + Clone, I: EntitySetIterator<Item = &'a T>>
284 EntitySetIterator for iter::Cloned<I>
285{
286}
287
288unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
290 for iter::Filter<I, P>
291{
292}
293
294unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Fuse<I> {}
296
297unsafe impl<I: EntitySetIterator, F: FnMut(&<I as Iterator>::Item)> EntitySetIterator
301 for iter::Inspect<I, F>
302{
303}
304
305unsafe impl<I: DoubleEndedIterator + EntitySetIterator> EntitySetIterator for iter::Rev<I> {}
307
308unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Skip<I> {}
310
311unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
313 for iter::SkipWhile<I, P>
314{
315}
316
317unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Take<I> {}
319
320unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
322 for iter::TakeWhile<I, P>
323{
324}
325
326unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::StepBy<I> {}
328
329pub trait FromEntitySetIterator<A: EntityEquivalent>: FromIterator<A> {
339 fn from_entity_set_iter<T: EntitySet<Item = A>>(set_iter: T) -> Self;
341}
342
343impl<T: EntityEquivalent + Hash, S: BuildHasher + Default> FromEntitySetIterator<T>
344 for HashSet<T, S>
345{
346 #[inline]
347 fn from_entity_set_iter<I: EntitySet<Item = T>>(set_iter: I) -> Self {
348 let iter = set_iter.into_iter();
349 let set = HashSet::with_capacity_and_hasher(iter.size_hint().0, S::default());
350 iter.fold(set, |mut set, e| {
351 unsafe {
353 set.insert_unique_unchecked(e);
354 }
355 set
356 })
357 }
358}
359
360#[repr(transparent)]
364pub struct UniqueEntityIter<I: Iterator<Item: EntityEquivalent>> {
365 iter: I,
366}
367
368impl<I: EntitySetIterator> UniqueEntityIter<I> {
369 #[inline]
371 pub const fn from_entity_set_iter(iter: I) -> Self {
372 unsafe { Self::from_iter_unchecked(iter) }
374 }
375}
376
377impl<I: Iterator<Item: EntityEquivalent>> UniqueEntityIter<I> {
378 #[inline]
384 pub const unsafe fn from_iter_unchecked(iter: I) -> Self {
385 Self { iter }
386 }
387
388 #[inline]
394 pub const unsafe fn from_iter_ref_unchecked(iter: &I) -> &Self {
395 unsafe { &*ptr::from_ref(iter).cast() }
397 }
398
399 #[inline]
405 pub const unsafe fn from_iter_mut_unchecked(iter: &mut I) -> &mut Self {
406 unsafe { &mut *ptr::from_mut(iter).cast() }
408 }
409
410 pub fn into_inner(self) -> I {
412 self.iter
413 }
414
415 pub const fn as_inner(&self) -> &I {
417 &self.iter
418 }
419
420 pub const unsafe fn as_mut_inner(&mut self) -> &mut I {
427 &mut self.iter
428 }
429}
430
431impl<I: Iterator<Item: EntityEquivalent>> Iterator for UniqueEntityIter<I> {
442 type Item = I::Item;
443
444 fn next(&mut self) -> Option<Self::Item> {
445 self.iter.next()
446 }
447
448 fn size_hint(&self) -> (usize, Option<usize>) {
449 self.iter.size_hint()
450 }
451
452 fn count(self) -> usize {
453 self.iter.count()
454 }
455
456 fn last(self) -> Option<Self::Item> {
457 self.iter.last()
458 }
459
460 fn nth(&mut self, n: usize) -> Option<Self::Item> {
461 self.iter.nth(n)
462 }
463
464 fn for_each<F>(self, f: F)
465 where
466 Self: Sized,
467 F: FnMut(Self::Item),
468 {
469 self.iter.for_each(f);
470 }
471
472 fn collect<B: FromIterator<Self::Item>>(self) -> B
473 where
474 Self: Sized,
475 {
476 self.iter.collect()
477 }
478
479 fn partition<B, F>(self, f: F) -> (B, B)
480 where
481 Self: Sized,
482 B: Default + Extend<Self::Item>,
483 F: FnMut(&Self::Item) -> bool,
484 {
485 self.iter.partition(f)
486 }
487
488 fn fold<B, F>(self, init: B, f: F) -> B
489 where
490 Self: Sized,
491 F: FnMut(B, Self::Item) -> B,
492 {
493 self.iter.fold(init, f)
494 }
495
496 fn reduce<F>(self, f: F) -> Option<Self::Item>
497 where
498 Self: Sized,
499 F: FnMut(Self::Item, Self::Item) -> Self::Item,
500 {
501 self.iter.reduce(f)
502 }
503
504 fn all<F>(&mut self, f: F) -> bool
505 where
506 Self: Sized,
507 F: FnMut(Self::Item) -> bool,
508 {
509 self.iter.all(f)
510 }
511
512 fn any<F>(&mut self, f: F) -> bool
513 where
514 Self: Sized,
515 F: FnMut(Self::Item) -> bool,
516 {
517 self.iter.any(f)
518 }
519
520 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
521 where
522 Self: Sized,
523 P: FnMut(&Self::Item) -> bool,
524 {
525 self.iter.find(predicate)
526 }
527
528 fn find_map<B, F>(&mut self, f: F) -> Option<B>
529 where
530 Self: Sized,
531 F: FnMut(Self::Item) -> Option<B>,
532 {
533 self.iter.find_map(f)
534 }
535
536 fn position<P>(&mut self, predicate: P) -> Option<usize>
537 where
538 Self: Sized,
539 P: FnMut(Self::Item) -> bool,
540 {
541 self.iter.position(predicate)
542 }
543
544 fn max(self) -> Option<Self::Item>
545 where
546 Self: Sized,
547 Self::Item: Ord,
548 {
549 self.iter.max()
550 }
551
552 fn min(self) -> Option<Self::Item>
553 where
554 Self: Sized,
555 Self::Item: Ord,
556 {
557 self.iter.min()
558 }
559
560 fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
561 where
562 Self: Sized,
563 F: FnMut(&Self::Item) -> B,
564 {
565 self.iter.max_by_key(f)
566 }
567
568 fn max_by<F>(self, compare: F) -> Option<Self::Item>
569 where
570 Self: Sized,
571 F: FnMut(&Self::Item, &Self::Item) -> Ordering,
572 {
573 self.iter.max_by(compare)
574 }
575
576 fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
577 where
578 Self: Sized,
579 F: FnMut(&Self::Item) -> B,
580 {
581 self.iter.min_by_key(f)
582 }
583
584 fn min_by<F>(self, compare: F) -> Option<Self::Item>
585 where
586 Self: Sized,
587 F: FnMut(&Self::Item, &Self::Item) -> Ordering,
588 {
589 self.iter.min_by(compare)
590 }
591
592 fn sum<S>(self) -> S
593 where
594 Self: Sized,
595 S: Sum<Self::Item>,
596 {
597 self.iter.sum()
598 }
599
600 fn product<P>(self) -> P
601 where
602 Self: Sized,
603 P: Product<Self::Item>,
604 {
605 self.iter.product()
606 }
607
608 fn cmp<O>(self, other: O) -> Ordering
609 where
610 O: IntoIterator<Item = Self::Item>,
611 Self::Item: Ord,
612 Self: Sized,
613 {
614 self.iter.cmp(other)
615 }
616
617 fn partial_cmp<O>(self, other: O) -> Option<Ordering>
618 where
619 O: IntoIterator,
620 Self::Item: PartialOrd<O::Item>,
621 Self: Sized,
622 {
623 self.iter.partial_cmp(other)
624 }
625
626 fn eq<O>(self, other: O) -> bool
627 where
628 O: IntoIterator,
629 Self::Item: PartialEq<O::Item>,
630 Self: Sized,
631 {
632 self.iter.eq(other)
633 }
634
635 fn lt<O>(self, other: O) -> bool
636 where
637 O: IntoIterator,
638 Self::Item: PartialOrd<O::Item>,
639 Self: Sized,
640 {
641 self.iter.lt(other)
642 }
643
644 fn le<O>(self, other: O) -> bool
645 where
646 O: IntoIterator,
647 Self::Item: PartialOrd<O::Item>,
648 Self: Sized,
649 {
650 self.iter.le(other)
651 }
652
653 fn gt<O>(self, other: O) -> bool
654 where
655 O: IntoIterator,
656 Self::Item: PartialOrd<O::Item>,
657 Self: Sized,
658 {
659 self.iter.gt(other)
660 }
661
662 fn ge<O>(self, other: O) -> bool
663 where
664 O: IntoIterator,
665 Self::Item: PartialOrd<O::Item>,
666 Self: Sized,
667 {
668 self.iter.ge(other)
669 }
670
671 fn is_sorted(self) -> bool
672 where
673 Self: Sized,
674 Self::Item: PartialOrd,
675 {
676 self.iter.is_sorted()
677 }
678
679 fn is_sorted_by<F>(self, compare: F) -> bool
680 where
681 Self: Sized,
682 F: FnMut(&Self::Item, &Self::Item) -> bool,
683 {
684 self.iter.is_sorted_by(compare)
685 }
686
687 fn is_sorted_by_key<F, K>(self, f: F) -> bool
688 where
689 Self: Sized,
690 F: FnMut(Self::Item) -> K,
691 K: PartialOrd,
692 {
693 self.iter.is_sorted_by_key(f)
694 }
695}
696
697impl<I: ExactSizeIterator<Item: EntityEquivalent>> ExactSizeIterator for UniqueEntityIter<I> {}
698
699impl<I: DoubleEndedIterator<Item: EntityEquivalent>> DoubleEndedIterator for UniqueEntityIter<I> {
701 #[inline]
702 fn next_back(&mut self) -> Option<Self::Item> {
703 self.iter.next_back()
704 }
705
706 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
707 self.iter.nth_back(n)
708 }
709
710 fn rfold<B, F>(self, init: B, f: F) -> B
711 where
712 Self: Sized,
713 F: FnMut(B, Self::Item) -> B,
714 {
715 self.iter.rfold(init, f)
716 }
717
718 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
719 where
720 Self: Sized,
721 P: FnMut(&Self::Item) -> bool,
722 {
723 self.iter.rfind(predicate)
724 }
725}
726
727impl<I: FusedIterator<Item: EntityEquivalent>> FusedIterator for UniqueEntityIter<I> {}
728
729unsafe impl<I: Iterator<Item: EntityEquivalent>> EntitySetIterator for UniqueEntityIter<I> {}
731
732impl<T, I: Iterator<Item: EntityEquivalent> + AsRef<[T]>> AsRef<[T]> for UniqueEntityIter<I> {
733 fn as_ref(&self) -> &[T] {
734 self.iter.as_ref()
735 }
736}
737
738impl<T: EntityEquivalent, I: Iterator<Item: EntityEquivalent> + AsRef<[T]>>
739 AsRef<UniqueEntityEquivalentSlice<T>> for UniqueEntityIter<I>
740{
741 fn as_ref(&self) -> &UniqueEntityEquivalentSlice<T> {
742 unsafe { UniqueEntityEquivalentSlice::from_slice_unchecked(self.iter.as_ref()) }
744 }
745}
746
747impl<T: EntityEquivalent, I: Iterator<Item: EntityEquivalent> + AsMut<[T]>>
748 AsMut<UniqueEntityEquivalentSlice<T>> for UniqueEntityIter<I>
749{
750 fn as_mut(&mut self) -> &mut UniqueEntityEquivalentSlice<T> {
751 unsafe { UniqueEntityEquivalentSlice::from_slice_unchecked_mut(self.iter.as_mut()) }
753 }
754}
755
756impl<I: EntitySetIterator + Default> Default for UniqueEntityIter<I> {
758 fn default() -> Self {
759 Self {
760 iter: Default::default(),
761 }
762 }
763}
764
765impl<I: EntitySetIterator + Clone> Clone for UniqueEntityIter<I> {
767 fn clone(&self) -> Self {
768 Self {
769 iter: self.iter.clone(),
770 }
771 }
772
773 fn clone_from(&mut self, source: &Self) {
774 self.iter.clone_from(&source.iter);
775 }
776}
777
778impl<I: Iterator<Item: EntityEquivalent> + Debug> Debug for UniqueEntityIter<I> {
779 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
780 f.debug_struct("UniqueEntityIter")
781 .field("iter", &self.iter)
782 .finish()
783 }
784}
785
786#[cfg(test)]
787mod tests {
788 use alloc::{vec, vec::Vec};
789
790 use crate::{
791 component::Component,
792 entity::{Entity, EntityEquivalentHashMap, EntityEquivalentHashSet},
793 prelude::{Schedule, World},
794 query::{QueryState, With},
795 system::Query,
796 world::Mut,
797 };
798
799 use super::{ContainsEntity, EntityEquivalent, UniqueEntityIter};
800
801 #[derive(Component, Clone)]
802 pub struct Thing;
803
804 #[expect(
805 clippy::iter_skip_zero,
806 reason = "The `skip(0)` is used to ensure that the `Skip` iterator implements `EntitySet`, which is needed to pass the iterator as the `entities` parameter."
807 )]
808 #[test]
809 fn preserving_uniqueness() {
810 let mut world = World::new();
811
812 let mut query = QueryState::<&mut Thing>::new(&mut world);
813
814 let spawn_batch: Vec<Entity> = world.spawn_batch(vec![Thing; 1000]).collect();
815
816 let mut unique_entity_iter =
818 unsafe { UniqueEntityIter::from_iter_unchecked(spawn_batch.iter()) };
819
820 let entity_set = unique_entity_iter
821 .by_ref()
822 .filter(|_| true)
823 .fuse()
824 .inspect(|_| ())
825 .rev()
826 .skip(0)
827 .skip_while(|_| false)
828 .take(1000)
829 .take_while(|_| true)
830 .step_by(2)
831 .cloned();
832
833 let _results: Vec<Mut<Thing>> = query
835 .iter_many_unique_mut(&mut world, entity_set)
836 .unwrapped()
837 .collect();
838 }
839
840 #[test]
841 fn nesting_queries() {
842 let mut world = World::new();
843
844 world.spawn_batch(vec![Thing; 1000]);
845
846 pub fn system(
847 mut thing_entities: Query<Entity, With<Thing>>,
848 mut things: Query<&mut Thing>,
849 ) {
850 things.iter_many_unique(thing_entities.iter());
851 things.iter_many_unique_mut(thing_entities.iter_mut());
852 }
853
854 let mut schedule = Schedule::default();
855 schedule.add_systems(system);
856 schedule.run(&mut world);
857 }
858
859 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
860 struct EntityWrapper(Entity);
861
862 impl ContainsEntity for EntityWrapper {
863 fn entity(&self) -> Entity {
864 self.0
865 }
866 }
867
868 impl EntityWrapper {
869 fn new(index: u32) -> EntityWrapper {
870 EntityWrapper(Entity::from_raw_u32(index).unwrap())
871 }
872 }
873
874 unsafe impl EntityEquivalent for EntityWrapper {}
876
877 #[test]
878 fn entity_equivalent_map_test() {
879 type EntityWrapperMap = EntityEquivalentHashMap<EntityWrapper, i32>;
880
881 let mut map = EntityWrapperMap::default();
882 map.insert(EntityWrapper::new(0), 10);
883 map.insert(EntityWrapper::new(1), 11);
884 map.insert(EntityWrapper::new(0), 12);
885 assert_eq!(map.len(), 2);
886 assert!(map
887 .get(&EntityWrapper::new(0))
888 .is_some_and(|val| *val == 12));
889 map.remove(&EntityWrapper::new(1));
890 assert_eq!(map.len(), 1);
891 map.clear();
892 assert!(map.is_empty());
893 }
894
895 #[test]
896 fn entity_equivalent_set_test() {
897 type EntityWrapperSet = EntityEquivalentHashSet<EntityWrapper>;
898
899 let mut set = EntityWrapperSet::default();
900 set.insert(EntityWrapper::new(0));
901 set.insert(EntityWrapper::new(1));
902 set.insert(EntityWrapper::new(0));
903 assert_eq!(set.len(), 2);
904 assert!(set.get(&EntityWrapper::new(0)).is_some());
905 set.remove(&EntityWrapper::new(1));
906 assert_eq!(set.len(), 1);
907 set.clear();
908 assert!(set.is_empty());
909 }
910}