bevy_ecs/query/iter.rs
1use crate::{
2 archetype::{Archetype, ArchetypeEntity, Archetypes},
3 component::Tick,
4 entity::{Entities, Entity},
5 query::{ArchetypeFilter, DebugCheckedUnwrap, QueryState, StorageId},
6 storage::{Table, TableRow, Tables},
7 world::unsafe_world_cell::UnsafeWorldCell,
8};
9use core::{
10 borrow::Borrow,
11 cmp::Ordering,
12 fmt::{self, Debug, Formatter},
13 iter::FusedIterator,
14 mem::MaybeUninit,
15 ops::Range,
16};
17
18use super::{QueryData, QueryFilter, ReadOnlyQueryData};
19
20/// An [`Iterator`] over query results of a [`Query`](crate::system::Query).
21///
22/// This struct is created by the [`Query::iter`](crate::system::Query::iter) and
23/// [`Query::iter_mut`](crate::system::Query::iter_mut) methods.
24pub struct QueryIter<'w, 's, D: QueryData, F: QueryFilter> {
25 world: UnsafeWorldCell<'w>,
26 tables: &'w Tables,
27 archetypes: &'w Archetypes,
28 query_state: &'s QueryState<D, F>,
29 cursor: QueryIterationCursor<'w, 's, D, F>,
30}
31
32impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
33 /// # Safety
34 /// - `world` must have permission to access any of the components registered in `query_state`.
35 /// - `world` must be the same one used to initialize `query_state`.
36 pub(crate) unsafe fn new(
37 world: UnsafeWorldCell<'w>,
38 query_state: &'s QueryState<D, F>,
39 last_run: Tick,
40 this_run: Tick,
41 ) -> Self {
42 QueryIter {
43 world,
44 query_state,
45 // SAFETY: We only access table data that has been registered in `query_state`.
46 tables: unsafe { &world.storages().tables },
47 archetypes: world.archetypes(),
48 // SAFETY: The invariants are uphold by the caller.
49 cursor: unsafe { QueryIterationCursor::init(world, query_state, last_run, this_run) },
50 }
51 }
52
53 /// Creates a new separate iterator yielding the same remaining items of the current one.
54 /// Advancing the new iterator will not advance the original one, which will resume at the
55 /// point it was left at.
56 ///
57 /// Differently from [`remaining_mut`](QueryIter::remaining_mut) the new iterator does not
58 /// borrow from the original one. However it can only be called from an iterator over read only
59 /// items.
60 ///
61 /// # Example
62 ///
63 /// ```
64 /// # use bevy_ecs::prelude::*;
65 /// #
66 /// # #[derive(Component)]
67 /// # struct ComponentA;
68 ///
69 /// fn combinations(query: Query<&ComponentA>) {
70 /// let mut iter = query.iter();
71 /// while let Some(a) = iter.next() {
72 /// for b in iter.remaining() {
73 /// // Check every combination (a, b)
74 /// }
75 /// }
76 /// }
77 /// ```
78 pub fn remaining(&self) -> QueryIter<'w, 's, D, F>
79 where
80 D: ReadOnlyQueryData,
81 {
82 QueryIter {
83 world: self.world,
84 tables: self.tables,
85 archetypes: self.archetypes,
86 query_state: self.query_state,
87 cursor: self.cursor.clone(),
88 }
89 }
90
91 /// Creates a new separate iterator yielding the same remaining items of the current one.
92 /// Advancing the new iterator will not advance the original one, which will resume at the
93 /// point it was left at.
94 ///
95 /// This method can be called on iterators over mutable items. However the original iterator
96 /// will be borrowed while the new iterator exists and will thus not be usable in that timespan.
97 ///
98 /// # Example
99 ///
100 /// ```
101 /// # use bevy_ecs::prelude::*;
102 /// #
103 /// # #[derive(Component)]
104 /// # struct ComponentA;
105 ///
106 /// fn combinations(mut query: Query<&mut ComponentA>) {
107 /// let mut iter = query.iter_mut();
108 /// while let Some(a) = iter.next() {
109 /// for b in iter.remaining_mut() {
110 /// // Check every combination (a, b)
111 /// }
112 /// }
113 /// }
114 /// ```
115 pub fn remaining_mut(&mut self) -> QueryIter<'_, 's, D, F> {
116 QueryIter {
117 world: self.world,
118 tables: self.tables,
119 archetypes: self.archetypes,
120 query_state: self.query_state,
121 cursor: self.cursor.reborrow(),
122 }
123 }
124
125 /// Executes the equivalent of [`Iterator::fold`] over a contiguous segment
126 /// from an storage.
127 ///
128 /// # Safety
129 /// - `range` must be in `[0, storage::entity_count)` or None.
130 #[inline]
131 pub(super) unsafe fn fold_over_storage_range<B, Func>(
132 &mut self,
133 mut accum: B,
134 func: &mut Func,
135 storage: StorageId,
136 range: Option<Range<usize>>,
137 ) -> B
138 where
139 Func: FnMut(B, D::Item<'w>) -> B,
140 {
141 if self.cursor.is_dense {
142 // SAFETY: `self.cursor.is_dense` is true, so storage ids are guaranteed to be table ids.
143 let table_id = unsafe { storage.table_id };
144 // SAFETY: Matched table IDs are guaranteed to still exist.
145 let table = unsafe { self.tables.get(table_id).debug_checked_unwrap() };
146
147 let range = range.unwrap_or(0..table.entity_count());
148 accum =
149 // SAFETY:
150 // - The fetched table matches both D and F
151 // - caller ensures `range` is within `[0, table.entity_count)`
152 // - The if block ensures that the query iteration is dense
153 unsafe { self.fold_over_table_range(accum, func, table, range) };
154 } else {
155 // SAFETY: `self.cursor.is_dense` is false, so storage ids are guaranteed to be archetype ids.
156 let archetype_id = unsafe { storage.archetype_id };
157 // SAFETY: Matched archetype IDs are guaranteed to still exist.
158 let archetype = unsafe { self.archetypes.get(archetype_id).debug_checked_unwrap() };
159 // SAFETY: Matched table IDs are guaranteed to still exist.
160 let table = unsafe { self.tables.get(archetype.table_id()).debug_checked_unwrap() };
161
162 let range = range.unwrap_or(0..archetype.len());
163
164 // When an archetype and its table have equal entity counts, dense iteration can be safely used.
165 // this leverages cache locality to optimize performance.
166 if table.entity_count() == archetype.len() {
167 accum =
168 // SAFETY:
169 // - The fetched archetype matches both D and F
170 // - The provided archetype and its' table have the same length.
171 // - caller ensures `range` is within `[0, archetype.len)`
172 // - The if block ensures that the query iteration is not dense.
173 unsafe { self.fold_over_dense_archetype_range(accum, func, archetype,range) };
174 } else {
175 accum =
176 // SAFETY:
177 // - The fetched archetype matches both D and F
178 // - caller ensures `range` is within `[0, archetype.len)`
179 // - The if block ensures that the query iteration is not dense.
180 unsafe { self.fold_over_archetype_range(accum, func, archetype,range) };
181 }
182 }
183 accum
184 }
185
186 /// Executes the equivalent of [`Iterator::fold`] over a contiguous segment
187 /// from an table.
188 ///
189 /// # Safety
190 /// - all `rows` must be in `[0, table.entity_count)`.
191 /// - `table` must match D and F
192 /// - The query iteration must be dense (i.e. `self.query_state.is_dense` must be true).
193 #[inline]
194 pub(super) unsafe fn fold_over_table_range<B, Func>(
195 &mut self,
196 mut accum: B,
197 func: &mut Func,
198 table: &'w Table,
199 rows: Range<usize>,
200 ) -> B
201 where
202 Func: FnMut(B, D::Item<'w>) -> B,
203 {
204 if table.is_empty() {
205 return accum;
206 }
207 debug_assert!(
208 rows.end <= u32::MAX as usize,
209 "TableRow is only valid up to u32::MAX"
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) };
223 let row = TableRow::from_usize(row);
224
225 // SAFETY: set_table was called prior.
226 // Caller assures `row` in range of the current archetype.
227 let fetched = unsafe { !F::filter_fetch(&mut self.cursor.filter, *entity, row) };
228 if fetched {
229 continue;
230 }
231
232 // SAFETY: set_table was called prior.
233 // Caller assures `row` in range of the current archetype.
234 let item = D::fetch(&mut self.cursor.fetch, *entity, row);
235
236 accum = func(accum, item);
237 }
238 accum
239 }
240
241 /// Executes the equivalent of [`Iterator::fold`] over a contiguous segment
242 /// from an archetype.
243 ///
244 /// # Safety
245 /// - all `indices` must be in `[0, archetype.len())`.
246 /// - `archetype` must match D and F
247 /// - The query iteration must not be dense (i.e. `self.query_state.is_dense` must be false).
248 #[inline]
249 pub(super) unsafe fn fold_over_archetype_range<B, Func>(
250 &mut self,
251 mut accum: B,
252 func: &mut Func,
253 archetype: &'w Archetype,
254 indices: Range<usize>,
255 ) -> B
256 where
257 Func: FnMut(B, D::Item<'w>) -> B,
258 {
259 if archetype.is_empty() {
260 return accum;
261 }
262 let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();
263 D::set_archetype(
264 &mut self.cursor.fetch,
265 &self.query_state.fetch_state,
266 archetype,
267 table,
268 );
269 F::set_archetype(
270 &mut self.cursor.filter,
271 &self.query_state.filter_state,
272 archetype,
273 table,
274 );
275
276 let entities = archetype.entities();
277 for index in indices {
278 // SAFETY: Caller assures `index` in range of the current archetype.
279 let archetype_entity = unsafe { entities.get_unchecked(index) };
280
281 // SAFETY: set_archetype was called prior.
282 // Caller assures `index` in range of the current archetype.
283 let fetched = unsafe {
284 !F::filter_fetch(
285 &mut self.cursor.filter,
286 archetype_entity.id(),
287 archetype_entity.table_row(),
288 )
289 };
290 if fetched {
291 continue;
292 }
293
294 // SAFETY: set_archetype was called prior, `index` is an archetype index in range of the current archetype
295 // Caller assures `index` in range of the current archetype.
296 let item = unsafe {
297 D::fetch(
298 &mut self.cursor.fetch,
299 archetype_entity.id(),
300 archetype_entity.table_row(),
301 )
302 };
303
304 accum = func(accum, item);
305 }
306 accum
307 }
308
309 /// Executes the equivalent of [`Iterator::fold`] over a contiguous segment
310 /// from an archetype which has the same entity count as its table.
311 ///
312 /// # Safety
313 /// - all `indices` must be in `[0, archetype.len())`.
314 /// - `archetype` must match D and F
315 /// - `archetype` must have the same length with it's table.
316 /// - The query iteration must not be dense (i.e. `self.query_state.is_dense` must be false).
317 #[inline]
318 pub(super) unsafe fn fold_over_dense_archetype_range<B, Func>(
319 &mut self,
320 mut accum: B,
321 func: &mut Func,
322 archetype: &'w Archetype,
323 rows: Range<usize>,
324 ) -> B
325 where
326 Func: FnMut(B, D::Item<'w>) -> B,
327 {
328 if archetype.is_empty() {
329 return accum;
330 }
331 debug_assert!(
332 rows.end <= u32::MAX as usize,
333 "TableRow is only valid up to u32::MAX"
334 );
335 let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();
336 debug_assert!(
337 archetype.len() == table.entity_count(),
338 "archetype and it's table must have the same length. "
339 );
340
341 D::set_archetype(
342 &mut self.cursor.fetch,
343 &self.query_state.fetch_state,
344 archetype,
345 table,
346 );
347 F::set_archetype(
348 &mut self.cursor.filter,
349 &self.query_state.filter_state,
350 archetype,
351 table,
352 );
353 let entities = table.entities();
354 for row in rows {
355 // SAFETY: Caller assures `row` in range of the current archetype.
356 let entity = unsafe { *entities.get_unchecked(row) };
357 let row = TableRow::from_usize(row);
358
359 // SAFETY: set_table was called prior.
360 // Caller assures `row` in range of the current archetype.
361 let filter_matched = unsafe { F::filter_fetch(&mut self.cursor.filter, entity, row) };
362 if !filter_matched {
363 continue;
364 }
365
366 // SAFETY: set_table was called prior.
367 // Caller assures `row` in range of the current archetype.
368 let item = D::fetch(&mut self.cursor.fetch, entity, row);
369
370 accum = func(accum, item);
371 }
372 accum
373 }
374
375 /// Sorts all query items into a new iterator, using the query lens as a key.
376 ///
377 /// This sort is stable (i.e., does not reorder equal elements).
378 ///
379 /// This uses [`slice::sort`] internally.
380 ///
381 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
382 /// This includes the allowed parameter type changes listed under [allowed transmutes].
383 /// However, the lens uses the filter of the original query when present.
384 ///
385 /// The sort is not cached across system runs.
386 ///
387 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
388 ///
389 /// # Panics
390 ///
391 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
392 ///
393 /// # Examples
394 /// ```rust
395 /// # use bevy_ecs::prelude::*;
396 /// # use std::{ops::{Deref, DerefMut}, iter::Sum};
397 /// #
398 /// # #[derive(Component)]
399 /// # struct PartMarker;
400 /// #
401 /// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
402 /// # struct PartIndex(usize);
403 /// #
404 /// # #[derive(Component, Clone, Copy)]
405 /// # struct PartValue(f32);
406 /// #
407 /// # impl Deref for PartValue {
408 /// # type Target = f32;
409 /// #
410 /// # fn deref(&self) -> &Self::Target {
411 /// # &self.0
412 /// # }
413 /// # }
414 /// #
415 /// # #[derive(Component)]
416 /// # struct ParentValue(f32);
417 /// #
418 /// # impl Deref for ParentValue {
419 /// # type Target = f32;
420 /// #
421 /// # fn deref(&self) -> &Self::Target {
422 /// # &self.0
423 /// # }
424 /// # }
425 /// #
426 /// # impl DerefMut for ParentValue {
427 /// # fn deref_mut(&mut self) -> &mut Self::Target {
428 /// # &mut self.0
429 /// # }
430 /// # }
431 /// #
432 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
433 /// # struct Length(usize);
434 /// #
435 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
436 /// # struct Width(usize);
437 /// #
438 /// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]
439 /// # struct Height(usize);
440 /// #
441 /// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
442 /// # struct ParentEntity(Entity);
443 /// #
444 /// # #[derive(Component, Clone, Copy)]
445 /// # struct ChildPartCount(usize);
446 /// #
447 /// # impl Deref for ChildPartCount {
448 /// # type Target = usize;
449 /// #
450 /// # fn deref(&self) -> &Self::Target {
451 /// # &self.0
452 /// # }
453 /// # }
454 /// # let mut world = World::new();
455 /// // We can ensure that a query always returns in the same order.
456 /// fn system_1(query: Query<(Entity, &PartIndex)>) {
457 /// let parts: Vec<(Entity, &PartIndex)> = query.iter().sort::<&PartIndex>().collect();
458 /// }
459 ///
460 /// // We can freely rearrange query components in the key.
461 /// fn system_2(query: Query<(&Length, &Width, &Height), With<PartMarker>>) {
462 /// for (length, width, height) in query.iter().sort::<(&Height, &Length, &Width)>() {
463 /// println!("height: {height:?}, width: {width:?}, length: {length:?}")
464 /// }
465 /// }
466 ///
467 /// // We can sort by Entity without including it in the original Query.
468 /// // Here, we match iteration orders between query iterators.
469 /// fn system_3(
470 /// part_query: Query<(&PartValue, &ParentEntity)>,
471 /// mut parent_query: Query<(&ChildPartCount, &mut ParentValue)>,
472 /// ) {
473 /// let part_values = &mut part_query
474 /// .into_iter()
475 /// .sort::<&ParentEntity>()
476 /// .map(|(&value, parent_entity)| *value);
477 ///
478 /// for (&child_count, mut parent_value) in parent_query.iter_mut().sort::<Entity>() {
479 /// **parent_value = part_values.take(*child_count).sum();
480 /// }
481 /// }
482 /// #
483 /// # let mut schedule = Schedule::default();
484 /// # schedule.add_systems((system_1, system_2, system_3));
485 /// # schedule.run(&mut world);
486 /// ```
487 pub fn sort<L: ReadOnlyQueryData<Item<'w>: Ord> + 'w>(
488 self,
489 ) -> QuerySortedIter<
490 'w,
491 's,
492 D,
493 F,
494 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
495 > {
496 // On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`
497 // will be set to a non-zero value. The correctness of this method relies on this.
498 // I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a
499 // non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.
500 if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {
501 panic!("it is not valid to call sort() after next()")
502 }
503
504 let world = self.world;
505
506 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
507
508 // SAFETY:
509 // `self.world` has permission to access the required components.
510 // The original query iter has not been iterated on, so no items are aliased from it.
511 let query_lens = unsafe {
512 query_lens_state.iter_unchecked_manual(
513 world,
514 world.last_change_tick(),
515 world.change_tick(),
516 )
517 };
518 let mut keyed_query: Vec<_> = query_lens
519 .map(|(key, entity)| (key, NeutralOrd(entity)))
520 .collect();
521 keyed_query.sort();
522 let entity_iter = keyed_query.into_iter().map(|(.., entity)| entity.0);
523 // SAFETY:
524 // `self.world` has permission to access the required components.
525 // Each lens query item is dropped before the respective actual query item is accessed.
526 unsafe {
527 QuerySortedIter::new(
528 world,
529 self.query_state,
530 entity_iter,
531 world.last_change_tick(),
532 world.change_tick(),
533 )
534 }
535 }
536
537 /// Sorts all query items into a new iterator, using the query lens as a key.
538 ///
539 /// This sort is unstable (i.e., may reorder equal elements).
540 ///
541 /// This uses [`slice::sort_unstable`] internally.
542 ///
543 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
544 /// This includes the allowed parameter type changes listed under [allowed transmutes]..
545 /// However, the lens uses the filter of the original query when present.
546 ///
547 /// The sort is not cached across system runs.
548 ///
549 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
550 ///
551 /// # Panics
552 ///
553 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
554 ///
555 /// # Example
556 /// ```
557 /// # use bevy_ecs::prelude::*;
558 /// #
559 /// # let mut world = World::new();
560 /// #
561 /// # #[derive(Component)]
562 /// # struct PartMarker;
563 /// #
564 /// #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
565 /// enum Flying {
566 /// Enabled,
567 /// Disabled
568 /// };
569 ///
570 /// // We perform an unstable sort by a Component with few values.
571 /// fn system_1(query: Query<&Flying, With<PartMarker>>) {
572 /// let part_values: Vec<&Flying> = query.iter().sort_unstable::<&Flying>().collect();
573 /// }
574 /// #
575 /// # let mut schedule = Schedule::default();
576 /// # schedule.add_systems((system_1));
577 /// # schedule.run(&mut world);
578 /// ```
579 pub fn sort_unstable<L: ReadOnlyQueryData<Item<'w>: Ord> + 'w>(
580 self,
581 ) -> QuerySortedIter<
582 'w,
583 's,
584 D,
585 F,
586 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
587 > {
588 // On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`
589 // will be set to a non-zero value. The correctness of this method relies on this.
590 // I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a
591 // non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.
592 if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {
593 panic!("it is not valid to call sort() after next()")
594 }
595
596 let world = self.world;
597
598 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
599
600 // SAFETY:
601 // `self.world` has permission to access the required components.
602 // The original query iter has not been iterated on, so no items are aliased from it.
603 let query_lens = unsafe {
604 query_lens_state.iter_unchecked_manual(
605 world,
606 world.last_change_tick(),
607 world.change_tick(),
608 )
609 };
610 let mut keyed_query: Vec<_> = query_lens
611 .map(|(key, entity)| (key, NeutralOrd(entity)))
612 .collect();
613 keyed_query.sort_unstable();
614 let entity_iter = keyed_query.into_iter().map(|(.., entity)| entity.0);
615 // SAFETY:
616 // `self.world` has permission to access the required components.
617 // Each lens query item is dropped before the respective actual query item is accessed.
618 unsafe {
619 QuerySortedIter::new(
620 world,
621 self.query_state,
622 entity_iter,
623 world.last_change_tick(),
624 world.change_tick(),
625 )
626 }
627 }
628
629 /// Sorts all query items into a new iterator with a comparator function over the query lens.
630 ///
631 /// This sort is stable (i.e., does not reorder equal elements).
632 ///
633 /// This uses [`slice::sort_by`] internally.
634 ///
635 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
636 /// This includes the allowed parameter type changes listed under [allowed transmutes].
637 /// However, the lens uses the filter of the original query when present.
638 ///
639 /// The sort is not cached across system runs.
640 ///
641 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
642 ///
643 /// # Panics
644 ///
645 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
646 ///
647 /// # Example
648 /// ```
649 /// # use bevy_ecs::prelude::*;
650 /// # use std::ops::Deref;
651 /// #
652 /// # impl Deref for PartValue {
653 /// # type Target = f32;
654 /// #
655 /// # fn deref(&self) -> &Self::Target {
656 /// # &self.0
657 /// # }
658 /// # }
659 /// #
660 /// # let mut world = World::new();
661 /// #
662 /// #[derive(Component)]
663 /// struct PartValue(f32);
664 ///
665 /// // We can use a cmp function on components do not implement Ord.
666 /// fn system_1(query: Query<&PartValue>) {
667 /// // Sort part values according to `f32::total_comp`.
668 /// let part_values: Vec<&PartValue> = query
669 /// .iter()
670 /// .sort_by::<&PartValue>(|value_1, value_2| value_1.total_cmp(*value_2))
671 /// .collect();
672 /// }
673 /// #
674 /// # let mut schedule = Schedule::default();
675 /// # schedule.add_systems((system_1));
676 /// # schedule.run(&mut world);
677 /// ```
678 pub fn sort_by<L: ReadOnlyQueryData + 'w>(
679 self,
680 mut compare: impl FnMut(&L::Item<'w>, &L::Item<'w>) -> Ordering,
681 ) -> QuerySortedIter<
682 'w,
683 's,
684 D,
685 F,
686 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
687 > {
688 // On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`
689 // will be set to a non-zero value. The correctness of this method relies on this.
690 // I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a
691 // non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.
692 if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {
693 panic!("it is not valid to call sort() after next()")
694 }
695
696 let world = self.world;
697
698 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
699
700 // SAFETY:
701 // `self.world` has permission to access the required components.
702 // The original query iter has not been iterated on, so no items are aliased from it.
703 let query_lens = unsafe {
704 query_lens_state.iter_unchecked_manual(
705 world,
706 world.last_change_tick(),
707 world.change_tick(),
708 )
709 };
710 let mut keyed_query: Vec<_> = query_lens.collect();
711 keyed_query.sort_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));
712 let entity_iter = keyed_query.into_iter().map(|(.., entity)| entity);
713 // SAFETY:
714 // `self.world` has permission to access the required components.
715 // Each lens query item is dropped before the respective actual query item is accessed.
716 unsafe {
717 QuerySortedIter::new(
718 world,
719 self.query_state,
720 entity_iter,
721 world.last_change_tick(),
722 world.change_tick(),
723 )
724 }
725 }
726
727 /// Sorts all query items into a new iterator with a comparator function over the query lens.
728 ///
729 /// This sort is unstable (i.e., may reorder equal elements).
730 ///
731 /// This uses [`slice::sort_unstable_by`] internally.
732 ///
733 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
734 /// This includes the allowed parameter type changes listed under [allowed transmutes].
735 /// However, the lens uses the filter of the original query when present.
736 ///
737 /// The sort is not cached across system runs.
738 ///
739 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
740 ///
741 /// # Panics
742 ///
743 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
744 pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(
745 self,
746 mut compare: impl FnMut(&L::Item<'w>, &L::Item<'w>) -> Ordering,
747 ) -> QuerySortedIter<
748 'w,
749 's,
750 D,
751 F,
752 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
753 > {
754 // On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`
755 // will be set to a non-zero value. The correctness of this method relies on this.
756 // I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a
757 // non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.
758 if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {
759 panic!("it is not valid to call sort() after next()")
760 }
761
762 let world = self.world;
763
764 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
765
766 // SAFETY:
767 // `self.world` has permission to access the required components.
768 // The original query iter has not been iterated on, so no items are aliased from it.
769 let query_lens = unsafe {
770 query_lens_state.iter_unchecked_manual(
771 world,
772 world.last_change_tick(),
773 world.change_tick(),
774 )
775 };
776 let mut keyed_query: Vec<_> = query_lens.collect();
777 keyed_query.sort_unstable_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));
778 let entity_iter = keyed_query.into_iter().map(|(.., entity)| entity);
779 // SAFETY:
780 // `self.world` has permission to access the required components.
781 // Each lens query item is dropped before the respective actual query item is accessed.
782 unsafe {
783 QuerySortedIter::new(
784 world,
785 self.query_state,
786 entity_iter,
787 world.last_change_tick(),
788 world.change_tick(),
789 )
790 }
791 }
792
793 /// Sorts all query items into a new iterator with a key extraction function over the query lens.
794 ///
795 /// This sort is stable (i.e., does not reorder equal elements).
796 ///
797 /// This uses [`slice::sort_by_key`] internally.
798 ///
799 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
800 /// This includes the allowed parameter type changes listed under [allowed transmutes].
801 /// However, the lens uses the filter of the original query when present.
802 ///
803 /// The sort is not cached across system runs.
804 ///
805 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
806 ///
807 /// # Panics
808 ///
809 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
810 ///
811 /// # Example
812 /// ```
813 /// # use bevy_ecs::prelude::*;
814 /// # use std::ops::Deref;
815 /// #
816 /// # #[derive(Component)]
817 /// # struct PartMarker;
818 /// #
819 /// # impl Deref for PartValue {
820 /// # type Target = f32;
821 /// #
822 /// # fn deref(&self) -> &Self::Target {
823 /// # &self.0
824 /// # }
825 /// # }
826 /// #
827 /// # let mut world = World::new();
828 /// #
829 /// #[derive(Component)]
830 /// struct AvailableMarker;
831 ///
832 /// #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]
833 /// enum Rarity {
834 /// Common,
835 /// Rare,
836 /// Epic,
837 /// Legendary
838 /// };
839 ///
840 /// #[derive(Component)]
841 /// struct PartValue(f32);
842 ///
843 /// // We can sort with the internals of components that do not implement Ord.
844 /// fn system_1(query: Query<(Entity, &PartValue)>) {
845 /// // Sort by the sines of the part values.
846 /// let parts: Vec<(Entity, &PartValue)> = query
847 /// .iter()
848 /// .sort_by_key::<&PartValue, _>(|value| value.sin() as usize)
849 /// .collect();
850 /// }
851 ///
852 /// // We can define our own custom comparison functions over an EntityRef.
853 /// fn system_2(query: Query<EntityRef, With<PartMarker>>) {
854 /// // Sort by whether parts are available and their rarity.
855 /// // We want the available legendaries to come first, so we reverse the iterator.
856 /// let parts: Vec<EntityRef> = query.iter()
857 /// .sort_by_key::<EntityRef, _>(|entity_ref| {
858 /// (
859 /// entity_ref.contains::<AvailableMarker>(),
860 /// entity_ref.get::<Rarity>()
861 /// )
862 /// })
863 /// .rev()
864 /// .collect();
865 /// }
866 /// # let mut schedule = Schedule::default();
867 /// # schedule.add_systems((system_1, system_2));
868 /// # schedule.run(&mut world);
869 /// ```
870 pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(
871 self,
872 mut f: impl FnMut(&L::Item<'w>) -> K,
873 ) -> QuerySortedIter<
874 'w,
875 's,
876 D,
877 F,
878 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
879 >
880 where
881 K: Ord,
882 {
883 // On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`
884 // will be set to a non-zero value. The correctness of this method relies on this.
885 // I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a
886 // non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.
887 if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {
888 panic!("it is not valid to call sort() after next()")
889 }
890
891 let world = self.world;
892
893 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
894
895 // SAFETY:
896 // `self.world` has permission to access the required components.
897 // The original query iter has not been iterated on, so no items are aliased from it.
898 let query_lens = unsafe {
899 query_lens_state.iter_unchecked_manual(
900 world,
901 world.last_change_tick(),
902 world.change_tick(),
903 )
904 };
905 let mut keyed_query: Vec<_> = query_lens.collect();
906 keyed_query.sort_by_key(|(lens, _)| f(lens));
907 let entity_iter = keyed_query.into_iter().map(|(.., entity)| entity);
908 // SAFETY:
909 // `self.world` has permission to access the required components.
910 // Each lens query item is dropped before the respective actual query item is accessed.
911 unsafe {
912 QuerySortedIter::new(
913 world,
914 self.query_state,
915 entity_iter,
916 world.last_change_tick(),
917 world.change_tick(),
918 )
919 }
920 }
921
922 /// Sorts all query items into a new iterator with a key extraction function over the query lens.
923 ///
924 /// This sort is unstable (i.e., may reorder equal elements).
925 ///
926 /// This uses [`slice::sort_unstable_by_key`] internally.
927 ///
928 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
929 /// This includes the allowed parameter type changes listed under [allowed transmutes].
930 /// However, the lens uses the filter of the original query when present.
931 ///
932 /// The sort is not cached across system runs.
933 ///
934 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
935 ///
936 /// # Panics
937 ///
938 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
939 pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(
940 self,
941 mut f: impl FnMut(&L::Item<'w>) -> K,
942 ) -> QuerySortedIter<
943 'w,
944 's,
945 D,
946 F,
947 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
948 >
949 where
950 K: Ord,
951 {
952 // On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`
953 // will be set to a non-zero value. The correctness of this method relies on this.
954 // I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a
955 // non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.
956 if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {
957 panic!("it is not valid to call sort() after next()")
958 }
959
960 let world = self.world;
961
962 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
963
964 // SAFETY:
965 // `self.world` has permission to access the required components.
966 // The original query iter has not been iterated on, so no items are aliased from it.
967 let query_lens = unsafe {
968 query_lens_state.iter_unchecked_manual(
969 world,
970 world.last_change_tick(),
971 world.change_tick(),
972 )
973 };
974 let mut keyed_query: Vec<_> = query_lens.collect();
975 keyed_query.sort_unstable_by_key(|(lens, _)| f(lens));
976 let entity_iter = keyed_query.into_iter().map(|(.., entity)| entity);
977 // SAFETY:
978 // `self.world` has permission to access the required components.
979 // Each lens query item is dropped before the respective actual query item is accessed.
980 unsafe {
981 QuerySortedIter::new(
982 world,
983 self.query_state,
984 entity_iter,
985 world.last_change_tick(),
986 world.change_tick(),
987 )
988 }
989 }
990
991 /// Sort all query items into a new iterator with a key extraction function over the query lens.
992 ///
993 /// This sort is stable (i.e., does not reorder equal elements).
994 ///
995 /// This uses [`slice::sort_by_cached_key`] internally.
996 ///
997 /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).
998 /// This includes the allowed parameter type changes listed under [allowed transmutes].
999 /// However, the lens uses the filter of the original query when present.
1000 ///
1001 /// The sort is not cached across system runs.
1002 ///
1003 /// [allowed transmutes]: crate::system::Query#allowed-transmutes
1004 ///
1005 /// # Panics
1006 ///
1007 /// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
1008 pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(
1009 self,
1010 mut f: impl FnMut(&L::Item<'w>) -> K,
1011 ) -> QuerySortedIter<
1012 'w,
1013 's,
1014 D,
1015 F,
1016 impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
1017 >
1018 where
1019 K: Ord,
1020 {
1021 // On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`
1022 // will be set to a non-zero value. The correctness of this method relies on this.
1023 // I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a
1024 // non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.
1025 if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {
1026 panic!("it is not valid to call sort() after next()")
1027 }
1028
1029 let world = self.world;
1030
1031 let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);
1032
1033 // SAFETY:
1034 // `self.world` has permission to access the required components.
1035 // The original query iter has not been iterated on, so no items are aliased from it.
1036 let query_lens = unsafe {
1037 query_lens_state.iter_unchecked_manual(
1038 world,
1039 world.last_change_tick(),
1040 world.change_tick(),
1041 )
1042 };
1043 let mut keyed_query: Vec<_> = query_lens.collect();
1044 keyed_query.sort_by_cached_key(|(lens, _)| f(lens));
1045 let entity_iter = keyed_query.into_iter().map(|(.., entity)| entity);
1046 // SAFETY:
1047 // `self.world` has permission to access the required components.
1048 // Each lens query item is dropped before the respective actual query item is accessed.
1049 unsafe {
1050 QuerySortedIter::new(
1051 world,
1052 self.query_state,
1053 entity_iter,
1054 world.last_change_tick(),
1055 world.change_tick(),
1056 )
1057 }
1058 }
1059}
1060
1061impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F> {
1062 type Item = D::Item<'w>;
1063
1064 #[inline(always)]
1065 fn next(&mut self) -> Option<Self::Item> {
1066 // SAFETY:
1067 // `tables` and `archetypes` belong to the same world that the cursor was initialized for.
1068 // `query_state` is the state that was passed to `QueryIterationCursor::init`.
1069 unsafe {
1070 self.cursor
1071 .next(self.tables, self.archetypes, self.query_state)
1072 }
1073 }
1074
1075 fn size_hint(&self) -> (usize, Option<usize>) {
1076 let max_size = self.cursor.max_remaining(self.tables, self.archetypes);
1077 let archetype_query = F::IS_ARCHETYPAL;
1078 let min_size = if archetype_query { max_size } else { 0 };
1079 (min_size, Some(max_size))
1080 }
1081
1082 #[inline]
1083 fn fold<B, Func>(mut self, init: B, mut func: Func) -> B
1084 where
1085 Func: FnMut(B, Self::Item) -> B,
1086 {
1087 let mut accum = init;
1088 // Empty any remaining uniterated values from the current table/archetype
1089 while self.cursor.current_row != self.cursor.current_len {
1090 let Some(item) = self.next() else { break };
1091 accum = func(accum, item);
1092 }
1093
1094 for id in self.cursor.storage_id_iter.clone().copied() {
1095 // SAFETY:
1096 // - The range(None) is equivalent to [0, storage.entity_count)
1097 accum = unsafe { self.fold_over_storage_range(accum, &mut func, id, None) };
1098 }
1099 accum
1100 }
1101}
1102
1103// This is correct as [`QueryIter`] always returns `None` once exhausted.
1104impl<'w, 's, D: QueryData, F: QueryFilter> FusedIterator for QueryIter<'w, 's, D, F> {}
1105
1106impl<'w, 's, D: QueryData, F: QueryFilter> Debug for QueryIter<'w, 's, D, F> {
1107 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1108 f.debug_struct("QueryIter").finish()
1109 }
1110}
1111
1112/// An [`Iterator`] over sorted query results of a [`Query`](crate::system::Query).
1113///
1114/// This struct is created by the [`QueryIter::sort`], [`QueryIter::sort_unstable`],
1115/// [`QueryIter::sort_by`], [`QueryIter::sort_unstable_by`], [`QueryIter::sort_by_key`],
1116/// [`QueryIter::sort_unstable_by_key`], and [`QueryIter::sort_by_cached_key`] methods.
1117pub struct QuerySortedIter<'w, 's, D: QueryData, F: QueryFilter, I>
1118where
1119 I: Iterator<Item = Entity>,
1120{
1121 entity_iter: I,
1122 entities: &'w Entities,
1123 tables: &'w Tables,
1124 archetypes: &'w Archetypes,
1125 fetch: D::Fetch<'w>,
1126 query_state: &'s QueryState<D, F>,
1127}
1128
1129impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> QuerySortedIter<'w, 's, D, F, I>
1130where
1131 I: Iterator<Item = Entity>,
1132{
1133 /// # Safety
1134 /// - `world` must have permission to access any of the components registered in `query_state`.
1135 /// - `world` must be the same one used to initialize `query_state`.
1136 /// - `entity_list` must only contain unique entities or be empty.
1137 pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(
1138 world: UnsafeWorldCell<'w>,
1139 query_state: &'s QueryState<D, F>,
1140 entity_list: EntityList,
1141 last_run: Tick,
1142 this_run: Tick,
1143 ) -> QuerySortedIter<'w, 's, D, F, I> {
1144 let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
1145 QuerySortedIter {
1146 query_state,
1147 entities: world.entities(),
1148 archetypes: world.archetypes(),
1149 // SAFETY: We only access table data that has been registered in `query_state`.
1150 // This means `world` has permission to access the data we use.
1151 tables: &world.storages().tables,
1152 fetch,
1153 entity_iter: entity_list.into_iter(),
1154 }
1155 }
1156
1157 /// # Safety
1158 /// `entity` must stem from `self.entity_iter`, and not have been passed before.
1159 #[inline(always)]
1160 unsafe fn fetch_next(&mut self, entity: Entity) -> D::Item<'w> {
1161 let (location, archetype, table);
1162 // SAFETY:
1163 // `tables` and `archetypes` belong to the same world that the [`QueryIter`]
1164 // was initialized for.
1165 unsafe {
1166 location = self.entities.get(entity).debug_checked_unwrap();
1167 archetype = self
1168 .archetypes
1169 .get(location.archetype_id)
1170 .debug_checked_unwrap();
1171 table = self.tables.get(location.table_id).debug_checked_unwrap();
1172 }
1173
1174 // SAFETY: `archetype` is from the world that `fetch` was created for,
1175 // `fetch_state` is the state that `fetch` was initialized with
1176 unsafe {
1177 D::set_archetype(
1178 &mut self.fetch,
1179 &self.query_state.fetch_state,
1180 archetype,
1181 table,
1182 );
1183 }
1184
1185 // The entity list has already been filtered by the query lens, so we forego filtering here.
1186 // SAFETY:
1187 // - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
1188 // - fetch is only called once for each entity.
1189 unsafe { D::fetch(&mut self.fetch, entity, location.table_row) }
1190 }
1191}
1192
1193impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> Iterator
1194 for QuerySortedIter<'w, 's, D, F, I>
1195where
1196 I: Iterator<Item = Entity>,
1197{
1198 type Item = D::Item<'w>;
1199
1200 #[inline(always)]
1201 fn next(&mut self) -> Option<Self::Item> {
1202 let entity = self.entity_iter.next()?;
1203 // SAFETY: `entity` is passed from `entity_iter` the first time.
1204 unsafe { self.fetch_next(entity).into() }
1205 }
1206
1207 fn size_hint(&self) -> (usize, Option<usize>) {
1208 self.entity_iter.size_hint()
1209 }
1210}
1211
1212impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> DoubleEndedIterator
1213 for QuerySortedIter<'w, 's, D, F, I>
1214where
1215 I: DoubleEndedIterator<Item = Entity>,
1216{
1217 #[inline(always)]
1218 fn next_back(&mut self) -> Option<Self::Item> {
1219 let entity = self.entity_iter.next_back()?;
1220 // SAFETY: `entity` is passed from `entity_iter` the first time.
1221 unsafe { self.fetch_next(entity).into() }
1222 }
1223}
1224
1225impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> ExactSizeIterator
1226 for QuerySortedIter<'w, 's, D, F, I>
1227where
1228 I: ExactSizeIterator<Item = Entity>,
1229{
1230}
1231
1232// This is correct as [`QuerySortedIter`] returns `None` once exhausted if `entity_iter` does.
1233impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> FusedIterator
1234 for QuerySortedIter<'w, 's, D, F, I>
1235where
1236 I: FusedIterator<Item = Entity>,
1237{
1238}
1239
1240impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> Debug
1241 for QuerySortedIter<'w, 's, D, F, I>
1242{
1243 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1244 f.debug_struct("QuerySortedIter").finish()
1245 }
1246}
1247
1248/// An [`Iterator`] over the query items generated from an iterator of [`Entity`]s.
1249///
1250/// Items are returned in the order of the provided iterator.
1251/// Entities that don't match the query are skipped.
1252///
1253/// 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.
1254pub struct QueryManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: Borrow<Entity>>> {
1255 entity_iter: I,
1256 entities: &'w Entities,
1257 tables: &'w Tables,
1258 archetypes: &'w Archetypes,
1259 fetch: D::Fetch<'w>,
1260 filter: F::Fetch<'w>,
1261 query_state: &'s QueryState<D, F>,
1262}
1263
1264impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: Borrow<Entity>>>
1265 QueryManyIter<'w, 's, D, F, I>
1266{
1267 /// # Safety
1268 /// - `world` must have permission to access any of the components registered in `query_state`.
1269 /// - `world` must be the same one used to initialize `query_state`.
1270 pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(
1271 world: UnsafeWorldCell<'w>,
1272 query_state: &'s QueryState<D, F>,
1273 entity_list: EntityList,
1274 last_run: Tick,
1275 this_run: Tick,
1276 ) -> QueryManyIter<'w, 's, D, F, I> {
1277 let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
1278 let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);
1279 QueryManyIter {
1280 query_state,
1281 entities: world.entities(),
1282 archetypes: world.archetypes(),
1283 // SAFETY: We only access table data that has been registered in `query_state`.
1284 // This means `world` has permission to access the data we use.
1285 tables: &world.storages().tables,
1286 fetch,
1287 filter,
1288 entity_iter: entity_list.into_iter(),
1289 }
1290 }
1291
1292 /// # Safety
1293 /// All arguments must stem from the same valid `QueryManyIter`.
1294 ///
1295 /// The lifetime here is not restrictive enough for Fetch with &mut access,
1296 /// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple
1297 /// references to the same component, leading to unique reference aliasing.
1298 ///
1299 /// It is always safe for shared access.
1300 #[inline(always)]
1301 unsafe fn fetch_next_aliased_unchecked(
1302 entity_iter: impl Iterator<Item: Borrow<Entity>>,
1303 entities: &'w Entities,
1304 tables: &'w Tables,
1305 archetypes: &'w Archetypes,
1306 fetch: &mut D::Fetch<'w>,
1307 filter: &mut F::Fetch<'w>,
1308 query_state: &'s QueryState<D, F>,
1309 ) -> Option<D::Item<'w>> {
1310 for entity in entity_iter {
1311 let entity = *entity.borrow();
1312 let Some(location) = entities.get(entity) else {
1313 continue;
1314 };
1315
1316 if !query_state
1317 .matched_archetypes
1318 .contains(location.archetype_id.index())
1319 {
1320 continue;
1321 }
1322
1323 let archetype = archetypes.get(location.archetype_id).debug_checked_unwrap();
1324 let table = tables.get(location.table_id).debug_checked_unwrap();
1325
1326 // SAFETY: `archetype` is from the world that `fetch/filter` were created for,
1327 // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
1328 unsafe {
1329 D::set_archetype(fetch, &query_state.fetch_state, archetype, table);
1330 }
1331 // SAFETY: `table` is from the world that `fetch/filter` were created for,
1332 // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
1333 unsafe {
1334 F::set_archetype(filter, &query_state.filter_state, archetype, table);
1335 }
1336
1337 // SAFETY: set_archetype was called prior.
1338 // `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
1339 if unsafe { F::filter_fetch(filter, entity, location.table_row) } {
1340 // SAFETY:
1341 // - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
1342 // - fetch is only called once for each entity.
1343 return Some(unsafe { D::fetch(fetch, entity, location.table_row) });
1344 }
1345 }
1346 None
1347 }
1348
1349 /// Get next result from the query
1350 #[inline(always)]
1351 pub fn fetch_next(&mut self) -> Option<D::Item<'_>> {
1352 // SAFETY:
1353 // All arguments stem from self.
1354 // We are limiting the returned reference to self,
1355 // making sure this method cannot be called multiple times without getting rid
1356 // of any previously returned unique references first, thus preventing aliasing.
1357 unsafe {
1358 Self::fetch_next_aliased_unchecked(
1359 &mut self.entity_iter,
1360 self.entities,
1361 self.tables,
1362 self.archetypes,
1363 &mut self.fetch,
1364 &mut self.filter,
1365 self.query_state,
1366 )
1367 .map(D::shrink)
1368 }
1369 }
1370}
1371
1372impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item: Borrow<Entity>>>
1373 QueryManyIter<'w, 's, D, F, I>
1374{
1375 /// Get next result from the back of the query
1376 #[inline(always)]
1377 pub fn fetch_next_back(&mut self) -> Option<D::Item<'_>> {
1378 // SAFETY:
1379 // All arguments stem from self.
1380 // We are limiting the returned reference to self,
1381 // making sure this method cannot be called multiple times without getting rid
1382 // of any previously returned unique references first, thus preventing aliasing.
1383 unsafe {
1384 Self::fetch_next_aliased_unchecked(
1385 self.entity_iter.by_ref().rev(),
1386 self.entities,
1387 self.tables,
1388 self.archetypes,
1389 &mut self.fetch,
1390 &mut self.filter,
1391 self.query_state,
1392 )
1393 .map(D::shrink)
1394 }
1395 }
1396}
1397
1398impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: Borrow<Entity>>> Iterator
1399 for QueryManyIter<'w, 's, D, F, I>
1400{
1401 type Item = D::Item<'w>;
1402
1403 #[inline(always)]
1404 fn next(&mut self) -> Option<Self::Item> {
1405 // SAFETY:
1406 // All arguments stem from self.
1407 // It is safe to alias for ReadOnlyWorldQuery.
1408 unsafe {
1409 Self::fetch_next_aliased_unchecked(
1410 &mut self.entity_iter,
1411 self.entities,
1412 self.tables,
1413 self.archetypes,
1414 &mut self.fetch,
1415 &mut self.filter,
1416 self.query_state,
1417 )
1418 }
1419 }
1420
1421 fn size_hint(&self) -> (usize, Option<usize>) {
1422 let (_, max_size) = self.entity_iter.size_hint();
1423 (0, max_size)
1424 }
1425}
1426
1427impl<
1428 'w,
1429 's,
1430 D: ReadOnlyQueryData,
1431 F: QueryFilter,
1432 I: DoubleEndedIterator<Item: Borrow<Entity>>,
1433 > DoubleEndedIterator for QueryManyIter<'w, 's, D, F, I>
1434{
1435 #[inline(always)]
1436 fn next_back(&mut self) -> Option<Self::Item> {
1437 // SAFETY:
1438 // All arguments stem from self.
1439 // It is safe to alias for ReadOnlyWorldQuery.
1440 unsafe {
1441 Self::fetch_next_aliased_unchecked(
1442 self.entity_iter.by_ref().rev(),
1443 self.entities,
1444 self.tables,
1445 self.archetypes,
1446 &mut self.fetch,
1447 &mut self.filter,
1448 self.query_state,
1449 )
1450 }
1451 }
1452}
1453
1454// This is correct as [`QueryManyIter`] always returns `None` once exhausted.
1455impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: Borrow<Entity>>> FusedIterator
1456 for QueryManyIter<'w, 's, D, F, I>
1457{
1458}
1459
1460impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: Borrow<Entity>>> Debug
1461 for QueryManyIter<'w, 's, D, F, I>
1462{
1463 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1464 f.debug_struct("QueryManyIter").finish()
1465 }
1466}
1467
1468/// An iterator over `K`-sized combinations of query items without repetition.
1469///
1470/// A combination is an arrangement of a collection of items where order does not matter.
1471///
1472/// `K` is the number of items that make up each subset, and the number of items returned by the iterator.
1473/// `N` is the number of total entities output by the query.
1474///
1475/// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are
1476/// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].
1477/// And in this case, `N` would be defined as 4 since the size of the input list is 4.
1478///
1479/// The number of combinations depend on how `K` relates to the number of entities matching the [`Query`]:
1480/// - if `K = N`, only one combination exists,
1481/// - if `K < N`, there are <sub>N</sub>C<sub>K</sub> combinations (see the [performance section] of `Query`),
1482/// - if `K > N`, there are no combinations.
1483///
1484/// The output combination is not guaranteed to have any order of iteration.
1485///
1486/// # Usage
1487///
1488/// This type is returned by calling [`Query::iter_combinations`] or [`Query::iter_combinations_mut`].
1489///
1490/// It implements [`Iterator`] only if it iterates over read-only query items ([learn more]).
1491///
1492/// In the case of mutable query items, it can be iterated by calling [`fetch_next`] in a `while let` loop.
1493///
1494/// # Examples
1495///
1496/// The following example shows how to traverse the iterator when the query items are read-only.
1497///
1498/// ```
1499/// # use bevy_ecs::prelude::*;
1500/// # #[derive(Component)]
1501/// # struct ComponentA;
1502/// #
1503/// fn some_system(query: Query<&ComponentA>) {
1504/// for [a1, a2] in query.iter_combinations() {
1505/// // ...
1506/// }
1507/// }
1508/// ```
1509///
1510/// 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.
1511///
1512/// ```
1513/// # use bevy_ecs::prelude::*;
1514/// # #[derive(Component)]
1515/// # struct ComponentA;
1516/// #
1517/// fn some_system(mut query: Query<&mut ComponentA>) {
1518/// let mut combinations = query.iter_combinations_mut();
1519/// while let Some([a1, a2]) = combinations.fetch_next() {
1520/// // ...
1521/// }
1522/// }
1523/// ```
1524///
1525/// [`fetch_next`]: Self::fetch_next
1526/// [learn more]: Self#impl-Iterator
1527/// [performance section]: crate::system::Query#performance
1528/// [`Query`]: crate::system::Query
1529/// [`Query::iter_combinations`]: crate::system::Query::iter_combinations
1530/// [`Query::iter_combinations_mut`]: crate::system::Query::iter_combinations_mut
1531pub struct QueryCombinationIter<'w, 's, D: QueryData, F: QueryFilter, const K: usize> {
1532 tables: &'w Tables,
1533 archetypes: &'w Archetypes,
1534 query_state: &'s QueryState<D, F>,
1535 cursors: [QueryIterationCursor<'w, 's, D, F>; K],
1536}
1537
1538impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<'w, 's, D, F, K> {
1539 /// # Safety
1540 /// - `world` must have permission to access any of the components registered in `query_state`.
1541 /// - `world` must be the same one used to initialize `query_state`.
1542 pub(crate) unsafe fn new(
1543 world: UnsafeWorldCell<'w>,
1544 query_state: &'s QueryState<D, F>,
1545 last_run: Tick,
1546 this_run: Tick,
1547 ) -> Self {
1548 assert!(K != 0, "K should not equal to zero");
1549 // Initialize array with cursors.
1550 // There is no FromIterator on arrays, so instead initialize it manually with MaybeUninit
1551
1552 let mut array: MaybeUninit<[QueryIterationCursor<'w, 's, D, F>; K]> = MaybeUninit::uninit();
1553 let ptr = array
1554 .as_mut_ptr()
1555 .cast::<QueryIterationCursor<'w, 's, D, F>>();
1556 ptr.write(QueryIterationCursor::init(
1557 world,
1558 query_state,
1559 last_run,
1560 this_run,
1561 ));
1562 for slot in (1..K).map(|offset| ptr.add(offset)) {
1563 slot.write(QueryIterationCursor::init_empty(
1564 world,
1565 query_state,
1566 last_run,
1567 this_run,
1568 ));
1569 }
1570
1571 QueryCombinationIter {
1572 query_state,
1573 // SAFETY: We only access table data that has been registered in `query_state`.
1574 tables: unsafe { &world.storages().tables },
1575 archetypes: world.archetypes(),
1576 cursors: array.assume_init(),
1577 }
1578 }
1579
1580 /// # Safety
1581 /// The lifetime here is not restrictive enough for Fetch with &mut access,
1582 /// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple
1583 /// references to the same component, leading to unique reference aliasing.
1584 /// .
1585 /// It is always safe for shared access.
1586 #[inline]
1587 unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<[D::Item<'w>; K]> {
1588 // PERF: can speed up the following code using `cursor.remaining()` instead of `next_item.is_none()`
1589 // when D::IS_ARCHETYPAL && F::IS_ARCHETYPAL
1590 //
1591 // let `i` be the index of `c`, the last cursor in `self.cursors` that
1592 // returns `K-i` or more elements.
1593 // Make cursor in index `j` for all `j` in `[i, K)` a copy of `c` advanced `j-i+1` times.
1594 // If no such `c` exists, return `None`
1595 'outer: for i in (0..K).rev() {
1596 match self.cursors[i].next(self.tables, self.archetypes, self.query_state) {
1597 Some(_) => {
1598 for j in (i + 1)..K {
1599 self.cursors[j] = self.cursors[j - 1].clone();
1600 match self.cursors[j].next(self.tables, self.archetypes, self.query_state) {
1601 Some(_) => {}
1602 None if i > 0 => continue 'outer,
1603 None => return None,
1604 }
1605 }
1606 break;
1607 }
1608 None if i > 0 => continue,
1609 None => return None,
1610 }
1611 }
1612
1613 let mut values = MaybeUninit::<[D::Item<'w>; K]>::uninit();
1614
1615 let ptr = values.as_mut_ptr().cast::<D::Item<'w>>();
1616 for (offset, cursor) in self.cursors.iter_mut().enumerate() {
1617 ptr.add(offset).write(cursor.peek_last().unwrap());
1618 }
1619
1620 Some(values.assume_init())
1621 }
1622
1623 /// Get next combination of queried components
1624 #[inline]
1625 pub fn fetch_next(&mut self) -> Option<[D::Item<'_>; K]> {
1626 // SAFETY: we are limiting the returned reference to self,
1627 // making sure this method cannot be called multiple times without getting rid
1628 // of any previously returned unique references first, thus preventing aliasing.
1629 unsafe {
1630 self.fetch_next_aliased_unchecked()
1631 .map(|array| array.map(D::shrink))
1632 }
1633 }
1634}
1635
1636// Iterator type is intentionally implemented only for read-only access.
1637// Doing so for mutable references would be unsound, because calling `next`
1638// multiple times would allow multiple owned references to the same data to exist.
1639impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator
1640 for QueryCombinationIter<'w, 's, D, F, K>
1641{
1642 type Item = [D::Item<'w>; K];
1643
1644 #[inline]
1645 fn next(&mut self) -> Option<Self::Item> {
1646 // Safety: it is safe to alias for ReadOnlyWorldQuery
1647 unsafe { QueryCombinationIter::fetch_next_aliased_unchecked(self) }
1648 }
1649
1650 fn size_hint(&self) -> (usize, Option<usize>) {
1651 // binomial coefficient: (n ; k) = n! / k!(n-k)! = (n*n-1*...*n-k+1) / k!
1652 // See https://en.wikipedia.org/wiki/Binomial_coefficient
1653 // See https://blog.plover.com/math/choose.html for implementation
1654 // It was chosen to reduce overflow potential.
1655 fn choose(n: usize, k: usize) -> Option<usize> {
1656 if k > n || n == 0 {
1657 return Some(0);
1658 }
1659 let k = k.min(n - k);
1660 let ks = 1..=k;
1661 let ns = (n - k + 1..=n).rev();
1662 ks.zip(ns)
1663 .try_fold(1_usize, |acc, (k, n)| Some(acc.checked_mul(n)? / k))
1664 }
1665 // sum_i=0..k choose(cursors[i].remaining, k-i)
1666 let max_combinations = self
1667 .cursors
1668 .iter()
1669 .enumerate()
1670 .try_fold(0, |acc, (i, cursor)| {
1671 let n = cursor.max_remaining(self.tables, self.archetypes);
1672 Some(acc + choose(n, K - i)?)
1673 });
1674
1675 let archetype_query = F::IS_ARCHETYPAL;
1676 let known_max = max_combinations.unwrap_or(usize::MAX);
1677 let min_combinations = if archetype_query { known_max } else { 0 };
1678 (min_combinations, max_combinations)
1679 }
1680}
1681
1682impl<'w, 's, D: QueryData, F: QueryFilter> ExactSizeIterator for QueryIter<'w, 's, D, F>
1683where
1684 F: ArchetypeFilter,
1685{
1686 fn len(&self) -> usize {
1687 self.size_hint().0
1688 }
1689}
1690
1691// This is correct as [`QueryCombinationIter`] always returns `None` once exhausted.
1692impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> FusedIterator
1693 for QueryCombinationIter<'w, 's, D, F, K>
1694{
1695}
1696
1697impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> Debug
1698 for QueryCombinationIter<'w, 's, D, F, K>
1699{
1700 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1701 f.debug_struct("QueryCombinationIter").finish()
1702 }
1703}
1704
1705struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> {
1706 // whether the query iteration is dense or not. Mirrors QueryState's `is_dense` field.
1707 is_dense: bool,
1708 storage_id_iter: core::slice::Iter<'s, StorageId>,
1709 table_entities: &'w [Entity],
1710 archetype_entities: &'w [ArchetypeEntity],
1711 fetch: D::Fetch<'w>,
1712 filter: F::Fetch<'w>,
1713 // length of the table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense
1714 current_len: usize,
1715 // either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense
1716 current_row: usize,
1717}
1718
1719impl<D: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, D, F> {
1720 fn clone(&self) -> Self {
1721 Self {
1722 is_dense: self.is_dense,
1723 storage_id_iter: self.storage_id_iter.clone(),
1724 table_entities: self.table_entities,
1725 archetype_entities: self.archetype_entities,
1726 fetch: self.fetch.clone(),
1727 filter: self.filter.clone(),
1728 current_len: self.current_len,
1729 current_row: self.current_row,
1730 }
1731 }
1732}
1733
1734impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
1735 /// # Safety
1736 /// - `world` must have permission to access any of the components registered in `query_state`.
1737 /// - `world` must be the same one used to initialize `query_state`.
1738 unsafe fn init_empty(
1739 world: UnsafeWorldCell<'w>,
1740 query_state: &'s QueryState<D, F>,
1741 last_run: Tick,
1742 this_run: Tick,
1743 ) -> Self {
1744 QueryIterationCursor {
1745 storage_id_iter: [].iter(),
1746 ..Self::init(world, query_state, last_run, this_run)
1747 }
1748 }
1749
1750 /// # Safety
1751 /// - `world` must have permission to access any of the components registered in `query_state`.
1752 /// - `world` must be the same one used to initialize `query_state`.
1753 unsafe fn init(
1754 world: UnsafeWorldCell<'w>,
1755 query_state: &'s QueryState<D, F>,
1756 last_run: Tick,
1757 this_run: Tick,
1758 ) -> Self {
1759 let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
1760 let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);
1761 QueryIterationCursor {
1762 fetch,
1763 filter,
1764 table_entities: &[],
1765 archetype_entities: &[],
1766 storage_id_iter: query_state.matched_storage_ids.iter(),
1767 is_dense: query_state.is_dense,
1768 current_len: 0,
1769 current_row: 0,
1770 }
1771 }
1772
1773 fn reborrow(&mut self) -> QueryIterationCursor<'_, 's, D, F> {
1774 QueryIterationCursor {
1775 is_dense: self.is_dense,
1776 fetch: D::shrink_fetch(self.fetch.clone()),
1777 filter: F::shrink_fetch(self.filter.clone()),
1778 table_entities: self.table_entities,
1779 archetype_entities: self.archetype_entities,
1780 storage_id_iter: self.storage_id_iter.clone(),
1781 current_len: self.current_len,
1782 current_row: self.current_row,
1783 }
1784 }
1785
1786 /// Retrieve item returned from most recent `next` call again.
1787 ///
1788 /// # Safety
1789 /// The result of `next` and any previous calls to `peek_last` with this row must have been
1790 /// dropped to prevent aliasing mutable references.
1791 #[inline]
1792 unsafe fn peek_last(&mut self) -> Option<D::Item<'w>> {
1793 if self.current_row > 0 {
1794 let index = self.current_row - 1;
1795 if self.is_dense {
1796 // SAFETY: This must have been called previously in `next` as `current_row > 0`
1797 let entity = unsafe { self.table_entities.get_unchecked(index) };
1798 // SAFETY:
1799 // - `set_table` must have been called previously either in `next` or before it.
1800 // - `*entity` and `index` are in the current table.
1801 unsafe {
1802 Some(D::fetch(
1803 &mut self.fetch,
1804 *entity,
1805 TableRow::from_usize(index),
1806 ))
1807 }
1808 } else {
1809 // SAFETY: This must have been called previously in `next` as `current_row > 0`
1810 let archetype_entity = unsafe { self.archetype_entities.get_unchecked(index) };
1811 // SAFETY:
1812 // - `set_archetype` must have been called previously either in `next` or before it.
1813 // - `archetype_entity.id()` and `archetype_entity.table_row()` are in the current archetype.
1814 unsafe {
1815 Some(D::fetch(
1816 &mut self.fetch,
1817 archetype_entity.id(),
1818 archetype_entity.table_row(),
1819 ))
1820 }
1821 }
1822 } else {
1823 None
1824 }
1825 }
1826
1827 /// How many values will this cursor return at most?
1828 ///
1829 /// Note that if `F::IS_ARCHETYPAL`, the return value
1830 /// will be **the exact count of remaining values**.
1831 fn max_remaining(&self, tables: &'w Tables, archetypes: &'w Archetypes) -> usize {
1832 let ids = self.storage_id_iter.clone();
1833 let remaining_matched: usize = if self.is_dense {
1834 // SAFETY: The if check ensures that storage_id_iter stores TableIds
1835 unsafe { ids.map(|id| tables[id.table_id].entity_count()).sum() }
1836 } else {
1837 // SAFETY: The if check ensures that storage_id_iter stores ArchetypeIds
1838 unsafe { ids.map(|id| archetypes[id.archetype_id].len()).sum() }
1839 };
1840 remaining_matched + self.current_len - self.current_row
1841 }
1842
1843 // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
1844 // QueryIter, QueryIterationCursor, QuerySortedIter, QueryManyIter, QueryCombinationIter, QueryState::par_fold_init_unchecked_manual
1845 /// # Safety
1846 /// `tables` and `archetypes` must belong to the same world that the [`QueryIterationCursor`]
1847 /// was initialized for.
1848 /// `query_state` must be the same [`QueryState`] that was passed to `init` or `init_empty`.
1849 #[inline(always)]
1850 unsafe fn next(
1851 &mut self,
1852 tables: &'w Tables,
1853 archetypes: &'w Archetypes,
1854 query_state: &'s QueryState<D, F>,
1855 ) -> Option<D::Item<'w>> {
1856 if self.is_dense {
1857 loop {
1858 // we are on the beginning of the query, or finished processing a table, so skip to the next
1859 if self.current_row == self.current_len {
1860 let table_id = self.storage_id_iter.next()?.table_id;
1861 let table = tables.get(table_id).debug_checked_unwrap();
1862 if table.is_empty() {
1863 continue;
1864 }
1865 // SAFETY: `table` is from the world that `fetch/filter` were created for,
1866 // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
1867 unsafe {
1868 D::set_table(&mut self.fetch, &query_state.fetch_state, table);
1869 F::set_table(&mut self.filter, &query_state.filter_state, table);
1870 }
1871 self.table_entities = table.entities();
1872 self.current_len = table.entity_count();
1873 self.current_row = 0;
1874 }
1875
1876 // SAFETY: set_table was called prior.
1877 // `current_row` is a table row in range of the current table, because if it was not, then the above would have been executed.
1878 let entity = unsafe { self.table_entities.get_unchecked(self.current_row) };
1879 let row = TableRow::from_usize(self.current_row);
1880 if !F::filter_fetch(&mut self.filter, *entity, row) {
1881 self.current_row += 1;
1882 continue;
1883 }
1884
1885 // SAFETY:
1886 // - set_table was called prior.
1887 // - `current_row` must be a table row in range of the current table,
1888 // because if it was not, then the above would have been executed.
1889 // - fetch is only called once for each `entity`.
1890 let item = unsafe { D::fetch(&mut self.fetch, *entity, row) };
1891
1892 self.current_row += 1;
1893 return Some(item);
1894 }
1895 } else {
1896 loop {
1897 if self.current_row == self.current_len {
1898 let archetype_id = self.storage_id_iter.next()?.archetype_id;
1899 let archetype = archetypes.get(archetype_id).debug_checked_unwrap();
1900 if archetype.is_empty() {
1901 continue;
1902 }
1903 let table = tables.get(archetype.table_id()).debug_checked_unwrap();
1904 // SAFETY: `archetype` and `tables` are from the world that `fetch/filter` were created for,
1905 // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
1906 unsafe {
1907 D::set_archetype(
1908 &mut self.fetch,
1909 &query_state.fetch_state,
1910 archetype,
1911 table,
1912 );
1913 F::set_archetype(
1914 &mut self.filter,
1915 &query_state.filter_state,
1916 archetype,
1917 table,
1918 );
1919 }
1920 self.archetype_entities = archetype.entities();
1921 self.current_len = archetype.len();
1922 self.current_row = 0;
1923 }
1924
1925 // SAFETY: set_archetype was called prior.
1926 // `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.
1927 let archetype_entity =
1928 unsafe { self.archetype_entities.get_unchecked(self.current_row) };
1929 if !F::filter_fetch(
1930 &mut self.filter,
1931 archetype_entity.id(),
1932 archetype_entity.table_row(),
1933 ) {
1934 self.current_row += 1;
1935 continue;
1936 }
1937
1938 // SAFETY:
1939 // - set_archetype was called prior.
1940 // - `current_row` must be an archetype index row in range of the current archetype,
1941 // because if it was not, then the if above would have been executed.
1942 // - fetch is only called once for each `archetype_entity`.
1943 let item = unsafe {
1944 D::fetch(
1945 &mut self.fetch,
1946 archetype_entity.id(),
1947 archetype_entity.table_row(),
1948 )
1949 };
1950 self.current_row += 1;
1951 return Some(item);
1952 }
1953 }
1954 }
1955}
1956
1957// A wrapper struct that gives its data a neutral ordering.
1958#[derive(Copy, Clone)]
1959struct NeutralOrd<T>(T);
1960
1961impl<T> PartialEq for NeutralOrd<T> {
1962 fn eq(&self, _other: &Self) -> bool {
1963 true
1964 }
1965}
1966
1967impl<T> Eq for NeutralOrd<T> {}
1968
1969#[allow(clippy::non_canonical_partial_ord_impl)]
1970impl<T> PartialOrd for NeutralOrd<T> {
1971 fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
1972 Some(Ordering::Equal)
1973 }
1974}
1975
1976impl<T> Ord for NeutralOrd<T> {
1977 fn cmp(&self, _other: &Self) -> Ordering {
1978 Ordering::Equal
1979 }
1980}
1981
1982#[cfg(test)]
1983mod tests {
1984 #[allow(unused_imports)]
1985 use crate::component::Component;
1986 #[allow(unused_imports)]
1987 use crate::entity::Entity;
1988 #[allow(unused_imports)]
1989 use crate::prelude::World;
1990 #[allow(unused_imports)]
1991 use crate::{self as bevy_ecs};
1992
1993 #[derive(Component, Debug, PartialEq, PartialOrd, Clone, Copy)]
1994 struct A(f32);
1995 #[derive(Component, Debug, Eq, PartialEq, Clone, Copy)]
1996 #[component(storage = "SparseSet")]
1997 struct Sparse(usize);
1998
1999 #[allow(clippy::unnecessary_sort_by)]
2000 #[test]
2001 fn query_sorts() {
2002 let mut world = World::new();
2003
2004 let mut query = world.query::<Entity>();
2005
2006 let sort = query.iter(&world).sort::<Entity>().collect::<Vec<_>>();
2007
2008 let sort_unstable = query
2009 .iter(&world)
2010 .sort_unstable::<Entity>()
2011 .collect::<Vec<_>>();
2012
2013 let sort_by = query
2014 .iter(&world)
2015 .sort_by::<Entity>(Ord::cmp)
2016 .collect::<Vec<_>>();
2017
2018 let sort_unstable_by = query
2019 .iter(&world)
2020 .sort_unstable_by::<Entity>(Ord::cmp)
2021 .collect::<Vec<_>>();
2022
2023 let sort_by_key = query
2024 .iter(&world)
2025 .sort_by_key::<Entity, _>(|&e| e)
2026 .collect::<Vec<_>>();
2027
2028 let sort_unstable_by_key = query
2029 .iter(&world)
2030 .sort_unstable_by_key::<Entity, _>(|&e| e)
2031 .collect::<Vec<_>>();
2032
2033 let sort_by_cached_key = query
2034 .iter(&world)
2035 .sort_by_cached_key::<Entity, _>(|&e| e)
2036 .collect::<Vec<_>>();
2037
2038 let mut sort_v2 = query.iter(&world).collect::<Vec<_>>();
2039 sort_v2.sort();
2040
2041 let mut sort_unstable_v2 = query.iter(&world).collect::<Vec<_>>();
2042 sort_unstable_v2.sort_unstable();
2043
2044 let mut sort_by_v2 = query.iter(&world).collect::<Vec<_>>();
2045 sort_by_v2.sort_by(Ord::cmp);
2046
2047 let mut sort_unstable_by_v2 = query.iter(&world).collect::<Vec<_>>();
2048 sort_unstable_by_v2.sort_unstable_by(Ord::cmp);
2049
2050 let mut sort_by_key_v2 = query.iter(&world).collect::<Vec<_>>();
2051 sort_by_key_v2.sort_by_key(|&e| e);
2052
2053 let mut sort_unstable_by_key_v2 = query.iter(&world).collect::<Vec<_>>();
2054 sort_unstable_by_key_v2.sort_unstable_by_key(|&e| e);
2055
2056 let mut sort_by_cached_key_v2 = query.iter(&world).collect::<Vec<_>>();
2057 sort_by_cached_key_v2.sort_by_cached_key(|&e| e);
2058
2059 assert_eq!(sort, sort_v2);
2060 assert_eq!(sort_unstable, sort_unstable_v2);
2061 assert_eq!(sort_by, sort_by_v2);
2062 assert_eq!(sort_unstable_by, sort_unstable_by_v2);
2063 assert_eq!(sort_by_key, sort_by_key_v2);
2064 assert_eq!(sort_unstable_by_key, sort_unstable_by_key_v2);
2065 assert_eq!(sort_by_cached_key, sort_by_cached_key_v2);
2066 }
2067
2068 #[test]
2069 #[should_panic]
2070 fn query_sort_after_next() {
2071 let mut world = World::new();
2072 world.spawn((A(0.),));
2073 world.spawn((A(1.1),));
2074 world.spawn((A(2.22),));
2075
2076 {
2077 let mut query = world.query::<&A>();
2078 let mut iter = query.iter(&world);
2079 println!(
2080 "archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2081 iter.cursor.archetype_entities.len(),
2082 iter.cursor.table_entities.len(),
2083 iter.cursor.current_len,
2084 iter.cursor.current_row
2085 );
2086 _ = iter.next();
2087 println!(
2088 "archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2089 iter.cursor.archetype_entities.len(),
2090 iter.cursor.table_entities.len(),
2091 iter.cursor.current_len,
2092 iter.cursor.current_row
2093 );
2094 println!("{}", iter.sort::<Entity>().len());
2095 }
2096 }
2097
2098 #[test]
2099 #[should_panic]
2100 fn query_sort_after_next_dense() {
2101 let mut world = World::new();
2102 world.spawn((Sparse(11),));
2103 world.spawn((Sparse(22),));
2104 world.spawn((Sparse(33),));
2105
2106 {
2107 let mut query = world.query::<&Sparse>();
2108 let mut iter = query.iter(&world);
2109 println!(
2110 "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2111 iter.cursor.archetype_entities.len(),
2112 iter.cursor.table_entities.len(),
2113 iter.cursor.current_len,
2114 iter.cursor.current_row
2115 );
2116 _ = iter.next();
2117 println!(
2118 "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2119 iter.cursor.archetype_entities.len(),
2120 iter.cursor.table_entities.len(),
2121 iter.cursor.current_len,
2122 iter.cursor.current_row
2123 );
2124 println!("{}", iter.sort::<Entity>().len());
2125 }
2126 }
2127
2128 #[test]
2129 fn empty_query_sort_after_next_does_not_panic() {
2130 let mut world = World::new();
2131 {
2132 let mut query = world.query::<(&A, &Sparse)>();
2133 let mut iter = query.iter(&world);
2134 println!(
2135 "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2136 iter.cursor.archetype_entities.len(),
2137 iter.cursor.table_entities.len(),
2138 iter.cursor.current_len,
2139 iter.cursor.current_row
2140 );
2141 _ = iter.next();
2142 println!(
2143 "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2144 iter.cursor.archetype_entities.len(),
2145 iter.cursor.table_entities.len(),
2146 iter.cursor.current_len,
2147 iter.cursor.current_row
2148 );
2149 println!("{}", iter.sort::<Entity>().len());
2150 }
2151 }
2152
2153 #[test]
2154 fn query_iter_cursor_state_non_empty_after_next() {
2155 let mut world = World::new();
2156 world.spawn((A(0.), Sparse(11)));
2157 world.spawn((A(1.1), Sparse(22)));
2158 world.spawn((A(2.22), Sparse(33)));
2159 {
2160 let mut query = world.query::<(&A, &Sparse)>();
2161 let mut iter = query.iter(&world);
2162 println!(
2163 "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2164 iter.cursor.archetype_entities.len(),
2165 iter.cursor.table_entities.len(),
2166 iter.cursor.current_len,
2167 iter.cursor.current_row
2168 );
2169 assert!(iter.cursor.table_entities.len() | iter.cursor.archetype_entities.len() == 0);
2170 _ = iter.next();
2171 println!(
2172 "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
2173 iter.cursor.archetype_entities.len(),
2174 iter.cursor.table_entities.len(),
2175 iter.cursor.current_len,
2176 iter.cursor.current_row
2177 );
2178 assert!(
2179 (
2180 iter.cursor.table_entities.len(),
2181 iter.cursor.archetype_entities.len()
2182 ) != (0, 0)
2183 );
2184 }
2185 }
2186}