bevy_ecs/entity/entity_set.rs
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 fmt::{Debug, Formatter},
11 hash::{BuildHasher, Hash},
12 iter::{self, FusedIterator},
13 option, result,
14};
15
16use super::{Entity, UniqueEntityEquivalentSlice};
17
18use bevy_platform::sync::Arc;
19
20/// A trait for types that contain an [`Entity`].
21///
22/// This trait behaves similarly to `Borrow<Entity>`, but yielding `Entity` directly.
23///
24/// It should only be implemented when:
25/// - Retrieving the [`Entity`] is a simple operation.
26/// - The [`Entity`] contained by the type is unambiguous.
27pub trait ContainsEntity {
28 /// Returns the contained entity.
29 fn entity(&self) -> Entity;
30}
31
32/// A trait for types that represent an [`Entity`].
33///
34/// Comparison trait behavior between an [`EntityEquivalent`] type and its underlying entity will match.
35/// This property includes [`PartialEq`], [`Eq`], [`PartialOrd`], [`Ord`] and [`Hash`],
36/// and remains even after [`Clone`] and/or [`Borrow`] calls.
37///
38/// # Safety
39/// Any [`PartialEq`], [`Eq`], [`PartialOrd`], and [`Ord`] impls must evaluate the same for `Self` and
40/// its underlying entity.
41/// `x.entity() == y.entity()` must be equivalent to `x == y`.
42///
43/// The above equivalence must also hold through and between calls to any [`Clone`] and
44/// [`Borrow`]/[`BorrowMut`] impls in place of [`entity()`].
45///
46/// The result of [`entity()`] must be unaffected by any interior mutability.
47///
48/// The aforementioned properties imply determinism in both [`entity()`] calls
49/// and comparison trait behavior.
50///
51/// All [`Hash`] impls except that for [`Entity`] must delegate to the [`Hash`] impl of
52/// another [`EntityEquivalent`] type. All conversions to the delegatee within the [`Hash`] impl must
53/// follow [`entity()`] equivalence.
54///
55/// It should be noted that [`Hash`] is *not* a comparison trait, and with [`Hash::hash`] being forcibly
56/// generic over all [`Hasher`]s, **cannot** guarantee determinism or uniqueness of any final hash values
57/// on its own.
58/// To obtain hash values forming the same total order as [`Entity`], any [`Hasher`] used must be
59/// deterministic and concerning [`Entity`], collisionless.
60/// Standard library hash collections handle collisions with an [`Eq`] fallback, but do not account for
61/// determinism when [`BuildHasher`] is unspecified,.
62///
63/// [`Hash`]: core::hash::Hash
64/// [`Hasher`]: core::hash::Hasher
65/// [`Borrow`]: core::borrow::Borrow
66/// [`BorrowMut`]: core::borrow::BorrowMut
67/// [`entity()`]: ContainsEntity::entity
68pub unsafe trait EntityEquivalent: ContainsEntity + Eq {}
69
70impl ContainsEntity for Entity {
71 fn entity(&self) -> Entity {
72 *self
73 }
74}
75
76// SAFETY:
77// The trait implementations of Entity are correct and deterministic.
78unsafe impl EntityEquivalent for Entity {}
79
80impl<T: ContainsEntity> ContainsEntity for &T {
81 fn entity(&self) -> Entity {
82 (**self).entity()
83 }
84}
85
86// SAFETY:
87// `&T` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
88// `Clone` and `Borrow` maintain equality.
89// `&T` is `Freeze`.
90unsafe impl<T: EntityEquivalent> EntityEquivalent for &T {}
91
92impl<T: ContainsEntity> ContainsEntity for &mut T {
93 fn entity(&self) -> Entity {
94 (**self).entity()
95 }
96}
97
98// SAFETY:
99// `&mut T` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
100// `Borrow` and `BorrowMut` maintain equality.
101// `&mut T` is `Freeze`.
102unsafe impl<T: EntityEquivalent> EntityEquivalent for &mut T {}
103
104impl<T: ContainsEntity> ContainsEntity for Box<T> {
105 fn entity(&self) -> Entity {
106 (**self).entity()
107 }
108}
109
110// SAFETY:
111// `Box<T>` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
112// `Clone`, `Borrow` and `BorrowMut` maintain equality.
113// `Box<T>` is `Freeze`.
114unsafe impl<T: EntityEquivalent> EntityEquivalent for Box<T> {}
115
116impl<T: ContainsEntity> ContainsEntity for Rc<T> {
117 fn entity(&self) -> Entity {
118 (**self).entity()
119 }
120}
121
122// SAFETY:
123// `Rc<T>` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
124// `Clone`, `Borrow` and `BorrowMut` maintain equality.
125// `Rc<T>` is `Freeze`.
126unsafe impl<T: EntityEquivalent> EntityEquivalent for Rc<T> {}
127
128impl<T: ContainsEntity> ContainsEntity for Arc<T> {
129 fn entity(&self) -> Entity {
130 (**self).entity()
131 }
132}
133
134// SAFETY:
135// `Arc<T>` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
136// `Clone`, `Borrow` and `BorrowMut` maintain equality.
137// `Arc<T>` is `Freeze`.
138unsafe impl<T: EntityEquivalent> EntityEquivalent for Arc<T> {}
139
140/// A set of unique entities.
141///
142/// Any element returned by [`Self::IntoIter`] will compare non-equal to every other element in the iterator.
143/// As a consequence, [`into_iter()`] on `EntitySet` will always produce another `EntitySet`.
144///
145/// Implementing this trait allows for unique query iteration over a list of entities.
146/// See [`iter_many_unique`] and [`iter_many_unique_mut`]
147///
148/// Note that there is no guarantee of the [`IntoIterator`] impl being deterministic,
149/// it might return different iterators when called multiple times.
150/// Neither is there a guarantee that the comparison trait impls of `EntitySet` match that
151/// of the respective [`EntitySetIterator`] (or of a [`Vec`] collected from its elements)
152///
153/// [`Self::IntoIter`]: IntoIterator::IntoIter
154/// [`into_iter()`]: IntoIterator::into_iter
155/// [`iter_many_unique`]: crate::system::Query::iter_many_unique
156/// [`iter_many_unique_mut`]: crate::system::Query::iter_many_unique_mut
157/// [`Vec`]: alloc::vec::Vec
158pub trait EntitySet: IntoIterator<IntoIter: EntitySetIterator> {}
159
160impl<T: IntoIterator<IntoIter: EntitySetIterator>> EntitySet for T {}
161
162/// An iterator over a set of unique entities.
163///
164/// Every `EntitySetIterator` is also [`EntitySet`].
165///
166/// # Safety
167///
168/// `x != y` must hold for any 2 elements returned by the iterator.
169/// This is always true for iterators that cannot return more than one element.
170pub unsafe trait EntitySetIterator: Iterator<Item: EntityEquivalent> {
171 /// Transforms an `EntitySetIterator` into a collection.
172 ///
173 /// This is a specialized form of [`collect`], for collections which benefit from the uniqueness guarantee.
174 /// When present, this should always be preferred over [`collect`].
175 ///
176 /// [`collect`]: Iterator::collect
177 // FIXME: When subtrait item shadowing stabilizes, this should be renamed and shadow `Iterator::collect`
178 fn collect_set<B: FromEntitySetIterator<Self::Item>>(self) -> B
179 where
180 Self: Sized,
181 {
182 FromEntitySetIterator::from_entity_set_iter(self)
183 }
184}
185
186// SAFETY:
187// A correct `BTreeMap` contains only unique keys.
188// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeMap`.
189unsafe impl<K: EntityEquivalent, V> EntitySetIterator for btree_map::Keys<'_, K, V> {}
190
191// SAFETY:
192// A correct `BTreeMap` contains only unique keys.
193// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeMap`.
194unsafe impl<K: EntityEquivalent, V> EntitySetIterator for btree_map::IntoKeys<K, V> {}
195
196// SAFETY:
197// A correct `BTreeSet` contains only unique elements.
198// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
199// The sub-range maintains uniqueness.
200unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::Range<'_, T> {}
201
202// SAFETY:
203// A correct `BTreeSet` contains only unique elements.
204// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
205// The "intersection" operation maintains uniqueness.
206unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Intersection<'_, T> {}
207
208// SAFETY:
209// A correct `BTreeSet` contains only unique elements.
210// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
211// The "union" operation maintains uniqueness.
212unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Union<'_, T> {}
213
214// SAFETY:
215// A correct `BTreeSet` contains only unique elements.
216// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
217// The "difference" operation maintains uniqueness.
218unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Difference<'_, T> {}
219
220// SAFETY:
221// A correct `BTreeSet` contains only unique elements.
222// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
223// The "symmetric difference" operation maintains uniqueness.
224unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::SymmetricDifference<'_, T> {}
225
226// SAFETY:
227// A correct `BTreeSet` contains only unique elements.
228// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
229unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::Iter<'_, T> {}
230
231// SAFETY:
232// A correct `BTreeSet` contains only unique elements.
233// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
234unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::IntoIter<T> {}
235
236// SAFETY: This iterator only returns one element.
237unsafe impl<T: EntityEquivalent> EntitySetIterator for option::Iter<'_, T> {}
238
239// SAFETY: This iterator only returns one element.
240// unsafe impl<T: EntityEquivalent> EntitySetIterator for option::IterMut<'_, T> {}
241
242// SAFETY: This iterator only returns one element.
243unsafe impl<T: EntityEquivalent> EntitySetIterator for option::IntoIter<T> {}
244
245// SAFETY: This iterator only returns one element.
246unsafe impl<T: EntityEquivalent> EntitySetIterator for result::Iter<'_, T> {}
247
248// SAFETY: This iterator only returns one element.
249// unsafe impl<T: EntityEquivalent> EntitySetIterator for result::IterMut<'_, T> {}
250
251// SAFETY: This iterator only returns one element.
252unsafe impl<T: EntityEquivalent> EntitySetIterator for result::IntoIter<T> {}
253
254// SAFETY: This iterator only returns one element.
255unsafe impl<T: EntityEquivalent> EntitySetIterator for array::IntoIter<T, 1> {}
256
257// SAFETY: This iterator does not return any elements.
258unsafe impl<T: EntityEquivalent> EntitySetIterator for array::IntoIter<T, 0> {}
259
260// SAFETY: This iterator only returns one element.
261unsafe impl<T: EntityEquivalent, F: FnOnce() -> T> EntitySetIterator for iter::OnceWith<F> {}
262
263// SAFETY: This iterator only returns one element.
264unsafe impl<T: EntityEquivalent> EntitySetIterator for iter::Once<T> {}
265
266// SAFETY: This iterator does not return any elements.
267unsafe impl<T: EntityEquivalent> EntitySetIterator for iter::Empty<T> {}
268
269// SAFETY: Taking a mutable reference of an iterator has no effect on its elements.
270unsafe impl<I: EntitySetIterator + ?Sized> EntitySetIterator for &mut I {}
271
272// SAFETY: Boxing an iterator has no effect on its elements.
273unsafe impl<I: EntitySetIterator + ?Sized> EntitySetIterator for Box<I> {}
274
275// SAFETY: EntityEquivalent ensures that Copy does not affect equality, via its restrictions on Clone.
276unsafe impl<'a, T: 'a + EntityEquivalent + Copy, I: EntitySetIterator<Item = &'a T>>
277 EntitySetIterator for iter::Copied<I>
278{
279}
280
281// SAFETY: EntityEquivalent ensures that Clone does not affect equality.
282unsafe impl<'a, T: 'a + EntityEquivalent + Clone, I: EntitySetIterator<Item = &'a T>>
283 EntitySetIterator for iter::Cloned<I>
284{
285}
286
287// SAFETY: Discarding elements maintains uniqueness.
288unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
289 for iter::Filter<I, P>
290{
291}
292
293// SAFETY: Yielding only `None` after yielding it once can only remove elements, which maintains uniqueness.
294unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Fuse<I> {}
295
296// SAFETY:
297// Obtaining immutable references the elements of an iterator does not affect uniqueness.
298// EntityEquivalent ensures the lack of interior mutability.
299unsafe impl<I: EntitySetIterator, F: FnMut(&<I as Iterator>::Item)> EntitySetIterator
300 for iter::Inspect<I, F>
301{
302}
303
304// SAFETY: Reversing an iterator does not affect uniqueness.
305unsafe impl<I: DoubleEndedIterator + EntitySetIterator> EntitySetIterator for iter::Rev<I> {}
306
307// SAFETY: Discarding elements maintains uniqueness.
308unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Skip<I> {}
309
310// SAFETY: Discarding elements maintains uniqueness.
311unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
312 for iter::SkipWhile<I, P>
313{
314}
315
316// SAFETY: Discarding elements maintains uniqueness.
317unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Take<I> {}
318
319// SAFETY: Discarding elements maintains uniqueness.
320unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
321 for iter::TakeWhile<I, P>
322{
323}
324
325// SAFETY: Discarding elements maintains uniqueness.
326unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::StepBy<I> {}
327
328/// Conversion from an `EntitySetIterator`.
329///
330/// Some collections, while they can be constructed from plain iterators,
331/// benefit strongly from the additional uniqueness guarantee [`EntitySetIterator`] offers.
332/// Mirroring [`Iterator::collect`]/[`FromIterator::from_iter`], [`EntitySetIterator::collect_set`] and
333/// `FromEntitySetIterator::from_entity_set_iter` can be used for construction.
334///
335/// See also: [`EntitySet`].
336// FIXME: When subtrait item shadowing stabilizes, this should be renamed and shadow `FromIterator::from_iter`
337pub trait FromEntitySetIterator<A: EntityEquivalent>: FromIterator<A> {
338 /// Creates a value from an [`EntitySetIterator`].
339 fn from_entity_set_iter<T: EntitySet<Item = A>>(set_iter: T) -> Self;
340}
341
342impl<T: EntityEquivalent + Hash, S: BuildHasher + Default> FromEntitySetIterator<T>
343 for HashSet<T, S>
344{
345 fn from_entity_set_iter<I: EntitySet<Item = T>>(set_iter: I) -> Self {
346 let iter = set_iter.into_iter();
347 let set = HashSet::<T, S>::with_capacity_and_hasher(iter.size_hint().0, S::default());
348 iter.fold(set, |mut set, e| {
349 // SAFETY: Every element in self is unique.
350 unsafe {
351 set.insert_unique_unchecked(e);
352 }
353 set
354 })
355 }
356}
357
358/// An iterator that yields unique entities.
359///
360/// This wrapper can provide an [`EntitySetIterator`] implementation when an instance of `I` is known to uphold uniqueness.
361pub struct UniqueEntityIter<I: Iterator<Item: EntityEquivalent>> {
362 iter: I,
363}
364
365impl<I: EntitySetIterator> UniqueEntityIter<I> {
366 /// Constructs a `UniqueEntityIter` from an [`EntitySetIterator`].
367 pub fn from_entity_set_iterator<S>(iter: I) -> Self {
368 Self { iter }
369 }
370}
371
372impl<I: Iterator<Item: EntityEquivalent>> UniqueEntityIter<I> {
373 /// Constructs a [`UniqueEntityIter`] from an iterator unsafely.
374 ///
375 /// # Safety
376 /// `iter` must only yield unique elements.
377 /// As in, the resulting iterator must adhere to the safety contract of [`EntitySetIterator`].
378 pub unsafe fn from_iterator_unchecked(iter: I) -> Self {
379 Self { iter }
380 }
381
382 /// Returns the inner `I`.
383 pub fn into_inner(self) -> I {
384 self.iter
385 }
386
387 /// Returns a reference to the inner `I`.
388 pub fn as_inner(&self) -> &I {
389 &self.iter
390 }
391
392 /// Returns a mutable reference to the inner `I`.
393 ///
394 /// # Safety
395 ///
396 /// `self` must always contain an iterator that yields unique elements,
397 /// even while this reference is live.
398 pub unsafe fn as_mut_inner(&mut self) -> &mut I {
399 &mut self.iter
400 }
401}
402
403impl<I: Iterator<Item: EntityEquivalent>> Iterator for UniqueEntityIter<I> {
404 type Item = I::Item;
405
406 fn next(&mut self) -> Option<Self::Item> {
407 self.iter.next()
408 }
409
410 fn size_hint(&self) -> (usize, Option<usize>) {
411 self.iter.size_hint()
412 }
413}
414
415impl<I: ExactSizeIterator<Item: EntityEquivalent>> ExactSizeIterator for UniqueEntityIter<I> {}
416
417impl<I: DoubleEndedIterator<Item: EntityEquivalent>> DoubleEndedIterator for UniqueEntityIter<I> {
418 fn next_back(&mut self) -> Option<Self::Item> {
419 self.iter.next_back()
420 }
421}
422
423impl<I: FusedIterator<Item: EntityEquivalent>> FusedIterator for UniqueEntityIter<I> {}
424
425// SAFETY: The underlying iterator is ensured to only return unique elements by its construction.
426unsafe impl<I: Iterator<Item: EntityEquivalent>> EntitySetIterator for UniqueEntityIter<I> {}
427
428impl<T, I: Iterator<Item: EntityEquivalent> + AsRef<[T]>> AsRef<[T]> for UniqueEntityIter<I> {
429 fn as_ref(&self) -> &[T] {
430 self.iter.as_ref()
431 }
432}
433
434impl<T: EntityEquivalent, I: Iterator<Item: EntityEquivalent> + AsRef<[T]>>
435 AsRef<UniqueEntityEquivalentSlice<T>> for UniqueEntityIter<I>
436{
437 fn as_ref(&self) -> &UniqueEntityEquivalentSlice<T> {
438 // SAFETY: All elements in the original slice are unique.
439 unsafe { UniqueEntityEquivalentSlice::from_slice_unchecked(self.iter.as_ref()) }
440 }
441}
442
443impl<T: EntityEquivalent, I: Iterator<Item: EntityEquivalent> + AsMut<[T]>>
444 AsMut<UniqueEntityEquivalentSlice<T>> for UniqueEntityIter<I>
445{
446 fn as_mut(&mut self) -> &mut UniqueEntityEquivalentSlice<T> {
447 // SAFETY: All elements in the original slice are unique.
448 unsafe { UniqueEntityEquivalentSlice::from_slice_unchecked_mut(self.iter.as_mut()) }
449 }
450}
451
452// Default does not guarantee uniqueness, meaning `I` needs to be EntitySetIterator.
453impl<I: EntitySetIterator + Default> Default for UniqueEntityIter<I> {
454 fn default() -> Self {
455 Self {
456 iter: Default::default(),
457 }
458 }
459}
460
461// Clone does not guarantee to maintain uniqueness, meaning `I` needs to be EntitySetIterator.
462impl<I: EntitySetIterator + Clone> Clone for UniqueEntityIter<I> {
463 fn clone(&self) -> Self {
464 Self {
465 iter: self.iter.clone(),
466 }
467 }
468}
469
470impl<I: Iterator<Item: EntityEquivalent> + Debug> Debug for UniqueEntityIter<I> {
471 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
472 f.debug_struct("UniqueEntityIter")
473 .field("iter", &self.iter)
474 .finish()
475 }
476}
477
478#[cfg(test)]
479mod tests {
480 use alloc::{vec, vec::Vec};
481
482 use crate::prelude::{Schedule, World};
483
484 use crate::component::Component;
485 use crate::entity::Entity;
486 use crate::query::{QueryState, With};
487 use crate::system::Query;
488 use crate::world::Mut;
489
490 use super::UniqueEntityIter;
491
492 #[derive(Component, Clone)]
493 pub struct Thing;
494
495 #[expect(
496 clippy::iter_skip_zero,
497 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."
498 )]
499 #[test]
500 fn preserving_uniqueness() {
501 let mut world = World::new();
502
503 let mut query = QueryState::<&mut Thing>::new(&mut world);
504
505 let spawn_batch: Vec<Entity> = world.spawn_batch(vec![Thing; 1000]).collect();
506
507 // SAFETY: SpawnBatchIter is `EntitySetIterator`,
508 let mut unique_entity_iter =
509 unsafe { UniqueEntityIter::from_iterator_unchecked(spawn_batch.iter()) };
510
511 let entity_set = unique_entity_iter
512 .by_ref()
513 .filter(|_| true)
514 .fuse()
515 .inspect(|_| ())
516 .rev()
517 .skip(0)
518 .skip_while(|_| false)
519 .take(1000)
520 .take_while(|_| true)
521 .step_by(2)
522 .cloned();
523
524 // With `iter_many_mut` collecting is not possible, because you need to drop each `Mut`/`&mut` before the next is retrieved.
525 let _results: Vec<Mut<Thing>> =
526 query.iter_many_unique_mut(&mut world, entity_set).collect();
527 }
528
529 #[test]
530 fn nesting_queries() {
531 let mut world = World::new();
532
533 world.spawn_batch(vec![Thing; 1000]);
534
535 pub fn system(
536 mut thing_entities: Query<Entity, With<Thing>>,
537 mut things: Query<&mut Thing>,
538 ) {
539 things.iter_many_unique(thing_entities.iter());
540 things.iter_many_unique_mut(thing_entities.iter_mut());
541 }
542
543 let mut schedule = Schedule::default();
544 schedule.add_systems(system);
545 schedule.run(&mut world);
546 }
547}