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