Skip to main content

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, ptr, 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    #[inline]
346    fn from_entity_set_iter<I: EntitySet<Item = T>>(set_iter: I) -> Self {
347        let iter = set_iter.into_iter();
348        let set = HashSet::with_capacity_and_hasher(iter.size_hint().0, S::default());
349        iter.fold(set, |mut set, e| {
350            // SAFETY: Every element in self is unique.
351            unsafe {
352                set.insert_unique_unchecked(e);
353            }
354            set
355        })
356    }
357}
358
359/// An iterator that yields unique entities.
360///
361/// This wrapper can provide an [`EntitySetIterator`] implementation when an instance of `I` is known to uphold uniqueness.
362#[repr(transparent)]
363pub struct UniqueEntityIter<I: Iterator<Item: EntityEquivalent>> {
364    iter: I,
365}
366
367impl<I: EntitySetIterator> UniqueEntityIter<I> {
368    /// Constructs a `UniqueEntityIter` from an [`EntitySetIterator`].
369    #[inline]
370    pub const fn from_entity_set_iter(iter: I) -> Self {
371        // SAFETY: iter implements `EntitySetIterator`.
372        unsafe { Self::from_iter_unchecked(iter) }
373    }
374}
375
376impl<I: Iterator<Item: EntityEquivalent>> UniqueEntityIter<I> {
377    /// Constructs a [`UniqueEntityIter`] from an iterator unsafely.
378    ///
379    /// # Safety
380    /// `iter` must only yield unique elements.
381    /// As in, the resulting iterator must adhere to the safety contract of [`EntitySetIterator`].
382    #[inline]
383    pub const unsafe fn from_iter_unchecked(iter: I) -> Self {
384        Self { iter }
385    }
386
387    /// Constructs a [`UniqueEntityIter`] from an iterator unsafely.
388    ///
389    /// # Safety
390    /// `iter` must only yield unique elements.
391    /// As in, the resulting iterator must adhere to the safety contract of [`EntitySetIterator`].
392    #[inline]
393    pub const unsafe fn from_iter_ref_unchecked(iter: &I) -> &Self {
394        // SAFETY: UniqueEntityIter is a transparent wrapper around I.
395        unsafe { &*ptr::from_ref(iter).cast() }
396    }
397
398    /// Constructs a [`UniqueEntityIter`] from an iterator unsafely.
399    ///
400    /// # Safety
401    /// `iter` must only yield unique elements.
402    /// As in, the resulting iterator must adhere to the safety contract of [`EntitySetIterator`].
403    #[inline]
404    pub const unsafe fn from_iter_mut_unchecked(iter: &mut I) -> &mut Self {
405        // SAFETY: UniqueEntityIter is a transparent wrapper around I.
406        unsafe { &mut *ptr::from_mut(iter).cast() }
407    }
408
409    /// Returns the inner `I`.
410    pub fn into_inner(self) -> I {
411        self.iter
412    }
413
414    /// Returns a reference to the inner `I`.
415    pub const fn as_inner(&self) -> &I {
416        &self.iter
417    }
418
419    /// Returns a mutable reference to the inner `I`.
420    ///
421    /// # Safety
422    ///
423    /// `self` must always contain an iterator that yields unique elements,
424    /// even while this reference is live.
425    pub const unsafe fn as_mut_inner(&mut self) -> &mut I {
426        &mut self.iter
427    }
428}
429
430impl<I: Iterator<Item: EntityEquivalent>> Iterator for UniqueEntityIter<I> {
431    type Item = I::Item;
432
433    fn next(&mut self) -> Option<Self::Item> {
434        self.iter.next()
435    }
436
437    fn size_hint(&self) -> (usize, Option<usize>) {
438        self.iter.size_hint()
439    }
440}
441
442impl<I: ExactSizeIterator<Item: EntityEquivalent>> ExactSizeIterator for UniqueEntityIter<I> {}
443
444impl<I: DoubleEndedIterator<Item: EntityEquivalent>> DoubleEndedIterator for UniqueEntityIter<I> {
445    #[inline]
446    fn next_back(&mut self) -> Option<Self::Item> {
447        self.iter.next_back()
448    }
449}
450
451impl<I: FusedIterator<Item: EntityEquivalent>> FusedIterator for UniqueEntityIter<I> {}
452
453// SAFETY: The underlying iterator is ensured to only return unique elements by its construction.
454unsafe impl<I: Iterator<Item: EntityEquivalent>> EntitySetIterator for UniqueEntityIter<I> {}
455
456impl<T, I: Iterator<Item: EntityEquivalent> + AsRef<[T]>> AsRef<[T]> for UniqueEntityIter<I> {
457    fn as_ref(&self) -> &[T] {
458        self.iter.as_ref()
459    }
460}
461
462impl<T: EntityEquivalent, I: Iterator<Item: EntityEquivalent> + AsRef<[T]>>
463    AsRef<UniqueEntityEquivalentSlice<T>> for UniqueEntityIter<I>
464{
465    fn as_ref(&self) -> &UniqueEntityEquivalentSlice<T> {
466        // SAFETY: All elements in the original slice are unique.
467        unsafe { UniqueEntityEquivalentSlice::from_slice_unchecked(self.iter.as_ref()) }
468    }
469}
470
471impl<T: EntityEquivalent, I: Iterator<Item: EntityEquivalent> + AsMut<[T]>>
472    AsMut<UniqueEntityEquivalentSlice<T>> for UniqueEntityIter<I>
473{
474    fn as_mut(&mut self) -> &mut UniqueEntityEquivalentSlice<T> {
475        // SAFETY: All elements in the original slice are unique.
476        unsafe { UniqueEntityEquivalentSlice::from_slice_unchecked_mut(self.iter.as_mut()) }
477    }
478}
479
480// Default does not guarantee uniqueness, meaning `I` needs to be EntitySetIterator.
481impl<I: EntitySetIterator + Default> Default for UniqueEntityIter<I> {
482    fn default() -> Self {
483        Self {
484            iter: Default::default(),
485        }
486    }
487}
488
489// Clone does not guarantee to maintain uniqueness, meaning `I` needs to be EntitySetIterator.
490impl<I: EntitySetIterator + Clone> Clone for UniqueEntityIter<I> {
491    fn clone(&self) -> Self {
492        Self {
493            iter: self.iter.clone(),
494        }
495    }
496}
497
498impl<I: Iterator<Item: EntityEquivalent> + Debug> Debug for UniqueEntityIter<I> {
499    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
500        f.debug_struct("UniqueEntityIter")
501            .field("iter", &self.iter)
502            .finish()
503    }
504}
505
506#[cfg(test)]
507mod tests {
508    use alloc::{vec, vec::Vec};
509
510    use crate::prelude::{Schedule, World};
511
512    use crate::component::Component;
513    use crate::entity::Entity;
514    use crate::query::{QueryState, With};
515    use crate::system::Query;
516    use crate::world::Mut;
517
518    use super::UniqueEntityIter;
519
520    #[derive(Component, Clone)]
521    pub struct Thing;
522
523    #[expect(
524        clippy::iter_skip_zero,
525        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."
526    )]
527    #[test]
528    fn preserving_uniqueness() {
529        let mut world = World::new();
530
531        let mut query = QueryState::<&mut Thing>::new(&mut world);
532
533        let spawn_batch: Vec<Entity> = world.spawn_batch(vec![Thing; 1000]).collect();
534
535        // SAFETY: SpawnBatchIter is `EntitySetIterator`,
536        let mut unique_entity_iter =
537            unsafe { UniqueEntityIter::from_iter_unchecked(spawn_batch.iter()) };
538
539        let entity_set = unique_entity_iter
540            .by_ref()
541            .filter(|_| true)
542            .fuse()
543            .inspect(|_| ())
544            .rev()
545            .skip(0)
546            .skip_while(|_| false)
547            .take(1000)
548            .take_while(|_| true)
549            .step_by(2)
550            .cloned();
551
552        // With `iter_many_mut` collecting is not possible, because you need to drop each `Mut`/`&mut` before the next is retrieved.
553        let _results: Vec<Mut<Thing>> =
554            query.iter_many_unique_mut(&mut world, entity_set).collect();
555    }
556
557    #[test]
558    fn nesting_queries() {
559        let mut world = World::new();
560
561        world.spawn_batch(vec![Thing; 1000]);
562
563        pub fn system(
564            mut thing_entities: Query<Entity, With<Thing>>,
565            mut things: Query<&mut Thing>,
566        ) {
567            things.iter_many_unique(thing_entities.iter());
568            things.iter_many_unique_mut(thing_entities.iter_mut());
569        }
570
571        let mut schedule = Schedule::default();
572        schedule.add_systems(system);
573        schedule.run(&mut world);
574    }
575}