bevy_ecs/query/iter.rs
1use super::{QueryData, QueryFilter, ReadOnlyQueryData};
2use crate::{
3 archetype::{Archetype, ArchetypeEntity, Archetypes},
4 bundle::Bundle,
5 change_detection::Tick,
6 entity::{ContainsEntity, Entities, Entity, EntityEquivalent, EntitySet, EntitySetIterator},
7 query::{ArchetypeFilter, ArchetypeQueryData, DebugCheckedUnwrap, QueryState, StorageId},
8 storage::{Table, TableRow, Tables},
9 world::{
10 unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
11 FilteredEntityMut, FilteredEntityRef,
12 },
13};
14use alloc::vec::Vec;
15use core::{
16 cmp::Ordering,
17 fmt::{self, Debug, Formatter},
18 iter::FusedIterator,
19 mem::MaybeUninit,
20 ops::Range,
21};
22use nonmax::NonMaxU32;
23
24/// An [`Iterator`] over query results of a [`Query`](crate::system::Query).
25///
26/// This struct is created by the [`Query::iter`](crate::system::Query::iter) and
27/// [`Query::iter_mut`](crate::system::Query::iter_mut) methods.
28pub struct QueryIter<'w, 's, D: QueryData, F: QueryFilter> {
29 world: UnsafeWorldCell<'w>,
30 tables: &'w Tables,
31 archetypes: &'w Archetypes,
32 query_state: &'s QueryState<D, F>,
33 cursor: QueryIterationCursor<'w, 's, D, F>,
34}
35
36impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
37 /// # Safety
38 /// - `world` must have permission to access any of the components registered in `query_state`.
39 /// - `world` must be the same one used to initialize `query_state`.
40 pub(crate) unsafe fn new(
41 world: UnsafeWorldCell<'w>,
42 query_state: &'s QueryState<D, F>,
43 last_run: Tick,
44 this_run: Tick,
45 ) -> Self {
46 QueryIter {
47 world,
48 query_state,
49 // SAFETY: We only access table data that has been registered in `query_state`.
50 tables: unsafe { &world.storages().tables },
51 archetypes: world.archetypes(),
52 // SAFETY: The invariants are upheld by the caller.
53 cursor: unsafe { QueryIterationCursor::init(world, query_state, last_run, this_run) },
54 }
55 }
56
57 /// Creates a new separate iterator yielding the same remaining items of the current one.
58 /// Advancing the new iterator will not advance the original one, which will resume at the
59 /// point it was left at.
60 ///
61 /// Differently from [`remaining_mut`](QueryIter::remaining_mut) the new iterator does not
62 /// borrow from the original one. However it can only be called from an iterator over read only
63 /// items.
64 ///
65 /// # Example
66 ///
67 /// ```
68 /// # use bevy_ecs::prelude::*;
69 /// #
70 /// # #[derive(Component)]
71 /// # struct ComponentA;
72 ///
73 /// fn combinations(query: Query<&ComponentA>) {
74 /// let mut iter = query.iter();
75 /// while let Some(a) = iter.next() {
76 /// for b in iter.remaining() {
77 /// // Check every combination (a, b)
78 /// }
79 /// }
80 /// }
81 /// ```
82 pub fn remaining(&self) -> QueryIter<'w, 's, D, F>
83 where
84 D: ReadOnlyQueryData,
85 {
86 QueryIter {
87 world: self.world,
88 tables: self.tables,
89 archetypes: self.archetypes,
90 query_state: self.query_state,
91 cursor: self.cursor.clone(),
92 }
93 }
94
95 /// Creates a new separate iterator yielding the same remaining items of the current one.
96 /// Advancing the new iterator will not advance the original one, which will resume at the
97 /// point it was left at.
98 ///
99 /// This method can be called on iterators over mutable items. However the original iterator
100 /// will be borrowed while the new iterator exists and will thus not be usable in that timespan.
101 ///
102 /// # Example
103 ///
104 /// ```
105 /// # use bevy_ecs::prelude::*;
106 /// #
107 /// # #[derive(Component)]
108 /// # struct ComponentA;
109 ///
110 /// fn combinations(mut query: Query<&mut ComponentA>) {
111 /// let mut iter = query.iter_mut();
112 /// while let Some(a) = iter.next() {
113 /// for b in iter.remaining_mut() {
114 /// // Check every combination (a, b)
115 /// }
116 /// }
117 /// }
118 /// ```
119 pub fn remaining_mut(&mut self) -> QueryIter<'_, 's, D, F> {
120 QueryIter {
121 world: self.world,
122 tables: self.tables,
123 archetypes: self.archetypes,
124 query_state: self.query_state,
125 cursor: self.cursor.reborrow(),
126 }
127 }
128
129 /// Executes the equivalent of [`Iterator::fold`] over a contiguous segment
130 /// from a storage.
131 ///
132 /// # Safety
133 /// - `range` must be in `[0, storage::entity_count)` or None.
134 #[inline]
135 pub(super) unsafe fn fold_over_storage_range<B, Func>(
136 &mut self,
137 mut accum: B,
138 func: &mut Func,
139 storage: StorageId,
140 range: Option<Range<u32>>,
141 ) -> B
142 where
143 Func: FnMut(B, D::Item<'w, 's>) -> B,
144 {
145 if self.cursor.is_dense {
146 // SAFETY: `self.cursor.is_dense` is true, so storage ids are guaranteed to be table ids.
147 let table_id = unsafe { storage.table_id };
148 // SAFETY: Matched table IDs are guaranteed to still exist.
149 let table = unsafe { self.tables.get(table_id).debug_checked_unwrap() };
150
151 let range = range.unwrap_or(0..table.entity_count());
152 accum =
153 // SAFETY:
154 // - The fetched table matches both D and F
155 // - caller ensures `range` is within `[0, table.entity_count)`
156 // - The if block ensures that the query iteration is dense
157 unsafe { self.fold_over_table_range(accum, func, table, range) };
158 } else {
159 // SAFETY: `self.cursor.is_dense` is false, so storage ids are guaranteed to be archetype ids.
160 let archetype_id = unsafe { storage.archetype_id };
161 // SAFETY: Matched archetype IDs are guaranteed to still exist.
162 let archetype = unsafe { self.archetypes.get(archetype_id).debug_checked_unwrap() };
163 // SAFETY: Matched table IDs are guaranteed to still exist.
164 let table = unsafe { self.tables.get(archetype.table_id()).debug_checked_unwrap() };
165
166 let range = range.unwrap_or(0..archetype.len());
167
168 // When an archetype and its table have equal entity counts, dense iteration can be safely used.
169 // this leverages cache locality to optimize performance.
170 if table.entity_count() == archetype.len() {
171 accum =
172 // SAFETY:
173 // - The fetched archetype matches both D and F
174 // - The provided archetype and its' table have the same length.
175 // - caller ensures `range` is within `[0, archetype.len)`
176 // - The if block ensures that the query iteration is not dense.
177 unsafe { self.fold_over_dense_archetype_range(accum, func, archetype,range) };
178 } else {
179 accum =
180 // SAFETY:
181 // - The fetched archetype matches both D and F
182 // - caller ensures `range` is within `[0, archetype.len)`
183 // - The if block ensures that the query iteration is not dense.
184 unsafe { self.fold_over_archetype_range(accum, func, archetype,range) };
185 }
186 }
187 accum
188 }
189
190 /// Executes the equivalent of [`Iterator::fold`] over a contiguous segment
191 /// from a table.
192 ///
193 /// # Safety
194 /// - all `rows` must be in `[0, table.entity_count)`.
195 /// - `table` must match D and F
196 /// - The query iteration must be dense (i.e. `self.query_state.is_dense` must be true).
197 #[inline]
198 pub(super) unsafe fn fold_over_table_range<B, Func>(
199 &mut self,
200 mut accum: B,
201 func: &mut Func,
202 table: &'w Table,
203 rows: Range<u32>,
204 ) -> B
205 where
206 Func: FnMut(B, D::Item<'w, 's>) -> B,
207 {
208 if table.is_empty() {
209 return accum;
210 }
211
212 D::set_table(&mut self.cursor.fetch, &self.query_state.fetch_state, table);
213 F::set_table(
214 &mut self.cursor.filter,
215 &self.query_state.filter_state,
216 table,
217 );
218
219 let entities = table.entities();
220 for row in rows {
221 // SAFETY: Caller assures `row` in range of the current archetype.
222 let entity = unsafe { entities.get_unchecked(row as usize) };
223 // SAFETY: This is from an exclusive range, so it can't be max.
224 let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(row)) };
225
226 // SAFETY: set_table was called prior.
227 // Caller assures `row` in range of the current archetype.
228 let fetched = unsafe {
229 !F::filter_fetch(
230 &self.query_state.filter_state,
231 &mut self.cursor.filter,
232 *entity,
233 row,
234 )
235 };
236 if fetched {
237 continue;
238 }
239
240 // SAFETY: set_table was called prior.
241 // Caller assures `row` in range of the current archetype.
242 if let Some(item) = D::fetch(
243 &self.query_state.fetch_state,
244 &mut self.cursor.fetch,
245 *entity,
246 row,
247 ) {
248 accum = func(accum, item);
249 }
250 }
251 accum
252 }
253
254 /// Executes the equivalent of [`Iterator::fold`] over a contiguous segment
255 /// from an archetype.
256 ///
257 /// # Safety
258 /// - all `indices` must be in `[0, archetype.len())`.
259 /// - `archetype` must match D and F
260 /// - The query iteration must not be dense (i.e. `self.query_state.is_dense` must be false).
261 #[inline]
262 pub(super) unsafe fn fold_over_archetype_range<B, Func>(
263 &mut self,
264 mut accum: B,
265 func: &mut Func,
266 archetype: &'w Archetype,
267 indices: Range<u32>,
268 ) -> B
269 where
270 Func: FnMut(B, D::Item<'w, 's>) -> B,
271 {
272 if archetype.is_empty() {
273 return accum;
274 }
275 let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();
276 D::set_archetype(
277 &mut self.cursor.fetch,
278 &self.query_state.fetch_state,
279 archetype,
280 table,
281 );
282 F::set_archetype(
283 &mut self.cursor.filter,
284 &self.query_state.filter_state,
285 archetype,
286 table,
287 );
288
289 let entities = archetype.entities();
290 for index in indices {
291 // SAFETY: Caller assures `index` in range of the current archetype.
292 let archetype_entity = unsafe { entities.get_unchecked(index as usize) };
293
294 // SAFETY: set_archetype was called prior.
295 // Caller assures `index` in range of the current archetype.
296 let fetched = unsafe {
297 !F::filter_fetch(
298 &self.query_state.filter_state,
299 &mut self.cursor.filter,
300 archetype_entity.id(),
301 archetype_entity.table_row(),
302 )
303 };
304 if fetched {
305 continue;
306 }
307
308 // SAFETY: set_archetype was called prior, `index` is an archetype index in range of the current archetype
309 // Caller assures `index` in range of the current archetype.
310 if let Some(item) = unsafe {
311 D::fetch(
312 &self.query_state.fetch_state,
313 &mut self.cursor.fetch,
314 archetype_entity.id(),
315 archetype_entity.table_row(),
316 )
317 } {
318 accum = func(accum, item);
319 }
320 }
321 accum
322 }
323
324 /// Executes the equivalent of [`Iterator::fold`] over a contiguous segment
325 /// from an archetype which has the same entity count as its table.
326 ///
327 /// # Safety
328 /// - all `indices` must be in `[0, archetype.len())`.
329 /// - `archetype` must match D and F
330 /// - `archetype` must have the same length as its table.
331 /// - The query iteration must not be dense (i.e. `self.query_state.is_dense` must be false).
332 #[inline]
333 pub(super) unsafe fn fold_over_dense_archetype_range<B, Func>(
334 &mut self,
335 mut accum: B,
336 func: &mut Func,
337 archetype: &'w Archetype,
338 rows: Range<u32>,
339 ) -> B
340 where
341 Func: FnMut(B, D::Item<'w, 's>) -> B,
342 {
343 if archetype.is_empty() {
344 return accum;
345 }
346 let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();
347 debug_assert!(
348 archetype.len() == table.entity_count(),
349 "archetype and its table must have the same length. "
350 );
351
352 D::set_archetype(
353 &mut self.cursor.fetch,
354 &self.query_state.fetch_state,
355 archetype,
356 table,
357 );
358 F::set_archetype(
359 &mut self.cursor.filter,
360 &self.query_state.filter_state,
361 archetype,
362 table,
363 );
364 let entities = table.entities();
365 for row in rows {
366 // SAFETY: Caller assures `row` in range of the current archetype.
367 let entity = unsafe { *entities.get_unchecked(row as usize) };
368 // SAFETY: This is from an exclusive range, so it can't be max.
369 let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(row)) };
370
371 // SAFETY: set_table was called prior.
372 // Caller assures `row` in range of the current archetype.
373 let filter_matched = unsafe {
374 F::filter_fetch(
375 &self.query_state.filter_state,
376 &mut self.cursor.filter,
377 entity,
378 row,
379 )
380 };
381 if !filter_matched {
382 continue;
383 }
384
385 // SAFETY: set_table was called prior.
386 // Caller assures `row` in range of the current archetype.
387 if let Some(item) = D::fetch(
388 &self.query_state.fetch_state,
389 &mut self.cursor.fetch,
390 entity,
391 row,
392 ) {
393 accum = func(accum, item);
394 }
395 }
396 accum
397 }
398
399 /// Sorts all query items into a new iterator, using the query lens as a key.
400 ///
401 /// This sort is stable (i.e., does not reorder equal elements).
402 ///
403 /// This uses [`slice::sort`] internally.
404 ///
405 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
406 /// This includes the allowed parameter type changes listed under [allowed transmutes].
407 /// However, the lens uses the filter of the original query when present.
408 ///
409 /// The sort is not cached across system runs.
410 ///
411 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
412 ///
413 /// # Panics
414 ///
415 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
416 ///
417 /// # Examples
418 /// ```rust
419 /// # use bevy_ecs::prelude::*;
420 /// # use std::{ops::{Deref, DerefMut}, iter::Sum};
421 /// #
422 /// # #[derive(Component)]
423 /// # struct PartMarker;
424 /// #
425 /// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
426 /// # struct PartIndex(usize);
427 /// #
428 /// # #[derive(Component, Clone, Copy)]
429 /// # struct PartValue(f32);
430 /// #
431 /// # impl Deref for PartValue {
432 /// # type Target = f32;
433 /// #
434 /// # fn deref(&self) -> &Self::Target {
435 /// # &self.0
436 /// # }
437 /// # }
438 /// #
439 /// # #[derive(Component)]
440 /// # struct ParentValue(f32);
441 /// #
442 /// # impl Deref for ParentValue {
443 /// # type Target = f32;
444 /// #
445 /// # fn deref(&self) -> &Self::Target {
446 /// # &self.0
447 /// # }
448 /// # }
449 /// #
450 /// # impl DerefMut for ParentValue {
451 /// # fn deref_mut(&mut self) -> &mut Self::Target {
452 /// # &mut self.0
453 /// # }
454 /// # }
455 /// #
456 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
457 /// # struct Length(usize);
458 /// #
459 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
460 /// # struct Width(usize);
461 /// #
462 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
463 /// # struct Height(usize);
464 /// #
465 /// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
466 /// # struct ParentEntity(Entity);
467 /// #
468 /// # #[derive(Component, Clone, Copy)]
469 /// # struct ChildPartCount(usize);
470 /// #
471 /// # impl Deref for ChildPartCount {
472 /// # type Target = usize;
473 /// #
474 /// # fn deref(&self) -> &Self::Target {
475 /// # &self.0
476 /// # }
477 /// # }
478 /// # let mut world = World::new();
479 /// // We can ensure that a query always returns in the same order.
480 /// fn system_1(query: Query<(Entity, &PartIndex)>) {
481 /// let parts: Vec<(Entity, &PartIndex)> = query.iter().sort::<&PartIndex>().collect();
482 /// }
483 ///
484 /// // We can freely rearrange query components in the key.
485 /// fn system_2(query: Query<(&Length, &Width, &Height), With<PartMarker>>) {
486 /// for (length, width, height) in query.iter().sort::<(&Height, &Length, &Width)>() {
487 /// println!("height: {height:?}, width: {width:?}, length: {length:?}")
488 /// }
489 /// }
490 ///
491 /// // We can sort by Entity without including it in the original Query.
492 /// // Here, we match iteration orders between query iterators.
493 /// fn system_3(
494 /// part_query: Query<(&PartValue, &ParentEntity)>,
495 /// mut parent_query: Query<(&ChildPartCount, &mut ParentValue)>,
496 /// ) {
497 /// let part_values = &mut part_query
498 /// .into_iter()
499 /// .sort::<&ParentEntity>()
500 /// .map(|(&value, parent_entity)| *value);
501 ///
502 /// for (&child_count, mut parent_value) in parent_query.iter_mut().sort::<Entity>() {
503 /// **parent_value = part_values.take(*child_count).sum();
504 /// }
505 /// }
506 /// #
507 /// # let mut schedule = Schedule::default();
508 /// # schedule.add_systems((system_1, system_2, system_3));
509 /// # schedule.run(&mut world);
510 /// ```
511 pub fn sort<L: ReadOnlyQueryData + 'w>(
512 self,
513 ) -> QuerySortedIter<
514 'w,
515 's,
516 D,
517 F,
518 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
519 >
520 where
521 for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,
522 {
523 self.sort_impl::<L>(|keyed_query| keyed_query.sort())
524 }
525
526 /// Sorts all query items into a new iterator, using the query lens as a key.
527 ///
528 /// This sort is unstable (i.e., may reorder equal elements).
529 ///
530 /// This uses [`slice::sort_unstable`] internally.
531 ///
532 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
533 /// This includes the allowed parameter type changes listed under [allowed transmutes]..
534 /// However, the lens uses the filter of the original query when present.
535 ///
536 /// The sort is not cached across system runs.
537 ///
538 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
539 ///
540 /// # Panics
541 ///
542 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
543 ///
544 /// # Example
545 /// ```
546 /// # use bevy_ecs::prelude::*;
547 /// #
548 /// # let mut world = World::new();
549 /// #
550 /// # #[derive(Component)]
551 /// # struct PartMarker;
552 /// #
553 /// #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
554 /// enum Flying {
555 /// Enabled,
556 /// Disabled
557 /// };
558 ///
559 /// // We perform an unstable sort by a Component with few values.
560 /// fn system_1(query: Query<&Flying, With<PartMarker>>) {
561 /// let part_values: Vec<&Flying> = query.iter().sort_unstable::<&Flying>().collect();
562 /// }
563 /// #
564 /// # let mut schedule = Schedule::default();
565 /// # schedule.add_systems((system_1));
566 /// # schedule.run(&mut world);
567 /// ```
568 pub fn sort_unstable<L: ReadOnlyQueryData + 'w>(
569 self,
570 ) -> QuerySortedIter<
571 'w,
572 's,
573 D,
574 F,
575 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
576 >
577 where
578 for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,
579 {
580 self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())
581 }
582
583 /// Sorts all query items into a new iterator with a comparator function over the query lens.
584 ///
585 /// This sort is stable (i.e., does not reorder equal elements).
586 ///
587 /// This uses [`slice::sort_by`] internally.
588 ///
589 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
590 /// This includes the allowed parameter type changes listed under [allowed transmutes].
591 /// However, the lens uses the filter of the original query when present.
592 ///
593 /// The sort is not cached across system runs.
594 ///
595 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
596 ///
597 /// # Panics
598 ///
599 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
600 ///
601 /// # Example
602 /// ```
603 /// # use bevy_ecs::prelude::*;
604 /// # use std::ops::Deref;
605 /// #
606 /// # impl Deref for PartValue {
607 /// # type Target = f32;
608 /// #
609 /// # fn deref(&self) -> &Self::Target {
610 /// # &self.0
611 /// # }
612 /// # }
613 /// #
614 /// # let mut world = World::new();
615 /// #
616 /// #[derive(Component)]
617 /// struct PartValue(f32);
618 ///
619 /// // We can use a cmp function on components do not implement Ord.
620 /// fn system_1(query: Query<&PartValue>) {
621 /// // Sort part values according to `f32::total_comp`.
622 /// let part_values: Vec<&PartValue> = query
623 /// .iter()
624 /// .sort_by::<&PartValue>(|value_1, value_2| value_1.total_cmp(*value_2))
625 /// .collect();
626 /// }
627 /// #
628 /// # let mut schedule = Schedule::default();
629 /// # schedule.add_systems((system_1));
630 /// # schedule.run(&mut world);
631 /// ```
632 pub fn sort_by<L: ReadOnlyQueryData + 'w>(
633 self,
634 mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,
635 ) -> QuerySortedIter<
636 'w,
637 's,
638 D,
639 F,
640 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
641 > {
642 self.sort_impl::<L>(move |keyed_query| {
643 keyed_query.sort_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));
644 })
645 }
646
647 /// Sorts all query items into a new iterator with a comparator function over the query lens.
648 ///
649 /// This sort is unstable (i.e., may reorder equal elements).
650 ///
651 /// This uses [`slice::sort_unstable_by`] internally.
652 ///
653 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
654 /// This includes the allowed parameter type changes listed under [allowed transmutes].
655 /// However, the lens uses the filter of the original query when present.
656 ///
657 /// The sort is not cached across system runs.
658 ///
659 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
660 ///
661 /// # Panics
662 ///
663 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
664 pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(
665 self,
666 mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,
667 ) -> QuerySortedIter<
668 'w,
669 's,
670 D,
671 F,
672 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
673 > {
674 self.sort_impl::<L>(move |keyed_query| {
675 keyed_query.sort_unstable_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));
676 })
677 }
678
679 /// Sorts all query items into a new iterator with a key extraction function over the query lens.
680 ///
681 /// This sort is stable (i.e., does not reorder equal elements).
682 ///
683 /// This uses [`slice::sort_by_key`] internally.
684 ///
685 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
686 /// This includes the allowed parameter type changes listed under [allowed transmutes].
687 /// However, the lens uses the filter of the original query when present.
688 ///
689 /// The sort is not cached across system runs.
690 ///
691 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
692 ///
693 /// # Panics
694 ///
695 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
696 ///
697 /// # Example
698 /// ```
699 /// # use bevy_ecs::prelude::*;
700 /// # use std::ops::Deref;
701 /// #
702 /// # #[derive(Component)]
703 /// # struct PartMarker;
704 /// #
705 /// # impl Deref for PartValue {
706 /// # type Target = f32;
707 /// #
708 /// # fn deref(&self) -> &Self::Target {
709 /// # &self.0
710 /// # }
711 /// # }
712 /// #
713 /// # let mut world = World::new();
714 /// #
715 /// #[derive(Component)]
716 /// struct AvailableMarker;
717 ///
718 /// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
719 /// enum Rarity {
720 /// Common,
721 /// Rare,
722 /// Epic,
723 /// Legendary
724 /// };
725 ///
726 /// #[derive(Component)]
727 /// struct PartValue(f32);
728 ///
729 /// // We can sort with the internals of components that do not implement Ord.
730 /// fn system_1(query: Query<(Entity, &PartValue)>) {
731 /// // Sort by the sines of the part values.
732 /// let parts: Vec<(Entity, &PartValue)> = query
733 /// .iter()
734 /// .sort_by_key::<&PartValue, _>(|value| value.sin() as usize)
735 /// .collect();
736 /// }
737 ///
738 /// // We can define our own custom comparison functions over an EntityRef.
739 /// fn system_2(query: Query<EntityRef, With<PartMarker>>) {
740 /// // Sort by whether parts are available and their rarity.
741 /// // We want the available legendaries to come first, so we reverse the iterator.
742 /// let parts: Vec<EntityRef> = query.iter()
743 /// .sort_by_key::<EntityRef, _>(|entity_ref| {
744 /// (
745 /// entity_ref.contains::<AvailableMarker>(),
746 /// entity_ref.get::<Rarity>().copied()
747 /// )
748 /// })
749 /// .rev()
750 /// .collect();
751 /// }
752 /// # let mut schedule = Schedule::default();
753 /// # schedule.add_systems((system_1, system_2));
754 /// # schedule.run(&mut world);
755 /// ```
756 pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(
757 self,
758 mut f: impl FnMut(&L::Item<'_, '_>) -> K,
759 ) -> QuerySortedIter<
760 'w,
761 's,
762 D,
763 F,
764 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
765 >
766 where
767 K: Ord,
768 {
769 self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_key(|(lens, _)| f(lens)))
770 }
771
772 /// Sorts all query items into a new iterator with a key extraction function over the query lens.
773 ///
774 /// This sort is unstable (i.e., may reorder equal elements).
775 ///
776 /// This uses [`slice::sort_unstable_by_key`] internally.
777 ///
778 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
779 /// This includes the allowed parameter type changes listed under [allowed transmutes].
780 /// However, the lens uses the filter of the original query when present.
781 ///
782 /// The sort is not cached across system runs.
783 ///
784 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
785 ///
786 /// # Panics
787 ///
788 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
789 pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(
790 self,
791 mut f: impl FnMut(&L::Item<'_, '_>) -> K,
792 ) -> QuerySortedIter<
793 'w,
794 's,
795 D,
796 F,
797 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
798 >
799 where
800 K: Ord,
801 {
802 self.sort_impl::<L>(move |keyed_query| {
803 keyed_query.sort_unstable_by_key(|(lens, _)| f(lens));
804 })
805 }
806
807 /// Sort all query items into a new iterator with a key extraction function over the query lens.
808 ///
809 /// This sort is stable (i.e., does not reorder equal elements).
810 ///
811 /// This uses [`slice::sort_by_cached_key`] internally.
812 ///
813 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
814 /// This includes the allowed parameter type changes listed under [allowed transmutes].
815 /// However, the lens uses the filter of the original query when present.
816 ///
817 /// The sort is not cached across system runs.
818 ///
819 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
820 ///
821 /// # Panics
822 ///
823 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
824 pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(
825 self,
826 mut f: impl FnMut(&L::Item<'_, '_>) -> K,
827 ) -> QuerySortedIter<
828 'w,
829 's,
830 D,
831 F,
832 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
833 >
834 where
835 K: Ord,
836 {
837 self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_cached_key(|(lens, _)| f(lens)))
838 }
839
840 /// Shared implementation for the various `sort` methods.
841 /// This uses the lens to collect the items for sorting, but delegates the actual sorting to the provided closure.
842 ///
843 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
844 /// This includes the allowed parameter type changes listed under [allowed transmutes].
845 /// However, the lens uses the filter of the original query when present.
846 ///
847 /// The sort is not cached across system runs.
848 ///
849 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
850 ///
851 /// # Panics
852 ///
853 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
854 fn sort_impl<L: ReadOnlyQueryData + 'w>(
855 self,
856 f: impl FnOnce(&mut Vec<(L::Item<'_, '_>, NeutralOrd<Entity>)>),
857 ) -> QuerySortedIter<
858 'w,
859 's,
860 D,
861 F,
862 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
863 > {
864 // On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`
865 // will be set to a non-zero value. The correctness of this method relies on this.
866 // I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a
867 // non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.
868 if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {
869 panic!("it is not valid to call sort() after next()")
870 }
871
872 let world = self.world;
873
874 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
875
876 // SAFETY:
877 // `self.world` has permission to access the required components.
878 // The original query iter has not been iterated on, so no items are aliased from it.
879 // `QueryIter::new` ensures `world` is the same one used to initialize `query_state`.
880 let query_lens = unsafe { query_lens_state.query_unchecked_manual(world) }.into_iter();
881 let mut keyed_query: Vec<_> = query_lens
882 .map(|(key, entity)| (key, NeutralOrd(entity)))
883 .collect();
884 f(&mut keyed_query);
885 let entity_iter = keyed_query
886 .into_iter()
887 .map(|(.., entity)| entity.0)
888 .collect::<Vec<_>>()
889 .into_iter();
890 // SAFETY:
891 // `self.world` has permission to access the required components.
892 // Each lens query item is dropped before the respective actual query item is accessed.
893 unsafe {
894 QuerySortedIter::new(
895 world,
896 self.query_state,
897 entity_iter,
898 world.last_change_tick(),
899 world.change_tick(),
900 )
901 }
902 }
903}
904
905impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F> {
906 type Item = D::Item<'w, 's>;
907
908 #[inline(always)]
909 fn next(&mut self) -> Option<Self::Item> {
910 // SAFETY:
911 // `tables` and `archetypes` belong to the same world that the cursor was initialized for.
912 // `query_state` is the state that was passed to `QueryIterationCursor::init`.
913 unsafe {
914 self.cursor
915 .next(self.tables, self.archetypes, self.query_state)
916 }
917 }
918
919 fn size_hint(&self) -> (usize, Option<usize>) {
920 let max_size = self.cursor.max_remaining(self.tables, self.archetypes);
921 let archetype_query = D::IS_ARCHETYPAL && F::IS_ARCHETYPAL;
922 let min_size = if archetype_query { max_size } else { 0 };
923 (min_size as usize, Some(max_size as usize))
924 }
925
926 #[inline]
927 fn fold<B, Func>(mut self, init: B, mut func: Func) -> B
928 where
929 Func: FnMut(B, Self::Item) -> B,
930 {
931 let mut accum = init;
932 // Empty any remaining uniterated values from the current table/archetype
933 while self.cursor.current_row != self.cursor.current_len {
934 let Some(item) = self.next() else { break };
935 accum = func(accum, item);
936 }
937
938 for id in self.cursor.storage_id_iter.clone().copied() {
939 // SAFETY:
940 // - The range(None) is equivalent to [0, storage.entity_count)
941 accum = unsafe { self.fold_over_storage_range(accum, &mut func, id, None) };
942 }
943 accum
944 }
945}
946
947// This is correct as [`QueryIter`] always returns `None` once exhausted.
948impl<'w, 's, D: QueryData, F: QueryFilter> FusedIterator for QueryIter<'w, 's, D, F> {}
949
950// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.
951unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator for QueryIter<'w, 's, Entity, F> {}
952
953// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.
954unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator for QueryIter<'w, 's, EntityRef<'_>, F> {}
955
956// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.
957unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator for QueryIter<'w, 's, EntityMut<'_>, F> {}
958
959// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.
960unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator
961 for QueryIter<'w, 's, FilteredEntityRef<'_, '_>, F>
962{
963}
964
965// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.
966unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator
967 for QueryIter<'w, 's, FilteredEntityMut<'_, '_>, F>
968{
969}
970
971// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.
972unsafe impl<'w, 's, F: QueryFilter, B: Bundle> EntitySetIterator
973 for QueryIter<'w, 's, EntityRefExcept<'_, '_, B>, F>
974{
975}
976
977// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.
978unsafe impl<'w, 's, F: QueryFilter, B: Bundle> EntitySetIterator
979 for QueryIter<'w, 's, EntityMutExcept<'_, '_, B>, F>
980{
981}
982
983impl<'w, 's, D: QueryData, F: QueryFilter> Debug for QueryIter<'w, 's, D, F> {
984 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
985 f.debug_struct("QueryIter").finish()
986 }
987}
988
989impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Clone for QueryIter<'w, 's, D, F> {
990 fn clone(&self) -> Self {
991 self.remaining()
992 }
993}
994
995/// An [`Iterator`] over sorted query results of a [`Query`](crate::system::Query).
996///
997/// This struct is created by the [`QueryIter::sort`], [`QueryIter::sort_unstable`],
998/// [`QueryIter::sort_by`], [`QueryIter::sort_unstable_by`], [`QueryIter::sort_by_key`],
999/// [`QueryIter::sort_unstable_by_key`], and [`QueryIter::sort_by_cached_key`] methods.
1000pub struct QuerySortedIter<'w, 's, D: QueryData, F: QueryFilter, I>
1001where
1002 I: Iterator<Item = Entity>,
1003{
1004 entity_iter: I,
1005 entities: &'w Entities,
1006 tables: &'w Tables,
1007 archetypes: &'w Archetypes,
1008 fetch: D::Fetch<'w>,
1009 query_state: &'s QueryState<D, F>,
1010}
1011
1012impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> QuerySortedIter<'w, 's, D, F, I>
1013where
1014 I: Iterator<Item = Entity>,
1015{
1016 /// # Safety
1017 /// - `world` must have permission to access any of the components registered in `query_state`.
1018 /// - `world` must be the same one used to initialize `query_state`.
1019 /// - `entity_list` must only contain unique entities or be empty.
1020 pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(
1021 world: UnsafeWorldCell<'w>,
1022 query_state: &'s QueryState<D, F>,
1023 entity_list: EntityList,
1024 last_run: Tick,
1025 this_run: Tick,
1026 ) -> QuerySortedIter<'w, 's, D, F, I> {
1027 let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
1028 QuerySortedIter {
1029 query_state,
1030 entities: world.entities(),
1031 archetypes: world.archetypes(),
1032 // SAFETY: We only access table data that has been registered in `query_state`.
1033 // This means `world` has permission to access the data we use.
1034 tables: &world.storages().tables,
1035 fetch,
1036 entity_iter: entity_list.into_iter(),
1037 }
1038 }
1039
1040 /// # Safety
1041 /// `entity` must stem from `self.entity_iter`, and not have been passed before.
1042 #[inline(always)]
1043 unsafe fn fetch_next(&mut self, entity: Entity) -> Option<D::Item<'w, 's>> {
1044 let (location, archetype, table);
1045 // SAFETY:
1046 // `tables` and `archetypes` belong to the same world that the [`QueryIter`]
1047 // was initialized for.
1048 unsafe {
1049 location = self.entities.get_spawned(entity).debug_checked_unwrap();
1050 archetype = self
1051 .archetypes
1052 .get(location.archetype_id)
1053 .debug_checked_unwrap();
1054 table = self.tables.get(location.table_id).debug_checked_unwrap();
1055 }
1056
1057 // SAFETY: `archetype` is from the world that `fetch` was created for,
1058 // `fetch_state` is the state that `fetch` was initialized with
1059 unsafe {
1060 D::set_archetype(
1061 &mut self.fetch,
1062 &self.query_state.fetch_state,
1063 archetype,
1064 table,
1065 );
1066 }
1067
1068 // The entity list has already been filtered by the query lens, so we forego filtering here.
1069 // SAFETY:
1070 // - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
1071 // - fetch is only called once for each entity.
1072 unsafe {
1073 D::fetch(
1074 &self.query_state.fetch_state,
1075 &mut self.fetch,
1076 entity,
1077 location.table_row,
1078 )
1079 }
1080 }
1081}
1082
1083impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> Iterator
1084 for QuerySortedIter<'w, 's, D, F, I>
1085where
1086 I: Iterator<Item = Entity>,
1087{
1088 type Item = D::Item<'w, 's>;
1089
1090 #[inline(always)]
1091 fn next(&mut self) -> Option<Self::Item> {
1092 while let Some(entity) = self.entity_iter.next() {
1093 // SAFETY: `entity` is passed from `entity_iter` the first time.
1094 if let Some(item) = unsafe { self.fetch_next(entity) } {
1095 return Some(item);
1096 }
1097 }
1098 None
1099 }
1100
1101 fn size_hint(&self) -> (usize, Option<usize>) {
1102 let (min_size, max_size) = self.entity_iter.size_hint();
1103 let archetype_query = D::IS_ARCHETYPAL;
1104 let min_size = if archetype_query { min_size } else { 0 };
1105 (min_size, max_size)
1106 }
1107}
1108
1109impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> DoubleEndedIterator
1110 for QuerySortedIter<'w, 's, D, F, I>
1111where
1112 I: DoubleEndedIterator<Item = Entity>,
1113{
1114 #[inline(always)]
1115 fn next_back(&mut self) -> Option<Self::Item> {
1116 while let Some(entity) = self.entity_iter.next_back() {
1117 // SAFETY: `entity` is passed from `entity_iter` the first time.
1118 if let Some(item) = unsafe { self.fetch_next(entity) } {
1119 return Some(item);
1120 }
1121 }
1122 None
1123 }
1124}
1125
1126impl<D: ArchetypeQueryData, F: QueryFilter, I: ExactSizeIterator<Item = Entity>> ExactSizeIterator
1127 for QuerySortedIter<'_, '_, D, F, I>
1128{
1129}
1130
1131// This is correct as [`QuerySortedIter`] returns `None` once exhausted if `entity_iter` does.
1132impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> FusedIterator
1133 for QuerySortedIter<'w, 's, D, F, I>
1134where
1135 I: FusedIterator<Item = Entity>,
1136{
1137}
1138
1139// SAFETY:
1140// `I` stems from a collected and sorted `EntitySetIterator` ([`QueryIter`]).
1141// Fetching unique entities maintains uniqueness.
1142unsafe impl<'w, 's, F: QueryFilter, I: Iterator<Item = Entity>> EntitySetIterator
1143 for QuerySortedIter<'w, 's, Entity, F, I>
1144{
1145}
1146
1147impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> Debug
1148 for QuerySortedIter<'w, 's, D, F, I>
1149{
1150 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1151 f.debug_struct("QuerySortedIter").finish()
1152 }
1153}
1154
1155/// An [`Iterator`] over the query items generated from an iterator of [`Entity`]s.
1156///
1157/// Items are returned in the order of the provided iterator.
1158/// Entities that don't match the query are skipped.
1159///
1160/// This struct is created by the [`Query::iter_many`](crate::system::Query::iter_many) and [`Query::iter_many_mut`](crate::system::Query::iter_many_mut) methods.
1161pub struct QueryManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
1162{
1163 world: UnsafeWorldCell<'w>,
1164 entity_iter: I,
1165 entities: &'w Entities,
1166 tables: &'w Tables,
1167 archetypes: &'w Archetypes,
1168 fetch: D::Fetch<'w>,
1169 filter: F::Fetch<'w>,
1170 query_state: &'s QueryState<D, F>,
1171}
1172
1173impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
1174 QueryManyIter<'w, 's, D, F, I>
1175{
1176 /// # Safety
1177 /// - `world` must have permission to access any of the components registered in `query_state`.
1178 /// - `world` must be the same one used to initialize `query_state`.
1179 pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(
1180 world: UnsafeWorldCell<'w>,
1181 query_state: &'s QueryState<D, F>,
1182 entity_list: EntityList,
1183 last_run: Tick,
1184 this_run: Tick,
1185 ) -> QueryManyIter<'w, 's, D, F, I> {
1186 let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
1187 let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);
1188 QueryManyIter {
1189 world,
1190 query_state,
1191 entities: world.entities(),
1192 archetypes: world.archetypes(),
1193 // SAFETY: We only access table data that has been registered in `query_state`.
1194 // This means `world` has permission to access the data we use.
1195 tables: &world.storages().tables,
1196 fetch,
1197 filter,
1198 entity_iter: entity_list.into_iter(),
1199 }
1200 }
1201
1202 /// # Safety
1203 /// All arguments must stem from the same valid `QueryManyIter`.
1204 ///
1205 /// The lifetime here is not restrictive enough for Fetch with &mut access,
1206 /// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple
1207 /// references to the same component, leading to unique reference aliasing.
1208 ///
1209 /// It is always safe for shared access.
1210 #[inline(always)]
1211 unsafe fn fetch_next_aliased_unchecked(
1212 entity_iter: impl Iterator<Item: EntityEquivalent>,
1213 entities: &'w Entities,
1214 tables: &'w Tables,
1215 archetypes: &'w Archetypes,
1216 fetch: &mut D::Fetch<'w>,
1217 filter: &mut F::Fetch<'w>,
1218 query_state: &'s QueryState<D, F>,
1219 ) -> Option<D::Item<'w, 's>> {
1220 for entity_borrow in entity_iter {
1221 let entity = entity_borrow.entity();
1222 let Ok(location) = entities.get_spawned(entity) else {
1223 continue;
1224 };
1225
1226 if !query_state
1227 .matched_archetypes
1228 .contains(location.archetype_id.index())
1229 {
1230 continue;
1231 }
1232
1233 let archetype = archetypes.get(location.archetype_id).debug_checked_unwrap();
1234 let table = tables.get(location.table_id).debug_checked_unwrap();
1235
1236 // SAFETY: `archetype` is from the world that `fetch/filter` were created for,
1237 // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
1238 unsafe {
1239 D::set_archetype(fetch, &query_state.fetch_state, archetype, table);
1240 }
1241 // SAFETY: `table` is from the world that `fetch/filter` were created for,
1242 // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
1243 unsafe {
1244 F::set_archetype(filter, &query_state.filter_state, archetype, table);
1245 }
1246
1247 // SAFETY: set_archetype was called prior.
1248 // `location.archetype_row` is an archetype index row in range of the current archetype, because if it was not, the match above would have `continue`d
1249 if unsafe {
1250 F::filter_fetch(
1251 &query_state.filter_state,
1252 filter,
1253 entity,
1254 location.table_row,
1255 )
1256 } {
1257 // SAFETY:
1258 // - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
1259 // - fetch is only called once for each entity.
1260 let item = unsafe {
1261 D::fetch(&query_state.fetch_state, fetch, entity, location.table_row)
1262 };
1263 if let Some(item) = item {
1264 return Some(item);
1265 }
1266 }
1267 }
1268 None
1269 }
1270
1271 /// Get next result from the query
1272 #[inline(always)]
1273 pub fn fetch_next(&mut self) -> Option<D::Item<'_, 's>> {
1274 // SAFETY:
1275 // All arguments stem from self.
1276 // We are limiting the returned reference to self,
1277 // making sure this method cannot be called multiple times without getting rid
1278 // of any previously returned unique references first, thus preventing aliasing.
1279 unsafe {
1280 Self::fetch_next_aliased_unchecked(
1281 &mut self.entity_iter,
1282 self.entities,
1283 self.tables,
1284 self.archetypes,
1285 &mut self.fetch,
1286 &mut self.filter,
1287 self.query_state,
1288 )
1289 .map(D::shrink)
1290 }
1291 }
1292
1293 /// Sorts all query items into a new iterator, using the query lens as a key.
1294 ///
1295 /// This sort is stable (i.e., does not reorder equal elements).
1296 ///
1297 /// This uses [`slice::sort`] internally.
1298 ///
1299 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
1300 /// This includes the allowed parameter type changes listed under [allowed transmutes].
1301 /// However, the lens uses the filter of the original query when present.
1302 ///
1303 /// The sort is not cached across system runs.
1304 ///
1305 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1306 ///
1307 /// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been
1308 /// called on [`QueryManyIter`] before.
1309 ///
1310 /// # Examples
1311 /// ```rust
1312 /// # use bevy_ecs::prelude::*;
1313 /// # use std::{ops::{Deref, DerefMut}, iter::Sum};
1314 /// #
1315 /// # #[derive(Component)]
1316 /// # struct PartMarker;
1317 /// #
1318 /// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
1319 /// # struct PartIndex(usize);
1320 /// #
1321 /// # #[derive(Component, Clone, Copy)]
1322 /// # struct PartValue(usize);
1323 /// #
1324 /// # impl Deref for PartValue {
1325 /// # type Target = usize;
1326 /// #
1327 /// # fn deref(&self) -> &Self::Target {
1328 /// # &self.0
1329 /// # }
1330 /// # }
1331 /// #
1332 /// # impl DerefMut for PartValue {
1333 /// # fn deref_mut(&mut self) -> &mut Self::Target {
1334 /// # &mut self.0
1335 /// # }
1336 /// # }
1337 /// #
1338 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
1339 /// # struct Length(usize);
1340 /// #
1341 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
1342 /// # struct Width(usize);
1343 /// #
1344 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
1345 /// # struct Height(usize);
1346 /// #
1347 /// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
1348 /// # struct ParentEntity(Entity);
1349 /// #
1350 /// # let mut world = World::new();
1351 /// // We can ensure that a query always returns in the same order.
1352 /// fn system_1(query: Query<(Entity, &PartIndex)>) {
1353 /// # let entity_list: Vec<Entity> = Vec::new();
1354 /// let parts: Vec<(Entity, &PartIndex)> = query.iter_many(entity_list).sort::<&PartIndex>().collect();
1355 /// }
1356 ///
1357 /// // We can freely rearrange query components in the key.
1358 /// fn system_2(query: Query<(&Length, &Width, &Height), With<PartMarker>>) {
1359 /// # let entity_list: Vec<Entity> = Vec::new();
1360 /// for (length, width, height) in query.iter_many(entity_list).sort::<(&Height, &Length, &Width)>() {
1361 /// println!("height: {height:?}, width: {width:?}, length: {length:?}")
1362 /// }
1363 /// }
1364 ///
1365 /// // You can use `fetch_next_back` to obtain mutable references in reverse order.
1366 /// fn system_3(
1367 /// mut query: Query<&mut PartValue>,
1368 /// ) {
1369 /// # let entity_list: Vec<Entity> = Vec::new();
1370 /// // We need to collect the internal iterator before iterating mutably
1371 /// let mut parent_query_iter = query.iter_many_mut(entity_list)
1372 /// .sort::<Entity>();
1373 ///
1374 /// let mut scratch_value = 0;
1375 /// while let Some(mut part_value) = parent_query_iter.fetch_next_back()
1376 /// {
1377 /// // some order-dependent operation, here bitwise XOR
1378 /// **part_value ^= scratch_value;
1379 /// scratch_value = **part_value;
1380 /// }
1381 /// }
1382 /// #
1383 /// # let mut schedule = Schedule::default();
1384 /// # schedule.add_systems((system_1, system_2, system_3));
1385 /// # schedule.run(&mut world);
1386 /// ```
1387 pub fn sort<L: ReadOnlyQueryData + 'w>(
1388 self,
1389 ) -> QuerySortedManyIter<
1390 'w,
1391 's,
1392 D,
1393 F,
1394 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1395 >
1396 where
1397 for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,
1398 {
1399 self.sort_impl::<L>(|keyed_query| keyed_query.sort())
1400 }
1401
1402 /// Sorts all query items into a new iterator, using the query lens as a key.
1403 ///
1404 /// This sort is unstable (i.e., may reorder equal elements).
1405 ///
1406 /// This uses [`slice::sort_unstable`] internally.
1407 ///
1408 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
1409 /// This includes the allowed parameter type changes listed under [allowed transmutes]..
1410 /// However, the lens uses the filter of the original query when present.
1411 ///
1412 /// The sort is not cached across system runs.
1413 ///
1414 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1415 ///
1416 /// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been
1417 /// called on [`QueryManyIter`] before.
1418 ///
1419 /// # Example
1420 /// ```
1421 /// # use bevy_ecs::prelude::*;
1422 /// #
1423 /// # let mut world = World::new();
1424 /// #
1425 /// # #[derive(Component)]
1426 /// # struct PartMarker;
1427 /// #
1428 /// # let entity_list: Vec<Entity> = Vec::new();
1429 /// #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
1430 /// enum Flying {
1431 /// Enabled,
1432 /// Disabled
1433 /// };
1434 ///
1435 /// // We perform an unstable sort by a Component with few values.
1436 /// fn system_1(query: Query<&Flying, With<PartMarker>>) {
1437 /// # let entity_list: Vec<Entity> = Vec::new();
1438 /// let part_values: Vec<&Flying> = query.iter_many(entity_list).sort_unstable::<&Flying>().collect();
1439 /// }
1440 /// #
1441 /// # let mut schedule = Schedule::default();
1442 /// # schedule.add_systems((system_1));
1443 /// # schedule.run(&mut world);
1444 /// ```
1445 pub fn sort_unstable<L: ReadOnlyQueryData + 'w>(
1446 self,
1447 ) -> QuerySortedManyIter<
1448 'w,
1449 's,
1450 D,
1451 F,
1452 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1453 >
1454 where
1455 for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,
1456 {
1457 self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())
1458 }
1459
1460 /// Sorts all query items into a new iterator with a comparator function over the query lens.
1461 ///
1462 /// This sort is stable (i.e., does not reorder equal elements).
1463 ///
1464 /// This uses [`slice::sort_by`] internally.
1465 ///
1466 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
1467 /// This includes the allowed parameter type changes listed under [allowed transmutes].
1468 /// However, the lens uses the filter of the original query when present.
1469 ///
1470 /// The sort is not cached across system runs.
1471 ///
1472 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1473 ///
1474 /// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been
1475 /// called on [`QueryManyIter`] before.
1476 ///
1477 /// # Example
1478 /// ```
1479 /// # use bevy_ecs::prelude::*;
1480 /// # use std::ops::Deref;
1481 /// #
1482 /// # impl Deref for PartValue {
1483 /// # type Target = f32;
1484 /// #
1485 /// # fn deref(&self) -> &Self::Target {
1486 /// # &self.0
1487 /// # }
1488 /// # }
1489 /// #
1490 /// # let mut world = World::new();
1491 /// # let entity_list: Vec<Entity> = Vec::new();
1492 /// #
1493 /// #[derive(Component)]
1494 /// struct PartValue(f32);
1495 ///
1496 /// // We can use a cmp function on components do not implement Ord.
1497 /// fn system_1(query: Query<&PartValue>) {
1498 /// # let entity_list: Vec<Entity> = Vec::new();
1499 /// // Sort part values according to `f32::total_comp`.
1500 /// let part_values: Vec<&PartValue> = query
1501 /// .iter_many(entity_list)
1502 /// .sort_by::<&PartValue>(|value_1, value_2| value_1.total_cmp(*value_2))
1503 /// .collect();
1504 /// }
1505 /// #
1506 /// # let mut schedule = Schedule::default();
1507 /// # schedule.add_systems((system_1));
1508 /// # schedule.run(&mut world);
1509 /// ```
1510 pub fn sort_by<L: ReadOnlyQueryData + 'w>(
1511 self,
1512 mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,
1513 ) -> QuerySortedManyIter<
1514 'w,
1515 's,
1516 D,
1517 F,
1518 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1519 > {
1520 self.sort_impl::<L>(move |keyed_query| {
1521 keyed_query.sort_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));
1522 })
1523 }
1524
1525 /// Sorts all query items into a new iterator with a comparator function over the query lens.
1526 ///
1527 /// This sort is unstable (i.e., may reorder equal elements).
1528 ///
1529 /// This uses [`slice::sort_unstable_by`] internally.
1530 ///
1531 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
1532 /// This includes the allowed parameter type changes listed under [allowed transmutes].
1533 /// However, the lens uses the filter of the original query when present.
1534 ///
1535 /// The sort is not cached across system runs.
1536 ///
1537 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1538 ///
1539 /// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been
1540 /// called on [`QueryManyIter`] before.
1541 pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(
1542 self,
1543 mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,
1544 ) -> QuerySortedManyIter<
1545 'w,
1546 's,
1547 D,
1548 F,
1549 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1550 > {
1551 self.sort_impl::<L>(move |keyed_query| {
1552 keyed_query.sort_unstable_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));
1553 })
1554 }
1555
1556 /// Sorts all query items into a new iterator with a key extraction function over the query lens.
1557 ///
1558 /// This sort is stable (i.e., does not reorder equal elements).
1559 ///
1560 /// This uses [`slice::sort_by_key`] internally.
1561 ///
1562 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
1563 /// This includes the allowed parameter type changes listed under [allowed transmutes].
1564 /// However, the lens uses the filter of the original query when present.
1565 ///
1566 /// The sort is not cached across system runs.
1567 ///
1568 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1569 ///
1570 /// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been
1571 /// called on [`QueryManyIter`] before.
1572 ///
1573 /// # Example
1574 /// ```
1575 /// # use bevy_ecs::prelude::*;
1576 /// # use std::ops::Deref;
1577 /// #
1578 /// # #[derive(Component)]
1579 /// # struct PartMarker;
1580 /// #
1581 /// # impl Deref for PartValue {
1582 /// # type Target = f32;
1583 /// #
1584 /// # fn deref(&self) -> &Self::Target {
1585 /// # &self.0
1586 /// # }
1587 /// # }
1588 /// #
1589 /// # let mut world = World::new();
1590 /// # let entity_list: Vec<Entity> = Vec::new();
1591 /// #
1592 /// #[derive(Component)]
1593 /// struct AvailableMarker;
1594 ///
1595 /// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
1596 /// enum Rarity {
1597 /// Common,
1598 /// Rare,
1599 /// Epic,
1600 /// Legendary
1601 /// };
1602 ///
1603 /// #[derive(Component)]
1604 /// struct PartValue(f32);
1605 ///
1606 /// // We can sort with the internals of components that do not implement Ord.
1607 /// fn system_1(query: Query<(Entity, &PartValue)>) {
1608 /// # let entity_list: Vec<Entity> = Vec::new();
1609 /// // Sort by the sines of the part values.
1610 /// let parts: Vec<(Entity, &PartValue)> = query
1611 /// .iter_many(entity_list)
1612 /// .sort_by_key::<&PartValue, _>(|value| value.sin() as usize)
1613 /// .collect();
1614 /// }
1615 ///
1616 /// // We can define our own custom comparison functions over an EntityRef.
1617 /// fn system_2(query: Query<EntityRef, With<PartMarker>>) {
1618 /// # let entity_list: Vec<Entity> = Vec::new();
1619 /// // Sort by whether parts are available and their rarity.
1620 /// // We want the available legendaries to come first, so we reverse the iterator.
1621 /// let parts: Vec<EntityRef> = query.iter_many(entity_list)
1622 /// .sort_by_key::<EntityRef, _>(|entity_ref| {
1623 /// (
1624 /// entity_ref.contains::<AvailableMarker>(),
1625 // entity_ref.get::<Rarity>().copied()
1626 /// )
1627 /// })
1628 /// .rev()
1629 /// .collect();
1630 /// }
1631 /// # let mut schedule = Schedule::default();
1632 /// # schedule.add_systems((system_1, system_2));
1633 /// # schedule.run(&mut world);
1634 /// ```
1635 pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(
1636 self,
1637 mut f: impl FnMut(&L::Item<'_, '_>) -> K,
1638 ) -> QuerySortedManyIter<
1639 'w,
1640 's,
1641 D,
1642 F,
1643 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1644 >
1645 where
1646 K: Ord,
1647 {
1648 self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_key(|(lens, _)| f(lens)))
1649 }
1650
1651 /// Sorts all query items into a new iterator with a key extraction function over the query lens.
1652 ///
1653 /// This sort is unstable (i.e., may reorder equal elements).
1654 ///
1655 /// This uses [`slice::sort_unstable_by_key`] internally.
1656 ///
1657 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
1658 /// This includes the allowed parameter type changes listed under [allowed transmutes].
1659 /// However, the lens uses the filter of the original query when present.
1660 ///
1661 /// The sort is not cached across system runs.
1662 ///
1663 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1664 ///
1665 /// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been
1666 /// called on [`QueryManyIter`] before.
1667 pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(
1668 self,
1669 mut f: impl FnMut(&L::Item<'_, '_>) -> K,
1670 ) -> QuerySortedManyIter<
1671 'w,
1672 's,
1673 D,
1674 F,
1675 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1676 >
1677 where
1678 K: Ord,
1679 {
1680 self.sort_impl::<L>(move |keyed_query| {
1681 keyed_query.sort_unstable_by_key(|(lens, _)| f(lens));
1682 })
1683 }
1684
1685 /// Sort all query items into a new iterator with a key extraction function over the query lens.
1686 ///
1687 /// This sort is stable (i.e., does not reorder equal elements).
1688 ///
1689 /// This uses [`slice::sort_by_cached_key`] internally.
1690 ///
1691 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
1692 /// This includes the allowed parameter type changes listed under [allowed transmutes].
1693 /// However, the lens uses the filter of the original query when present.
1694 ///
1695 /// The sort is not cached across system runs.
1696 ///
1697 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1698 ///
1699 /// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been
1700 /// called on [`QueryManyIter`] before.
1701 pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(
1702 self,
1703 mut f: impl FnMut(&L::Item<'_, '_>) -> K,
1704 ) -> QuerySortedManyIter<
1705 'w,
1706 's,
1707 D,
1708 F,
1709 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1710 >
1711 where
1712 K: Ord,
1713 {
1714 self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_cached_key(|(lens, _)| f(lens)))
1715 }
1716
1717 /// Shared implementation for the various `sort` methods.
1718 /// This uses the lens to collect the items for sorting, but delegates the actual sorting to the provided closure.
1719 ///
1720 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
1721 /// This includes the allowed parameter type changes listed under [allowed transmutes].
1722 /// However, the lens uses the filter of the original query when present.
1723 ///
1724 /// The sort is not cached across system runs.
1725 ///
1726 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1727 ///
1728 /// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been
1729 /// called on [`QueryManyIter`] before.
1730 fn sort_impl<L: ReadOnlyQueryData + 'w>(
1731 self,
1732 f: impl FnOnce(&mut Vec<(L::Item<'_, '_>, NeutralOrd<Entity>)>),
1733 ) -> QuerySortedManyIter<
1734 'w,
1735 's,
1736 D,
1737 F,
1738 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1739 > {
1740 let world = self.world;
1741
1742 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
1743
1744 // SAFETY:
1745 // `self.world` has permission to access the required components.
1746 // The original query iter has not been iterated on, so no items are aliased from it.
1747 // `QueryIter::new` ensures `world` is the same one used to initialize `query_state`.
1748 let query_lens = unsafe { query_lens_state.query_unchecked_manual(world) }
1749 .iter_many_inner(self.entity_iter);
1750 let mut keyed_query: Vec<_> = query_lens
1751 .map(|(key, entity)| (key, NeutralOrd(entity)))
1752 .collect();
1753 f(&mut keyed_query);
1754 // Re-collect into a `Vec` to eagerly drop the lens items.
1755 // They must be dropped before `fetch_next` is called since they may alias
1756 // with other data items if there are duplicate entities in `entity_iter`.
1757 let entity_iter = keyed_query
1758 .into_iter()
1759 .map(|(.., entity)| entity.0)
1760 .collect::<Vec<_>>()
1761 .into_iter();
1762 // SAFETY:
1763 // `self.world` has permission to access the required components.
1764 // Each lens query item is dropped before the respective actual query item is accessed.
1765 unsafe {
1766 QuerySortedManyIter::new(
1767 world,
1768 self.query_state,
1769 entity_iter,
1770 world.last_change_tick(),
1771 world.change_tick(),
1772 )
1773 }
1774 }
1775}
1776
1777impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item: EntityEquivalent>>
1778 QueryManyIter<'w, 's, D, F, I>
1779{
1780 /// Get next result from the back of the query
1781 #[inline(always)]
1782 pub fn fetch_next_back(&mut self) -> Option<D::Item<'_, 's>> {
1783 // SAFETY:
1784 // All arguments stem from self.
1785 // We are limiting the returned reference to self,
1786 // making sure this method cannot be called multiple times without getting rid
1787 // of any previously returned unique references first, thus preventing aliasing.
1788 unsafe {
1789 Self::fetch_next_aliased_unchecked(
1790 self.entity_iter.by_ref().rev(),
1791 self.entities,
1792 self.tables,
1793 self.archetypes,
1794 &mut self.fetch,
1795 &mut self.filter,
1796 self.query_state,
1797 )
1798 .map(D::shrink)
1799 }
1800 }
1801}
1802
1803impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>> Iterator
1804 for QueryManyIter<'w, 's, D, F, I>
1805{
1806 type Item = D::Item<'w, 's>;
1807
1808 #[inline(always)]
1809 fn next(&mut self) -> Option<Self::Item> {
1810 // SAFETY:
1811 // All arguments stem from self.
1812 // It is safe to alias for ReadOnlyWorldQuery.
1813 unsafe {
1814 Self::fetch_next_aliased_unchecked(
1815 &mut self.entity_iter,
1816 self.entities,
1817 self.tables,
1818 self.archetypes,
1819 &mut self.fetch,
1820 &mut self.filter,
1821 self.query_state,
1822 )
1823 }
1824 }
1825
1826 fn size_hint(&self) -> (usize, Option<usize>) {
1827 let (_, max_size) = self.entity_iter.size_hint();
1828 (0, max_size)
1829 }
1830}
1831
1832impl<
1833 'w,
1834 's,
1835 D: ReadOnlyQueryData,
1836 F: QueryFilter,
1837 I: DoubleEndedIterator<Item: EntityEquivalent>,
1838 > DoubleEndedIterator for QueryManyIter<'w, 's, D, F, I>
1839{
1840 #[inline(always)]
1841 fn next_back(&mut self) -> Option<Self::Item> {
1842 // SAFETY:
1843 // All arguments stem from self.
1844 // It is safe to alias for ReadOnlyWorldQuery.
1845 unsafe {
1846 Self::fetch_next_aliased_unchecked(
1847 self.entity_iter.by_ref().rev(),
1848 self.entities,
1849 self.tables,
1850 self.archetypes,
1851 &mut self.fetch,
1852 &mut self.filter,
1853 self.query_state,
1854 )
1855 }
1856 }
1857}
1858
1859// This is correct as [`QueryManyIter`] always returns `None` once exhausted.
1860impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
1861 FusedIterator for QueryManyIter<'w, 's, D, F, I>
1862{
1863}
1864
1865// SAFETY: Fetching unique entities maintains uniqueness.
1866unsafe impl<'w, 's, F: QueryFilter, I: EntitySetIterator> EntitySetIterator
1867 for QueryManyIter<'w, 's, Entity, F, I>
1868{
1869}
1870
1871impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>> Debug
1872 for QueryManyIter<'w, 's, D, F, I>
1873{
1874 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1875 f.debug_struct("QueryManyIter").finish()
1876 }
1877}
1878
1879/// An [`Iterator`] over the query items generated from an iterator of unique [`Entity`]s.
1880///
1881/// Items are returned in the order of the provided iterator.
1882/// Entities that don't match the query are skipped.
1883///
1884/// In contrast with [`QueryManyIter`], this allows for mutable iteration without a [`fetch_next`] method.
1885///
1886/// This struct is created by the [`iter_many_unique`] and [`iter_many_unique_mut`] methods on [`Query`].
1887///
1888/// [`fetch_next`]: QueryManyIter::fetch_next
1889/// [`iter_many_unique`]: crate::system::Query::iter_many
1890/// [`iter_many_unique_mut`]: crate::system::Query::iter_many_mut
1891/// [`Query`]: crate::system::Query
1892pub struct QueryManyUniqueIter<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator>(
1893 QueryManyIter<'w, 's, D, F, I>,
1894);
1895
1896impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator>
1897 QueryManyUniqueIter<'w, 's, D, F, I>
1898{
1899 /// # Safety
1900 /// - `world` must have permission to access any of the components registered in `query_state`.
1901 /// - `world` must be the same one used to initialize `query_state`.
1902 pub(crate) unsafe fn new<EntityList: EntitySet<IntoIter = I>>(
1903 world: UnsafeWorldCell<'w>,
1904 query_state: &'s QueryState<D, F>,
1905 entity_list: EntityList,
1906 last_run: Tick,
1907 this_run: Tick,
1908 ) -> QueryManyUniqueIter<'w, 's, D, F, I> {
1909 QueryManyUniqueIter(QueryManyIter::new(
1910 world,
1911 query_state,
1912 entity_list,
1913 last_run,
1914 this_run,
1915 ))
1916 }
1917}
1918
1919impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> Iterator
1920 for QueryManyUniqueIter<'w, 's, D, F, I>
1921{
1922 type Item = D::Item<'w, 's>;
1923
1924 #[inline(always)]
1925 fn next(&mut self) -> Option<Self::Item> {
1926 // SAFETY: Entities are guaranteed to be unique, thus do not alias.
1927 unsafe {
1928 QueryManyIter::<'w, 's, D, F, I>::fetch_next_aliased_unchecked(
1929 &mut self.0.entity_iter,
1930 self.0.entities,
1931 self.0.tables,
1932 self.0.archetypes,
1933 &mut self.0.fetch,
1934 &mut self.0.filter,
1935 self.0.query_state,
1936 )
1937 }
1938 }
1939
1940 fn size_hint(&self) -> (usize, Option<usize>) {
1941 let (_, max_size) = self.0.entity_iter.size_hint();
1942 (0, max_size)
1943 }
1944}
1945
1946// This is correct as [`QueryManyIter`] always returns `None` once exhausted.
1947impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> FusedIterator
1948 for QueryManyUniqueIter<'w, 's, D, F, I>
1949{
1950}
1951
1952// SAFETY: Fetching unique entities maintains uniqueness.
1953unsafe impl<'w, 's, F: QueryFilter, I: EntitySetIterator> EntitySetIterator
1954 for QueryManyUniqueIter<'w, 's, Entity, F, I>
1955{
1956}
1957
1958impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> Debug
1959 for QueryManyUniqueIter<'w, 's, D, F, I>
1960{
1961 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1962 f.debug_struct("QueryManyUniqueIter").finish()
1963 }
1964}
1965
1966/// An [`Iterator`] over sorted query results of a [`QueryManyIter`].
1967///
1968/// This struct is created by the [`sort`](QueryManyIter), [`sort_unstable`](QueryManyIter),
1969/// [`sort_by`](QueryManyIter), [`sort_unstable_by`](QueryManyIter), [`sort_by_key`](QueryManyIter),
1970/// [`sort_unstable_by_key`](QueryManyIter), and [`sort_by_cached_key`](QueryManyIter) methods of [`QueryManyIter`].
1971pub struct QuerySortedManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> {
1972 entity_iter: I,
1973 entities: &'w Entities,
1974 tables: &'w Tables,
1975 archetypes: &'w Archetypes,
1976 fetch: D::Fetch<'w>,
1977 query_state: &'s QueryState<D, F>,
1978}
1979
1980impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>>
1981 QuerySortedManyIter<'w, 's, D, F, I>
1982{
1983 /// # Safety
1984 /// - `world` must have permission to access any of the components registered in `query_state`.
1985 /// - `world` must be the same one used to initialize `query_state`.
1986 /// - `entity_list` must only contain unique entities or be empty.
1987 pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(
1988 world: UnsafeWorldCell<'w>,
1989 query_state: &'s QueryState<D, F>,
1990 entity_list: EntityList,
1991 last_run: Tick,
1992 this_run: Tick,
1993 ) -> QuerySortedManyIter<'w, 's, D, F, I> {
1994 let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
1995 QuerySortedManyIter {
1996 query_state,
1997 entities: world.entities(),
1998 archetypes: world.archetypes(),
1999 // SAFETY: We only access table data that has been registered in `query_state`.
2000 // This means `world` has permission to access the data we use.
2001 tables: &world.storages().tables,
2002 fetch,
2003 entity_iter: entity_list.into_iter(),
2004 }
2005 }
2006
2007 /// # Safety
2008 /// The lifetime here is not restrictive enough for Fetch with &mut access,
2009 /// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple
2010 /// references to the same component, leading to unique reference aliasing.
2011 ///
2012 /// It is always safe for shared access.
2013 /// `entity` must stem from `self.entity_iter`, and not have been passed before.
2014 #[inline(always)]
2015 unsafe fn fetch_next_aliased_unchecked(&mut self, entity: Entity) -> Option<D::Item<'w, 's>> {
2016 let (location, archetype, table);
2017 // SAFETY:
2018 // `tables` and `archetypes` belong to the same world that the [`QueryIter`]
2019 // was initialized for.
2020 unsafe {
2021 location = self.entities.get_spawned(entity).debug_checked_unwrap();
2022 archetype = self
2023 .archetypes
2024 .get(location.archetype_id)
2025 .debug_checked_unwrap();
2026 table = self.tables.get(location.table_id).debug_checked_unwrap();
2027 }
2028
2029 // SAFETY: `archetype` is from the world that `fetch` was created for,
2030 // `fetch_state` is the state that `fetch` was initialized with
2031 unsafe {
2032 D::set_archetype(
2033 &mut self.fetch,
2034 &self.query_state.fetch_state,
2035 archetype,
2036 table,
2037 );
2038 }
2039
2040 // The entity list has already been filtered by the query lens, so we forego filtering here.
2041 // SAFETY:
2042 // - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
2043 // - fetch is only called once for each entity.
2044 unsafe {
2045 D::fetch(
2046 &self.query_state.fetch_state,
2047 &mut self.fetch,
2048 entity,
2049 location.table_row,
2050 )
2051 }
2052 }
2053
2054 /// Get next result from the query
2055 #[inline(always)]
2056 pub fn fetch_next(&mut self) -> Option<D::Item<'_, 's>> {
2057 while let Some(entity) = self.entity_iter.next() {
2058 // SAFETY:
2059 // We have collected the entity_iter once to drop all internal lens query item
2060 // references.
2061 // We are limiting the returned reference to self,
2062 // making sure this method cannot be called multiple times without getting rid
2063 // of any previously returned unique references first, thus preventing aliasing.
2064 // `entity` is passed from `entity_iter` the first time.
2065 if let Some(item) = unsafe { self.fetch_next_aliased_unchecked(entity) } {
2066 return Some(D::shrink(item));
2067 }
2068 }
2069 None
2070 }
2071}
2072
2073impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item = Entity>>
2074 QuerySortedManyIter<'w, 's, D, F, I>
2075{
2076 /// Get next result from the query
2077 #[inline(always)]
2078 pub fn fetch_next_back(&mut self) -> Option<D::Item<'_, 's>> {
2079 while let Some(entity) = self.entity_iter.next_back() {
2080 // SAFETY:
2081 // We have collected the entity_iter once to drop all internal lens query item
2082 // references.
2083 // We are limiting the returned reference to self,
2084 // making sure this method cannot be called multiple times without getting rid
2085 // of any previously returned unique references first, thus preventing aliasing.
2086 // `entity` is passed from `entity_iter` the first time.
2087 if let Some(item) = unsafe { self.fetch_next_aliased_unchecked(entity) } {
2088 return Some(D::shrink(item));
2089 }
2090 }
2091 None
2092 }
2093}
2094
2095impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item = Entity>> Iterator
2096 for QuerySortedManyIter<'w, 's, D, F, I>
2097{
2098 type Item = D::Item<'w, 's>;
2099
2100 #[inline(always)]
2101 fn next(&mut self) -> Option<Self::Item> {
2102 while let Some(entity) = self.entity_iter.next() {
2103 // SAFETY:
2104 // It is safe to alias for ReadOnlyWorldQuery.
2105 // `entity` is passed from `entity_iter` the first time.
2106 if let Some(item) = unsafe { self.fetch_next_aliased_unchecked(entity) } {
2107 return Some(D::shrink(item));
2108 }
2109 }
2110 None
2111 }
2112
2113 fn size_hint(&self) -> (usize, Option<usize>) {
2114 let (min_size, max_size) = self.entity_iter.size_hint();
2115 let archetype_query = D::IS_ARCHETYPAL;
2116 let min_size = if archetype_query { min_size } else { 0 };
2117 (min_size, max_size)
2118 }
2119}
2120
2121impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: DoubleEndedIterator<Item = Entity>>
2122 DoubleEndedIterator for QuerySortedManyIter<'w, 's, D, F, I>
2123{
2124 #[inline(always)]
2125 fn next_back(&mut self) -> Option<Self::Item> {
2126 while let Some(entity) = self.entity_iter.next_back() {
2127 // SAFETY:
2128 // It is safe to alias for ReadOnlyWorldQuery.
2129 // `entity` is passed from `entity_iter` the first time.
2130 if let Some(item) = unsafe { self.fetch_next_aliased_unchecked(entity) } {
2131 return Some(D::shrink(item));
2132 }
2133 }
2134 None
2135 }
2136}
2137
2138impl<
2139 D: ReadOnlyQueryData + ArchetypeQueryData,
2140 F: QueryFilter,
2141 I: ExactSizeIterator<Item = Entity>,
2142 > ExactSizeIterator for QuerySortedManyIter<'_, '_, D, F, I>
2143{
2144}
2145
2146impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> Debug
2147 for QuerySortedManyIter<'w, 's, D, F, I>
2148{
2149 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2150 f.debug_struct("QuerySortedManyIter").finish()
2151 }
2152}
2153
2154/// An iterator over `K`-sized combinations of query items without repetition.
2155///
2156/// A combination is an arrangement of a collection of items where order does not matter.
2157///
2158/// `K` is the number of items that make up each subset, and the number of items returned by the iterator.
2159/// `N` is the number of total entities output by the query.
2160///
2161/// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are
2162/// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].
2163/// And in this case, `N` would be defined as 4 since the size of the input list is 4.
2164///
2165/// The number of combinations depend on how `K` relates to the number of entities matching the [`Query`]:
2166/// - if `K = N`, only one combination exists,
2167/// - if `K < N`, there are <sub>N</sub>C<sub>K</sub> combinations (see the [performance section] of `Query`),
2168/// - if `K > N`, there are no combinations.
2169///
2170/// The output combination is not guaranteed to have any order of iteration.
2171///
2172/// # Usage
2173///
2174/// This type is returned by calling [`Query::iter_combinations`] or [`Query::iter_combinations_mut`].
2175///
2176/// It implements [`Iterator`] only if it iterates over read-only query items ([learn more]).
2177///
2178/// In the case of mutable query items, it can be iterated by calling [`fetch_next`] in a `while let` loop.
2179///
2180/// # Examples
2181///
2182/// The following example shows how to traverse the iterator when the query items are read-only.
2183///
2184/// ```
2185/// # use bevy_ecs::prelude::*;
2186/// # #[derive(Component)]
2187/// # struct ComponentA;
2188/// #
2189/// fn some_system(query: Query<&ComponentA>) {
2190/// for [a1, a2] in query.iter_combinations() {
2191/// // ...
2192/// }
2193/// }
2194/// ```
2195///
2196/// The following example shows how `fetch_next` should be called with a `while let` loop to traverse the iterator when the query items are mutable.
2197///
2198/// ```
2199/// # use bevy_ecs::prelude::*;
2200/// # #[derive(Component)]
2201/// # struct ComponentA;
2202/// #
2203/// fn some_system(mut query: Query<&mut ComponentA>) {
2204/// let mut combinations = query.iter_combinations_mut();
2205/// while let Some([a1, a2]) = combinations.fetch_next() {
2206/// // ...
2207/// }
2208/// }
2209/// ```
2210///
2211/// [`fetch_next`]: Self::fetch_next
2212/// [learn more]: Self#impl-Iterator
2213/// [performance section]: crate::system::Query#performance
2214/// [`Query`]: crate::system::Query
2215/// [`Query::iter_combinations`]: crate::system::Query::iter_combinations
2216/// [`Query::iter_combinations_mut`]: crate::system::Query::iter_combinations_mut
2217pub struct QueryCombinationIter<'w, 's, D: QueryData, F: QueryFilter, const K: usize> {
2218 tables: &'w Tables,
2219 archetypes: &'w Archetypes,
2220 query_state: &'s QueryState<D, F>,
2221 cursors: [QueryIterationCursor<'w, 's, D, F>; K],
2222}
2223
2224impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<'w, 's, D, F, K> {
2225 /// # Safety
2226 /// - `world` must have permission to access any of the components registered in `query_state`.
2227 /// - `world` must be the same one used to initialize `query_state`.
2228 pub(crate) unsafe fn new(
2229 world: UnsafeWorldCell<'w>,
2230 query_state: &'s QueryState<D, F>,
2231 last_run: Tick,
2232 this_run: Tick,
2233 ) -> Self {
2234 assert!(K != 0, "K should not equal to zero");
2235 // Initialize array with cursors.
2236 // There is no FromIterator on arrays, so instead initialize it manually with MaybeUninit
2237
2238 let mut array: MaybeUninit<[QueryIterationCursor<'w, 's, D, F>; K]> = MaybeUninit::uninit();
2239 let ptr = array
2240 .as_mut_ptr()
2241 .cast::<QueryIterationCursor<'w, 's, D, F>>();
2242 ptr.write(QueryIterationCursor::init(
2243 world,
2244 query_state,
2245 last_run,
2246 this_run,
2247 ));
2248 for slot in (1..K).map(|offset| ptr.add(offset)) {
2249 slot.write(QueryIterationCursor::init_empty(
2250 world,
2251 query_state,
2252 last_run,
2253 this_run,
2254 ));
2255 }
2256
2257 QueryCombinationIter {
2258 query_state,
2259 // SAFETY: We only access table data that has been registered in `query_state`.
2260 tables: unsafe { &world.storages().tables },
2261 archetypes: world.archetypes(),
2262 cursors: array.assume_init(),
2263 }
2264 }
2265
2266 /// # Safety
2267 /// The lifetime here is not restrictive enough for Fetch with &mut access,
2268 /// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple
2269 /// references to the same component, leading to unique reference aliasing.
2270 /// .
2271 /// It is always safe for shared access.
2272 #[inline]
2273 unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<[D::Item<'w, 's>; K]> {
2274 // PERF: can speed up the following code using `cursor.remaining()` instead of `next_item.is_none()`
2275 // when D::IS_ARCHETYPAL && F::IS_ARCHETYPAL
2276 //
2277 // let `i` be the index of `c`, the last cursor in `self.cursors` that
2278 // returns `K-i` or more elements.
2279 // Make cursor in index `j` for all `j` in `[i, K)` a copy of `c` advanced `j-i+1` times.
2280 // If no such `c` exists, return `None`
2281 'outer: for i in (0..K).rev() {
2282 match self.cursors[i].next(self.tables, self.archetypes, self.query_state) {
2283 Some(_) => {
2284 for j in (i + 1)..K {
2285 self.cursors[j] = self.cursors[j - 1].clone();
2286 match self.cursors[j].next(self.tables, self.archetypes, self.query_state) {
2287 Some(_) => {}
2288 None if i > 0 => continue 'outer,
2289 None => return None,
2290 }
2291 }
2292 break;
2293 }
2294 None if i > 0 => continue,
2295 None => return None,
2296 }
2297 }
2298
2299 let mut values = MaybeUninit::<[D::Item<'w, 's>; K]>::uninit();
2300
2301 let ptr = values.as_mut_ptr().cast::<D::Item<'w, 's>>();
2302 for (offset, cursor) in self.cursors.iter_mut().enumerate() {
2303 ptr.add(offset)
2304 .write(cursor.peek_last(self.query_state).unwrap());
2305 }
2306
2307 Some(values.assume_init())
2308 }
2309
2310 /// Get next combination of queried components
2311 #[inline]
2312 pub fn fetch_next(&mut self) -> Option<[D::Item<'_, 's>; K]> {
2313 // SAFETY: we are limiting the returned reference to self,
2314 // making sure this method cannot be called multiple times without getting rid
2315 // of any previously returned unique references first, thus preventing aliasing.
2316 unsafe {
2317 self.fetch_next_aliased_unchecked()
2318 .map(|array| array.map(D::shrink))
2319 }
2320 }
2321}
2322
2323// Iterator type is intentionally implemented only for read-only access.
2324// Doing so for mutable references would be unsound, because calling `next`
2325// multiple times would allow multiple owned references to the same data to exist.
2326impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator
2327 for QueryCombinationIter<'w, 's, D, F, K>
2328{
2329 type Item = [D::Item<'w, 's>; K];
2330
2331 #[inline]
2332 fn next(&mut self) -> Option<Self::Item> {
2333 // Safety: it is safe to alias for ReadOnlyWorldQuery
2334 unsafe { QueryCombinationIter::fetch_next_aliased_unchecked(self) }
2335 }
2336
2337 fn size_hint(&self) -> (usize, Option<usize>) {
2338 // binomial coefficient: (n ; k) = n! / k!(n-k)! = (n*n-1*...*n-k+1) / k!
2339 // See https://en.wikipedia.org/wiki/Binomial_coefficient
2340 // See https://blog.plover.com/math/choose.html for implementation
2341 // It was chosen to reduce overflow potential.
2342 fn choose(n: usize, k: usize) -> Option<usize> {
2343 if k > n || n == 0 {
2344 return Some(0);
2345 }
2346 let k = k.min(n - k);
2347 let ks = 1..=k;
2348 let ns = (n - k + 1..=n).rev();
2349 ks.zip(ns)
2350 .try_fold(1_usize, |acc, (k, n)| Some(acc.checked_mul(n)? / k))
2351 }
2352 // sum_i=0..k choose(cursors[i].remaining, k-i)
2353 let max_combinations = self
2354 .cursors
2355 .iter()
2356 .enumerate()
2357 .try_fold(0, |acc, (i, cursor)| {
2358 let n = cursor.max_remaining(self.tables, self.archetypes);
2359 Some(acc + choose(n as usize, K - i)?)
2360 });
2361
2362 let archetype_query = D::IS_ARCHETYPAL && F::IS_ARCHETYPAL;
2363 let known_max = max_combinations.unwrap_or(usize::MAX);
2364 let min_combinations = if archetype_query { known_max } else { 0 };
2365 (min_combinations, max_combinations)
2366 }
2367}
2368
2369impl<'w, 's, D: ArchetypeQueryData, F: ArchetypeFilter> ExactSizeIterator
2370 for QueryIter<'w, 's, D, F>
2371{
2372 fn len(&self) -> usize {
2373 self.size_hint().0
2374 }
2375}
2376
2377// This is correct as [`QueryCombinationIter`] always returns `None` once exhausted.
2378impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> FusedIterator
2379 for QueryCombinationIter<'w, 's, D, F, K>
2380{
2381}
2382
2383impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> Debug
2384 for QueryCombinationIter<'w, 's, D, F, K>
2385{
2386 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2387 f.debug_struct("QueryCombinationIter").finish()
2388 }
2389}
2390
2391struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> {
2392 // whether the query iteration is dense or not. Mirrors QueryState's `is_dense` field.
2393 is_dense: bool,
2394 storage_id_iter: core::slice::Iter<'s, StorageId>,
2395 table_entities: &'w [Entity],
2396 archetype_entities: &'w [ArchetypeEntity],
2397 fetch: D::Fetch<'w>,
2398 filter: F::Fetch<'w>,
2399 // length of the table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense
2400 current_len: u32,
2401 // either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense
2402 current_row: u32,
2403}
2404
2405impl<D: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, D, F> {
2406 fn clone(&self) -> Self {
2407 Self {
2408 is_dense: self.is_dense,
2409 storage_id_iter: self.storage_id_iter.clone(),
2410 table_entities: self.table_entities,
2411 archetype_entities: self.archetype_entities,
2412 fetch: self.fetch.clone(),
2413 filter: self.filter.clone(),
2414 current_len: self.current_len,
2415 current_row: self.current_row,
2416 }
2417 }
2418}
2419
2420impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2421 /// # Safety
2422 /// - `world` must have permission to access any of the components registered in `query_state`.
2423 /// - `world` must be the same one used to initialize `query_state`.
2424 unsafe fn init_empty(
2425 world: UnsafeWorldCell<'w>,
2426 query_state: &'s QueryState<D, F>,
2427 last_run: Tick,
2428 this_run: Tick,
2429 ) -> Self {
2430 QueryIterationCursor {
2431 storage_id_iter: [].iter(),
2432 ..Self::init(world, query_state, last_run, this_run)
2433 }
2434 }
2435
2436 /// # Safety
2437 /// - `world` must have permission to access any of the components registered in `query_state`.
2438 /// - `world` must be the same one used to initialize `query_state`.
2439 unsafe fn init(
2440 world: UnsafeWorldCell<'w>,
2441 query_state: &'s QueryState<D, F>,
2442 last_run: Tick,
2443 this_run: Tick,
2444 ) -> Self {
2445 let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
2446 let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);
2447 QueryIterationCursor {
2448 fetch,
2449 filter,
2450 table_entities: &[],
2451 archetype_entities: &[],
2452 storage_id_iter: query_state.matched_storage_ids.iter(),
2453 is_dense: query_state.is_dense,
2454 current_len: 0,
2455 current_row: 0,
2456 }
2457 }
2458
2459 fn reborrow(&mut self) -> QueryIterationCursor<'_, 's, D, F> {
2460 QueryIterationCursor {
2461 is_dense: self.is_dense,
2462 fetch: D::shrink_fetch(self.fetch.clone()),
2463 filter: F::shrink_fetch(self.filter.clone()),
2464 table_entities: self.table_entities,
2465 archetype_entities: self.archetype_entities,
2466 storage_id_iter: self.storage_id_iter.clone(),
2467 current_len: self.current_len,
2468 current_row: self.current_row,
2469 }
2470 }
2471
2472 /// Retrieve item returned from most recent `next` call again.
2473 ///
2474 /// # Safety
2475 /// The result of `next` and any previous calls to `peek_last` with this row must have been
2476 /// dropped to prevent aliasing mutable references.
2477 #[inline]
2478 unsafe fn peek_last(&mut self, query_state: &'s QueryState<D, F>) -> Option<D::Item<'w, 's>> {
2479 if self.current_row > 0 {
2480 let index = self.current_row - 1;
2481 if self.is_dense {
2482 // SAFETY: This must have been called previously in `next` as `current_row > 0`
2483 let entity = unsafe { self.table_entities.get_unchecked(index as usize) };
2484 // SAFETY:
2485 // - `set_table` must have been called previously either in `next` or before it.
2486 // - `*entity` and `index` are in the current table.
2487 unsafe {
2488 D::fetch(
2489 &query_state.fetch_state,
2490 &mut self.fetch,
2491 *entity,
2492 // SAFETY: This is from an exclusive range, so it can't be max.
2493 TableRow::new(NonMaxU32::new_unchecked(index)),
2494 )
2495 }
2496 } else {
2497 // SAFETY: This must have been called previously in `next` as `current_row > 0`
2498 let archetype_entity =
2499 unsafe { self.archetype_entities.get_unchecked(index as usize) };
2500 // SAFETY:
2501 // - `set_archetype` must have been called previously either in `next` or before it.
2502 // - `archetype_entity.id()` and `archetype_entity.table_row()` are in the current archetype.
2503 unsafe {
2504 D::fetch(
2505 &query_state.fetch_state,
2506 &mut self.fetch,
2507 archetype_entity.id(),
2508 archetype_entity.table_row(),
2509 )
2510 }
2511 }
2512 } else {
2513 None
2514 }
2515 }
2516
2517 /// How many values will this cursor return at most?
2518 ///
2519 /// Note that if `D::IS_ARCHETYPAL && F::IS_ARCHETYPAL`, the return value
2520 /// will be **the exact count of remaining values**.
2521 fn max_remaining(&self, tables: &'w Tables, archetypes: &'w Archetypes) -> u32 {
2522 let ids = self.storage_id_iter.clone();
2523 let remaining_matched: u32 = if self.is_dense {
2524 // SAFETY: The if check ensures that storage_id_iter stores TableIds
2525 unsafe { ids.map(|id| tables[id.table_id].entity_count()).sum() }
2526 } else {
2527 // SAFETY: The if check ensures that storage_id_iter stores ArchetypeIds
2528 unsafe { ids.map(|id| archetypes[id.archetype_id].len()).sum() }
2529 };
2530 remaining_matched + self.current_len - self.current_row
2531 }
2532
2533 // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
2534 // QueryIter, QueryIterationCursor, QuerySortedIter, QueryManyIter, QuerySortedManyIter, QueryCombinationIter,
2535 // QueryState::par_fold_init_unchecked_manual, QueryState::par_many_fold_init_unchecked_manual,
2536 // QueryState::par_many_unique_fold_init_unchecked_manual
2537 /// # Safety
2538 /// `tables` and `archetypes` must belong to the same world that the [`QueryIterationCursor`]
2539 /// was initialized for.
2540 /// `query_state` must be the same [`QueryState`] that was passed to `init` or `init_empty`.
2541 #[inline(always)]
2542 unsafe fn next(
2543 &mut self,
2544 tables: &'w Tables,
2545 archetypes: &'w Archetypes,
2546 query_state: &'s QueryState<D, F>,
2547 ) -> Option<D::Item<'w, 's>> {
2548 if self.is_dense {
2549 loop {
2550 // we are on the beginning of the query, or finished processing a table, so skip to the next
2551 if self.current_row == self.current_len {
2552 let table_id = self.storage_id_iter.next()?.table_id;
2553 let table = tables.get(table_id).debug_checked_unwrap();
2554 if table.is_empty() {
2555 continue;
2556 }
2557 // SAFETY: `table` is from the world that `fetch/filter` were created for,
2558 // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
2559 unsafe {
2560 D::set_table(&mut self.fetch, &query_state.fetch_state, table);
2561 F::set_table(&mut self.filter, &query_state.filter_state, table);
2562 }
2563 self.table_entities = table.entities();
2564 self.current_len = table.entity_count();
2565 self.current_row = 0;
2566 }
2567
2568 // SAFETY: set_table was called prior.
2569 // `current_row` is a table row in range of the current table, because if it was not, then the above would have been executed.
2570 let entity =
2571 unsafe { self.table_entities.get_unchecked(self.current_row as usize) };
2572 // SAFETY: The row is less than the u32 len, so it must not be max.
2573 let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(self.current_row)) };
2574 self.current_row += 1;
2575
2576 if !F::filter_fetch(&query_state.filter_state, &mut self.filter, *entity, row) {
2577 continue;
2578 }
2579
2580 // SAFETY:
2581 // - set_table was called prior.
2582 // - `current_row` must be a table row in range of the current table,
2583 // because if it was not, then the above would have been executed.
2584 // - fetch is only called once for each `entity`.
2585 let item =
2586 unsafe { D::fetch(&query_state.fetch_state, &mut self.fetch, *entity, row) };
2587 if let Some(item) = item {
2588 return Some(item);
2589 }
2590 }
2591 } else {
2592 loop {
2593 if self.current_row == self.current_len {
2594 let archetype_id = self.storage_id_iter.next()?.archetype_id;
2595 let archetype = archetypes.get(archetype_id).debug_checked_unwrap();
2596 if archetype.is_empty() {
2597 continue;
2598 }
2599 let table = tables.get(archetype.table_id()).debug_checked_unwrap();
2600 // SAFETY: `archetype` and `tables` are from the world that `fetch/filter` were created for,
2601 // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
2602 unsafe {
2603 D::set_archetype(
2604 &mut self.fetch,
2605 &query_state.fetch_state,
2606 archetype,
2607 table,
2608 );
2609 F::set_archetype(
2610 &mut self.filter,
2611 &query_state.filter_state,
2612 archetype,
2613 table,
2614 );
2615 }
2616 self.archetype_entities = archetype.entities();
2617 self.current_len = archetype.len();
2618 self.current_row = 0;
2619 }
2620
2621 // SAFETY: set_archetype was called prior.
2622 // `current_row` is an archetype index row in range of the current archetype, because if it was not, then the if above would have been executed.
2623 let archetype_entity = unsafe {
2624 self.archetype_entities
2625 .get_unchecked(self.current_row as usize)
2626 };
2627 self.current_row += 1;
2628
2629 if !F::filter_fetch(
2630 &query_state.filter_state,
2631 &mut self.filter,
2632 archetype_entity.id(),
2633 archetype_entity.table_row(),
2634 ) {
2635 continue;
2636 }
2637
2638 // SAFETY:
2639 // - set_archetype was called prior.
2640 // - `current_row` must be an archetype index row in range of the current archetype,
2641 // because if it was not, then the if above would have been executed.
2642 // - fetch is only called once for each `archetype_entity`.
2643 let item = unsafe {
2644 D::fetch(
2645 &query_state.fetch_state,
2646 &mut self.fetch,
2647 archetype_entity.id(),
2648 archetype_entity.table_row(),
2649 )
2650 };
2651 if let Some(item) = item {
2652 return Some(item);
2653 }
2654 }
2655 }
2656 }
2657}
2658
2659// A wrapper struct that gives its data a neutral ordering.
2660#[derive(Copy, Clone)]
2661struct NeutralOrd<T>(T);
2662
2663impl<T> PartialEq for NeutralOrd<T> {
2664 fn eq(&self, _other: &Self) -> bool {
2665 true
2666 }
2667}
2668
2669impl<T> Eq for NeutralOrd<T> {}
2670
2671#[expect(
2672 clippy::non_canonical_partial_ord_impl,
2673 reason = "`PartialOrd` and `Ord` on this struct must only ever return `Ordering::Equal`, so we prefer clarity"
2674)]
2675impl<T> PartialOrd for NeutralOrd<T> {
2676 fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
2677 Some(Ordering::Equal)
2678 }
2679}
2680
2681impl<T> Ord for NeutralOrd<T> {
2682 fn cmp(&self, _other: &Self) -> Ordering {
2683 Ordering::Equal
2684 }
2685}
2686
2687#[cfg(test)]
2688#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
2689mod tests {
2690 use alloc::vec::Vec;
2691 use std::println;
2692
2693 use crate::component::Component;
2694 use crate::entity::Entity;
2695 use crate::prelude::{With, World};
2696
2697 #[derive(Component, Debug, PartialEq, PartialOrd, Clone, Copy)]
2698 struct A(f32);
2699 #[derive(Component, Debug, Eq, PartialEq, Clone, Copy)]
2700 #[component(storage = "SparseSet")]
2701 struct Sparse(usize);
2702
2703 #[derive(Component)]
2704 struct Marker;
2705
2706 #[test]
2707 fn query_iter_sorts() {
2708 let mut world = World::new();
2709 for i in 0..100 {
2710 world.spawn((A(i as f32), Marker));
2711 world.spawn((A(i as f32), Sparse(i), Marker));
2712 world.spawn((Sparse(i), Marker));
2713 }
2714
2715 let mut query = world.query_filtered::<Entity, With<Marker>>();
2716
2717 let sort = query.iter(&world).sort::<Entity>().collect::<Vec<_>>();
2718 assert_eq!(sort.len(), 300);
2719
2720 let sort_unstable = query
2721 .iter(&world)
2722 .sort_unstable::<Entity>()
2723 .collect::<Vec<_>>();
2724
2725 let sort_by = query
2726 .iter(&world)
2727 .sort_by::<Entity>(Ord::cmp)
2728 .collect::<Vec<_>>();
2729
2730 let sort_unstable_by = query
2731 .iter(&world)
2732 .sort_unstable_by::<Entity>(Ord::cmp)
2733 .collect::<Vec<_>>();
2734
2735 let sort_by_key = query
2736 .iter(&world)
2737 .sort_by_key::<Entity, _>(|&e| e)
2738 .collect::<Vec<_>>();
2739
2740 let sort_unstable_by_key = query
2741 .iter(&world)
2742 .sort_unstable_by_key::<Entity, _>(|&e| e)
2743 .collect::<Vec<_>>();
2744
2745 let sort_by_cached_key = query
2746 .iter(&world)
2747 .sort_by_cached_key::<Entity, _>(|&e| e)
2748 .collect::<Vec<_>>();
2749
2750 let mut sort_v2 = query.iter(&world).collect::<Vec<_>>();
2751 sort_v2.sort();
2752
2753 let mut sort_unstable_v2 = query.iter(&world).collect::<Vec<_>>();
2754 sort_unstable_v2.sort_unstable();
2755
2756 let mut sort_by_v2 = query.iter(&world).collect::<Vec<_>>();
2757 sort_by_v2.sort_by(Ord::cmp);
2758
2759 let mut sort_unstable_by_v2 = query.iter(&world).collect::<Vec<_>>();
2760 sort_unstable_by_v2.sort_unstable_by(Ord::cmp);
2761
2762 let mut sort_by_key_v2 = query.iter(&world).collect::<Vec<_>>();
2763 sort_by_key_v2.sort_by_key(|&e| e);
2764
2765 let mut sort_unstable_by_key_v2 = query.iter(&world).collect::<Vec<_>>();
2766 sort_unstable_by_key_v2.sort_unstable_by_key(|&e| e);
2767
2768 let mut sort_by_cached_key_v2 = query.iter(&world).collect::<Vec<_>>();
2769 sort_by_cached_key_v2.sort_by_cached_key(|&e| e);
2770
2771 assert_eq!(sort, sort_v2);
2772 assert_eq!(sort_unstable, sort_unstable_v2);
2773 assert_eq!(sort_by, sort_by_v2);
2774 assert_eq!(sort_unstable_by, sort_unstable_by_v2);
2775 assert_eq!(sort_by_key, sort_by_key_v2);
2776 assert_eq!(sort_unstable_by_key, sort_unstable_by_key_v2);
2777 assert_eq!(sort_by_cached_key, sort_by_cached_key_v2);
2778 }
2779
2780 #[test]
2781 #[should_panic]
2782 fn query_iter_sort_after_next() {
2783 let mut world = World::new();
2784 world.spawn((A(0.),));
2785 world.spawn((A(1.1),));
2786 world.spawn((A(2.22),));
2787
2788 {
2789 let mut query = world.query::<&A>();
2790 let mut iter = query.iter(&world);
2791 println!(
2792 "archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2793 iter.cursor.archetype_entities.len(),
2794 iter.cursor.table_entities.len(),
2795 iter.cursor.current_len,
2796 iter.cursor.current_row
2797 );
2798 _ = iter.next();
2799 println!(
2800 "archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2801 iter.cursor.archetype_entities.len(),
2802 iter.cursor.table_entities.len(),
2803 iter.cursor.current_len,
2804 iter.cursor.current_row
2805 );
2806 println!("{}", iter.sort::<Entity>().len());
2807 }
2808 }
2809
2810 #[test]
2811 #[should_panic]
2812 fn query_iter_sort_after_next_dense() {
2813 let mut world = World::new();
2814 world.spawn((Sparse(11),));
2815 world.spawn((Sparse(22),));
2816 world.spawn((Sparse(33),));
2817
2818 {
2819 let mut query = world.query::<&Sparse>();
2820 let mut iter = query.iter(&world);
2821 println!(
2822 "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2823 iter.cursor.archetype_entities.len(),
2824 iter.cursor.table_entities.len(),
2825 iter.cursor.current_len,
2826 iter.cursor.current_row
2827 );
2828 _ = iter.next();
2829 println!(
2830 "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2831 iter.cursor.archetype_entities.len(),
2832 iter.cursor.table_entities.len(),
2833 iter.cursor.current_len,
2834 iter.cursor.current_row
2835 );
2836 println!("{}", iter.sort::<Entity>().len());
2837 }
2838 }
2839
2840 #[test]
2841 fn empty_query_iter_sort_after_next_does_not_panic() {
2842 let mut world = World::new();
2843 {
2844 let mut query = world.query::<(&A, &Sparse)>();
2845 let mut iter = query.iter(&world);
2846 println!(
2847 "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2848 iter.cursor.archetype_entities.len(),
2849 iter.cursor.table_entities.len(),
2850 iter.cursor.current_len,
2851 iter.cursor.current_row
2852 );
2853 _ = iter.next();
2854 println!(
2855 "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2856 iter.cursor.archetype_entities.len(),
2857 iter.cursor.table_entities.len(),
2858 iter.cursor.current_len,
2859 iter.cursor.current_row
2860 );
2861 println!("{}", iter.sort::<Entity>().len());
2862 }
2863 }
2864
2865 #[test]
2866 fn query_iter_cursor_state_non_empty_after_next() {
2867 let mut world = World::new();
2868 world.spawn((A(0.), Sparse(11)));
2869 world.spawn((A(1.1), Sparse(22)));
2870 world.spawn((A(2.22), Sparse(33)));
2871 {
2872 let mut query = world.query::<(&A, &Sparse)>();
2873 let mut iter = query.iter(&world);
2874 println!(
2875 "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2876 iter.cursor.archetype_entities.len(),
2877 iter.cursor.table_entities.len(),
2878 iter.cursor.current_len,
2879 iter.cursor.current_row
2880 );
2881 assert!(iter.cursor.table_entities.len() | iter.cursor.archetype_entities.len() == 0);
2882 _ = iter.next();
2883 println!(
2884 "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2885 iter.cursor.archetype_entities.len(),
2886 iter.cursor.table_entities.len(),
2887 iter.cursor.current_len,
2888 iter.cursor.current_row
2889 );
2890 assert!(
2891 (
2892 iter.cursor.table_entities.len(),
2893 iter.cursor.archetype_entities.len()
2894 ) != (0, 0)
2895 );
2896 }
2897 }
2898
2899 #[test]
2900 fn query_iter_many_sorts() {
2901 let mut world = World::new();
2902
2903 let entity_list: &Vec<_> = &world
2904 .spawn_batch([A(0.), A(1.), A(2.), A(3.), A(4.)])
2905 .collect();
2906
2907 let mut query = world.query::<Entity>();
2908
2909 let sort = query
2910 .iter_many(&world, entity_list)
2911 .sort::<Entity>()
2912 .collect::<Vec<_>>();
2913
2914 let sort_unstable = query
2915 .iter_many(&world, entity_list)
2916 .sort_unstable::<Entity>()
2917 .collect::<Vec<_>>();
2918
2919 let sort_by = query
2920 .iter_many(&world, entity_list)
2921 .sort_by::<Entity>(Ord::cmp)
2922 .collect::<Vec<_>>();
2923
2924 let sort_unstable_by = query
2925 .iter_many(&world, entity_list)
2926 .sort_unstable_by::<Entity>(Ord::cmp)
2927 .collect::<Vec<_>>();
2928
2929 let sort_by_key = query
2930 .iter_many(&world, entity_list)
2931 .sort_by_key::<Entity, _>(|&e| e)
2932 .collect::<Vec<_>>();
2933
2934 let sort_unstable_by_key = query
2935 .iter_many(&world, entity_list)
2936 .sort_unstable_by_key::<Entity, _>(|&e| e)
2937 .collect::<Vec<_>>();
2938
2939 let sort_by_cached_key = query
2940 .iter_many(&world, entity_list)
2941 .sort_by_cached_key::<Entity, _>(|&e| e)
2942 .collect::<Vec<_>>();
2943
2944 let mut sort_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();
2945 sort_v2.sort();
2946
2947 let mut sort_unstable_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();
2948 sort_unstable_v2.sort_unstable();
2949
2950 let mut sort_by_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();
2951 sort_by_v2.sort_by(Ord::cmp);
2952
2953 let mut sort_unstable_by_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();
2954 sort_unstable_by_v2.sort_unstable_by(Ord::cmp);
2955
2956 let mut sort_by_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();
2957 sort_by_key_v2.sort_by_key(|&e| e);
2958
2959 let mut sort_unstable_by_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();
2960 sort_unstable_by_key_v2.sort_unstable_by_key(|&e| e);
2961
2962 let mut sort_by_cached_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();
2963 sort_by_cached_key_v2.sort_by_cached_key(|&e| e);
2964
2965 assert_eq!(sort, sort_v2);
2966 assert_eq!(sort_unstable, sort_unstable_v2);
2967 assert_eq!(sort_by, sort_by_v2);
2968 assert_eq!(sort_unstable_by, sort_unstable_by_v2);
2969 assert_eq!(sort_by_key, sort_by_key_v2);
2970 assert_eq!(sort_unstable_by_key, sort_unstable_by_key_v2);
2971 assert_eq!(sort_by_cached_key, sort_by_cached_key_v2);
2972 }
2973
2974 #[test]
2975 fn query_iter_many_sort_doesnt_panic_after_next() {
2976 let mut world = World::new();
2977
2978 let entity_list: &Vec<_> = &world
2979 .spawn_batch([A(0.), A(1.), A(2.), A(3.), A(4.)])
2980 .collect();
2981
2982 let mut query = world.query::<Entity>();
2983 let mut iter = query.iter_many(&world, entity_list);
2984
2985 _ = iter.next();
2986
2987 iter.sort::<Entity>();
2988
2989 let mut query_2 = world.query::<&mut A>();
2990 let mut iter_2 = query_2.iter_many_mut(&mut world, entity_list);
2991
2992 _ = iter_2.fetch_next();
2993
2994 iter_2.sort::<Entity>();
2995 }
2996
2997 // This test should be run with miri to check for UB caused by aliasing.
2998 // The lens items created during the sort must not be live at the same time as the mutable references returned from the iterator.
2999 #[test]
3000 fn query_iter_many_sorts_duplicate_entities_no_ub() {
3001 #[derive(Component, Ord, PartialOrd, Eq, PartialEq)]
3002 struct C(usize);
3003
3004 let mut world = World::new();
3005 let id = world.spawn(C(10)).id();
3006 let mut query_state = world.query::<&mut C>();
3007
3008 {
3009 let mut query = query_state.iter_many_mut(&mut world, [id, id]).sort::<&C>();
3010 while query.fetch_next().is_some() {}
3011 }
3012 {
3013 let mut query = query_state
3014 .iter_many_mut(&mut world, [id, id])
3015 .sort_unstable::<&C>();
3016 while query.fetch_next().is_some() {}
3017 }
3018 {
3019 let mut query = query_state
3020 .iter_many_mut(&mut world, [id, id])
3021 .sort_by::<&C>(|l, r| Ord::cmp(l, r));
3022 while query.fetch_next().is_some() {}
3023 }
3024 {
3025 let mut query = query_state
3026 .iter_many_mut(&mut world, [id, id])
3027 .sort_unstable_by::<&C>(|l, r| Ord::cmp(l, r));
3028 while query.fetch_next().is_some() {}
3029 }
3030 {
3031 let mut query = query_state
3032 .iter_many_mut(&mut world, [id, id])
3033 .sort_by_key::<&C, _>(|d| d.0);
3034 while query.fetch_next().is_some() {}
3035 }
3036 {
3037 let mut query = query_state
3038 .iter_many_mut(&mut world, [id, id])
3039 .sort_unstable_by_key::<&C, _>(|d| d.0);
3040 while query.fetch_next().is_some() {}
3041 }
3042 {
3043 let mut query = query_state
3044 .iter_many_mut(&mut world, [id, id])
3045 .sort_by_cached_key::<&C, _>(|d| d.0);
3046 while query.fetch_next().is_some() {}
3047 }
3048 }
3049}