use super::{QueryData, QueryFilter, ReadOnlyQueryData};1use crate::{2archetype::{Archetype, ArchetypeEntity, Archetypes},3bundle::Bundle,4component::Tick,5entity::{ContainsEntity, Entities, Entity, EntityEquivalent, EntitySet, EntitySetIterator},6query::{ArchetypeFilter, DebugCheckedUnwrap, QueryState, StorageId},7storage::{Table, TableRow, Tables},8world::{9unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,10FilteredEntityMut, FilteredEntityRef,11},12};13use alloc::vec::Vec;14use core::{15cmp::Ordering,16fmt::{self, Debug, Formatter},17iter::FusedIterator,18mem::MaybeUninit,19ops::Range,20};21use nonmax::NonMaxU32;2223/// An [`Iterator`] over query results of a [`Query`](crate::system::Query).24///25/// This struct is created by the [`Query::iter`](crate::system::Query::iter) and26/// [`Query::iter_mut`](crate::system::Query::iter_mut) methods.27pub struct QueryIter<'w, 's, D: QueryData, F: QueryFilter> {28world: UnsafeWorldCell<'w>,29tables: &'w Tables,30archetypes: &'w Archetypes,31query_state: &'s QueryState<D, F>,32cursor: QueryIterationCursor<'w, 's, D, F>,33}3435impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {36/// # Safety37/// - `world` must have permission to access any of the components registered in `query_state`.38/// - `world` must be the same one used to initialize `query_state`.39pub(crate) unsafe fn new(40world: UnsafeWorldCell<'w>,41query_state: &'s QueryState<D, F>,42last_run: Tick,43this_run: Tick,44) -> Self {45QueryIter {46world,47query_state,48// SAFETY: We only access table data that has been registered in `query_state`.49tables: unsafe { &world.storages().tables },50archetypes: world.archetypes(),51// SAFETY: The invariants are upheld by the caller.52cursor: unsafe { QueryIterationCursor::init(world, query_state, last_run, this_run) },53}54}5556/// Creates a new separate iterator yielding the same remaining items of the current one.57/// Advancing the new iterator will not advance the original one, which will resume at the58/// point it was left at.59///60/// Differently from [`remaining_mut`](QueryIter::remaining_mut) the new iterator does not61/// borrow from the original one. However it can only be called from an iterator over read only62/// items.63///64/// # Example65///66/// ```67/// # use bevy_ecs::prelude::*;68/// #69/// # #[derive(Component)]70/// # struct ComponentA;71///72/// fn combinations(query: Query<&ComponentA>) {73/// let mut iter = query.iter();74/// while let Some(a) = iter.next() {75/// for b in iter.remaining() {76/// // Check every combination (a, b)77/// }78/// }79/// }80/// ```81pub fn remaining(&self) -> QueryIter<'w, 's, D, F>82where83D: ReadOnlyQueryData,84{85QueryIter {86world: self.world,87tables: self.tables,88archetypes: self.archetypes,89query_state: self.query_state,90cursor: self.cursor.clone(),91}92}9394/// Creates a new separate iterator yielding the same remaining items of the current one.95/// Advancing the new iterator will not advance the original one, which will resume at the96/// point it was left at.97///98/// This method can be called on iterators over mutable items. However the original iterator99/// will be borrowed while the new iterator exists and will thus not be usable in that timespan.100///101/// # Example102///103/// ```104/// # use bevy_ecs::prelude::*;105/// #106/// # #[derive(Component)]107/// # struct ComponentA;108///109/// fn combinations(mut query: Query<&mut ComponentA>) {110/// let mut iter = query.iter_mut();111/// while let Some(a) = iter.next() {112/// for b in iter.remaining_mut() {113/// // Check every combination (a, b)114/// }115/// }116/// }117/// ```118pub fn remaining_mut(&mut self) -> QueryIter<'_, 's, D, F> {119QueryIter {120world: self.world,121tables: self.tables,122archetypes: self.archetypes,123query_state: self.query_state,124cursor: self.cursor.reborrow(),125}126}127128/// Executes the equivalent of [`Iterator::fold`] over a contiguous segment129/// from a storage.130///131/// # Safety132/// - `range` must be in `[0, storage::entity_count)` or None.133#[inline]134pub(super) unsafe fn fold_over_storage_range<B, Func>(135&mut self,136mut accum: B,137func: &mut Func,138storage: StorageId,139range: Option<Range<u32>>,140) -> B141where142Func: FnMut(B, D::Item<'w, 's>) -> B,143{144if self.cursor.is_dense {145// SAFETY: `self.cursor.is_dense` is true, so storage ids are guaranteed to be table ids.146let table_id = unsafe { storage.table_id };147// SAFETY: Matched table IDs are guaranteed to still exist.148let table = unsafe { self.tables.get(table_id).debug_checked_unwrap() };149150let range = range.unwrap_or(0..table.entity_count());151accum =152// SAFETY:153// - The fetched table matches both D and F154// - caller ensures `range` is within `[0, table.entity_count)`155// - The if block ensures that the query iteration is dense156unsafe { self.fold_over_table_range(accum, func, table, range) };157} else {158// SAFETY: `self.cursor.is_dense` is false, so storage ids are guaranteed to be archetype ids.159let archetype_id = unsafe { storage.archetype_id };160// SAFETY: Matched archetype IDs are guaranteed to still exist.161let archetype = unsafe { self.archetypes.get(archetype_id).debug_checked_unwrap() };162// SAFETY: Matched table IDs are guaranteed to still exist.163let table = unsafe { self.tables.get(archetype.table_id()).debug_checked_unwrap() };164165let range = range.unwrap_or(0..archetype.len());166167// When an archetype and its table have equal entity counts, dense iteration can be safely used.168// this leverages cache locality to optimize performance.169if table.entity_count() == archetype.len() {170accum =171// SAFETY:172// - The fetched archetype matches both D and F173// - The provided archetype and its' table have the same length.174// - caller ensures `range` is within `[0, archetype.len)`175// - The if block ensures that the query iteration is not dense.176unsafe { self.fold_over_dense_archetype_range(accum, func, archetype,range) };177} else {178accum =179// SAFETY:180// - The fetched archetype matches both D and F181// - caller ensures `range` is within `[0, archetype.len)`182// - The if block ensures that the query iteration is not dense.183unsafe { self.fold_over_archetype_range(accum, func, archetype,range) };184}185}186accum187}188189/// Executes the equivalent of [`Iterator::fold`] over a contiguous segment190/// from a table.191///192/// # Safety193/// - all `rows` must be in `[0, table.entity_count)`.194/// - `table` must match D and F195/// - The query iteration must be dense (i.e. `self.query_state.is_dense` must be true).196#[inline]197pub(super) unsafe fn fold_over_table_range<B, Func>(198&mut self,199mut accum: B,200func: &mut Func,201table: &'w Table,202rows: Range<u32>,203) -> B204where205Func: FnMut(B, D::Item<'w, 's>) -> B,206{207if table.is_empty() {208return accum;209}210211D::set_table(&mut self.cursor.fetch, &self.query_state.fetch_state, table);212F::set_table(213&mut self.cursor.filter,214&self.query_state.filter_state,215table,216);217218let entities = table.entities();219for row in rows {220// SAFETY: Caller assures `row` in range of the current archetype.221let entity = unsafe { entities.get_unchecked(row as usize) };222// SAFETY: This is from an exclusive range, so it can't be max.223let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(row)) };224225// SAFETY: set_table was called prior.226// Caller assures `row` in range of the current archetype.227let fetched = unsafe {228!F::filter_fetch(229&self.query_state.filter_state,230&mut self.cursor.filter,231*entity,232row,233)234};235if fetched {236continue;237}238239// SAFETY: set_table was called prior.240// Caller assures `row` in range of the current archetype.241let item = D::fetch(242&self.query_state.fetch_state,243&mut self.cursor.fetch,244*entity,245row,246);247248accum = func(accum, item);249}250accum251}252253/// Executes the equivalent of [`Iterator::fold`] over a contiguous segment254/// from an archetype.255///256/// # Safety257/// - all `indices` must be in `[0, archetype.len())`.258/// - `archetype` must match D and F259/// - The query iteration must not be dense (i.e. `self.query_state.is_dense` must be false).260#[inline]261pub(super) unsafe fn fold_over_archetype_range<B, Func>(262&mut self,263mut accum: B,264func: &mut Func,265archetype: &'w Archetype,266indices: Range<u32>,267) -> B268where269Func: FnMut(B, D::Item<'w, 's>) -> B,270{271if archetype.is_empty() {272return accum;273}274let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();275D::set_archetype(276&mut self.cursor.fetch,277&self.query_state.fetch_state,278archetype,279table,280);281F::set_archetype(282&mut self.cursor.filter,283&self.query_state.filter_state,284archetype,285table,286);287288let entities = archetype.entities();289for index in indices {290// SAFETY: Caller assures `index` in range of the current archetype.291let archetype_entity = unsafe { entities.get_unchecked(index as usize) };292293// SAFETY: set_archetype was called prior.294// Caller assures `index` in range of the current archetype.295let fetched = unsafe {296!F::filter_fetch(297&self.query_state.filter_state,298&mut self.cursor.filter,299archetype_entity.id(),300archetype_entity.table_row(),301)302};303if fetched {304continue;305}306307// SAFETY: set_archetype was called prior, `index` is an archetype index in range of the current archetype308// Caller assures `index` in range of the current archetype.309let item = unsafe {310D::fetch(311&self.query_state.fetch_state,312&mut self.cursor.fetch,313archetype_entity.id(),314archetype_entity.table_row(),315)316};317318accum = func(accum, item);319}320accum321}322323/// Executes the equivalent of [`Iterator::fold`] over a contiguous segment324/// from an archetype which has the same entity count as its table.325///326/// # Safety327/// - all `indices` must be in `[0, archetype.len())`.328/// - `archetype` must match D and F329/// - `archetype` must have the same length as its table.330/// - The query iteration must not be dense (i.e. `self.query_state.is_dense` must be false).331#[inline]332pub(super) unsafe fn fold_over_dense_archetype_range<B, Func>(333&mut self,334mut accum: B,335func: &mut Func,336archetype: &'w Archetype,337rows: Range<u32>,338) -> B339where340Func: FnMut(B, D::Item<'w, 's>) -> B,341{342if archetype.is_empty() {343return accum;344}345let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();346debug_assert!(347archetype.len() == table.entity_count(),348"archetype and its table must have the same length. "349);350351D::set_archetype(352&mut self.cursor.fetch,353&self.query_state.fetch_state,354archetype,355table,356);357F::set_archetype(358&mut self.cursor.filter,359&self.query_state.filter_state,360archetype,361table,362);363let entities = table.entities();364for row in rows {365// SAFETY: Caller assures `row` in range of the current archetype.366let entity = unsafe { *entities.get_unchecked(row as usize) };367// SAFETY: This is from an exclusive range, so it can't be max.368let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(row)) };369370// SAFETY: set_table was called prior.371// Caller assures `row` in range of the current archetype.372let filter_matched = unsafe {373F::filter_fetch(374&self.query_state.filter_state,375&mut self.cursor.filter,376entity,377row,378)379};380if !filter_matched {381continue;382}383384// SAFETY: set_table was called prior.385// Caller assures `row` in range of the current archetype.386let item = D::fetch(387&self.query_state.fetch_state,388&mut self.cursor.fetch,389entity,390row,391);392393accum = func(accum, item);394}395accum396}397398/// Sorts all query items into a new iterator, using the query lens as a key.399///400/// This sort is stable (i.e., does not reorder equal elements).401///402/// This uses [`slice::sort`] internally.403///404/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).405/// This includes the allowed parameter type changes listed under [allowed transmutes].406/// However, the lens uses the filter of the original query when present.407///408/// The sort is not cached across system runs.409///410/// [allowed transmutes]: crate::system::Query#allowed-transmutes411///412/// # Panics413///414/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.415///416/// # Examples417/// ```rust418/// # use bevy_ecs::prelude::*;419/// # use std::{ops::{Deref, DerefMut}, iter::Sum};420/// #421/// # #[derive(Component)]422/// # struct PartMarker;423/// #424/// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]425/// # struct PartIndex(usize);426/// #427/// # #[derive(Component, Clone, Copy)]428/// # struct PartValue(f32);429/// #430/// # impl Deref for PartValue {431/// # type Target = f32;432/// #433/// # fn deref(&self) -> &Self::Target {434/// # &self.0435/// # }436/// # }437/// #438/// # #[derive(Component)]439/// # struct ParentValue(f32);440/// #441/// # impl Deref for ParentValue {442/// # type Target = f32;443/// #444/// # fn deref(&self) -> &Self::Target {445/// # &self.0446/// # }447/// # }448/// #449/// # impl DerefMut for ParentValue {450/// # fn deref_mut(&mut self) -> &mut Self::Target {451/// # &mut self.0452/// # }453/// # }454/// #455/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]456/// # struct Length(usize);457/// #458/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]459/// # struct Width(usize);460/// #461/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]462/// # struct Height(usize);463/// #464/// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]465/// # struct ParentEntity(Entity);466/// #467/// # #[derive(Component, Clone, Copy)]468/// # struct ChildPartCount(usize);469/// #470/// # impl Deref for ChildPartCount {471/// # type Target = usize;472/// #473/// # fn deref(&self) -> &Self::Target {474/// # &self.0475/// # }476/// # }477/// # let mut world = World::new();478/// // We can ensure that a query always returns in the same order.479/// fn system_1(query: Query<(Entity, &PartIndex)>) {480/// let parts: Vec<(Entity, &PartIndex)> = query.iter().sort::<&PartIndex>().collect();481/// }482///483/// // We can freely rearrange query components in the key.484/// fn system_2(query: Query<(&Length, &Width, &Height), With<PartMarker>>) {485/// for (length, width, height) in query.iter().sort::<(&Height, &Length, &Width)>() {486/// println!("height: {height:?}, width: {width:?}, length: {length:?}")487/// }488/// }489///490/// // We can sort by Entity without including it in the original Query.491/// // Here, we match iteration orders between query iterators.492/// fn system_3(493/// part_query: Query<(&PartValue, &ParentEntity)>,494/// mut parent_query: Query<(&ChildPartCount, &mut ParentValue)>,495/// ) {496/// let part_values = &mut part_query497/// .into_iter()498/// .sort::<&ParentEntity>()499/// .map(|(&value, parent_entity)| *value);500///501/// for (&child_count, mut parent_value) in parent_query.iter_mut().sort::<Entity>() {502/// **parent_value = part_values.take(*child_count).sum();503/// }504/// }505/// #506/// # let mut schedule = Schedule::default();507/// # schedule.add_systems((system_1, system_2, system_3));508/// # schedule.run(&mut world);509/// ```510pub fn sort<L: ReadOnlyQueryData + 'w>(511self,512) -> QuerySortedIter<513'w,514's,515D,516F,517impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,518>519where520for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,521{522self.sort_impl::<L>(|keyed_query| keyed_query.sort())523}524525/// Sorts all query items into a new iterator, using the query lens as a key.526///527/// This sort is unstable (i.e., may reorder equal elements).528///529/// This uses [`slice::sort_unstable`] internally.530///531/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).532/// This includes the allowed parameter type changes listed under [allowed transmutes]..533/// However, the lens uses the filter of the original query when present.534///535/// The sort is not cached across system runs.536///537/// [allowed transmutes]: crate::system::Query#allowed-transmutes538///539/// # Panics540///541/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.542///543/// # Example544/// ```545/// # use bevy_ecs::prelude::*;546/// #547/// # let mut world = World::new();548/// #549/// # #[derive(Component)]550/// # struct PartMarker;551/// #552/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]553/// enum Flying {554/// Enabled,555/// Disabled556/// };557///558/// // We perform an unstable sort by a Component with few values.559/// fn system_1(query: Query<&Flying, With<PartMarker>>) {560/// let part_values: Vec<&Flying> = query.iter().sort_unstable::<&Flying>().collect();561/// }562/// #563/// # let mut schedule = Schedule::default();564/// # schedule.add_systems((system_1));565/// # schedule.run(&mut world);566/// ```567pub fn sort_unstable<L: ReadOnlyQueryData + 'w>(568self,569) -> QuerySortedIter<570'w,571's,572D,573F,574impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,575>576where577for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,578{579self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())580}581582/// Sorts all query items into a new iterator with a comparator function over the query lens.583///584/// This sort is stable (i.e., does not reorder equal elements).585///586/// This uses [`slice::sort_by`] internally.587///588/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).589/// This includes the allowed parameter type changes listed under [allowed transmutes].590/// However, the lens uses the filter of the original query when present.591///592/// The sort is not cached across system runs.593///594/// [allowed transmutes]: crate::system::Query#allowed-transmutes595///596/// # Panics597///598/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.599///600/// # Example601/// ```602/// # use bevy_ecs::prelude::*;603/// # use std::ops::Deref;604/// #605/// # impl Deref for PartValue {606/// # type Target = f32;607/// #608/// # fn deref(&self) -> &Self::Target {609/// # &self.0610/// # }611/// # }612/// #613/// # let mut world = World::new();614/// #615/// #[derive(Component)]616/// struct PartValue(f32);617///618/// // We can use a cmp function on components do not implement Ord.619/// fn system_1(query: Query<&PartValue>) {620/// // Sort part values according to `f32::total_comp`.621/// let part_values: Vec<&PartValue> = query622/// .iter()623/// .sort_by::<&PartValue>(|value_1, value_2| value_1.total_cmp(*value_2))624/// .collect();625/// }626/// #627/// # let mut schedule = Schedule::default();628/// # schedule.add_systems((system_1));629/// # schedule.run(&mut world);630/// ```631pub fn sort_by<L: ReadOnlyQueryData + 'w>(632self,633mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,634) -> QuerySortedIter<635'w,636's,637D,638F,639impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,640> {641self.sort_impl::<L>(move |keyed_query| {642keyed_query.sort_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));643})644}645646/// Sorts all query items into a new iterator with a comparator function over the query lens.647///648/// This sort is unstable (i.e., may reorder equal elements).649///650/// This uses [`slice::sort_unstable_by`] internally.651///652/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).653/// This includes the allowed parameter type changes listed under [allowed transmutes].654/// However, the lens uses the filter of the original query when present.655///656/// The sort is not cached across system runs.657///658/// [allowed transmutes]: crate::system::Query#allowed-transmutes659///660/// # Panics661///662/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.663pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(664self,665mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,666) -> QuerySortedIter<667'w,668's,669D,670F,671impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,672> {673self.sort_impl::<L>(move |keyed_query| {674keyed_query.sort_unstable_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));675})676}677678/// Sorts all query items into a new iterator with a key extraction function over the query lens.679///680/// This sort is stable (i.e., does not reorder equal elements).681///682/// This uses [`slice::sort_by_key`] internally.683///684/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).685/// This includes the allowed parameter type changes listed under [allowed transmutes].686/// However, the lens uses the filter of the original query when present.687///688/// The sort is not cached across system runs.689///690/// [allowed transmutes]: crate::system::Query#allowed-transmutes691///692/// # Panics693///694/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.695///696/// # Example697/// ```698/// # use bevy_ecs::prelude::*;699/// # use std::ops::Deref;700/// #701/// # #[derive(Component)]702/// # struct PartMarker;703/// #704/// # impl Deref for PartValue {705/// # type Target = f32;706/// #707/// # fn deref(&self) -> &Self::Target {708/// # &self.0709/// # }710/// # }711/// #712/// # let mut world = World::new();713/// #714/// #[derive(Component)]715/// struct AvailableMarker;716///717/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]718/// enum Rarity {719/// Common,720/// Rare,721/// Epic,722/// Legendary723/// };724///725/// #[derive(Component)]726/// struct PartValue(f32);727///728/// // We can sort with the internals of components that do not implement Ord.729/// fn system_1(query: Query<(Entity, &PartValue)>) {730/// // Sort by the sines of the part values.731/// let parts: Vec<(Entity, &PartValue)> = query732/// .iter()733/// .sort_by_key::<&PartValue, _>(|value| value.sin() as usize)734/// .collect();735/// }736///737/// // We can define our own custom comparison functions over an EntityRef.738/// fn system_2(query: Query<EntityRef, With<PartMarker>>) {739/// // Sort by whether parts are available and their rarity.740/// // We want the available legendaries to come first, so we reverse the iterator.741/// let parts: Vec<EntityRef> = query.iter()742/// .sort_by_key::<EntityRef, _>(|entity_ref| {743/// (744/// entity_ref.contains::<AvailableMarker>(),745/// entity_ref.get::<Rarity>().copied()746/// )747/// })748/// .rev()749/// .collect();750/// }751/// # let mut schedule = Schedule::default();752/// # schedule.add_systems((system_1, system_2));753/// # schedule.run(&mut world);754/// ```755pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(756self,757mut f: impl FnMut(&L::Item<'_, '_>) -> K,758) -> QuerySortedIter<759'w,760's,761D,762F,763impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,764>765where766K: Ord,767{768self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_key(|(lens, _)| f(lens)))769}770771/// Sorts all query items into a new iterator with a key extraction function over the query lens.772///773/// This sort is unstable (i.e., may reorder equal elements).774///775/// This uses [`slice::sort_unstable_by_key`] internally.776///777/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).778/// This includes the allowed parameter type changes listed under [allowed transmutes].779/// However, the lens uses the filter of the original query when present.780///781/// The sort is not cached across system runs.782///783/// [allowed transmutes]: crate::system::Query#allowed-transmutes784///785/// # Panics786///787/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.788pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(789self,790mut f: impl FnMut(&L::Item<'_, '_>) -> K,791) -> QuerySortedIter<792'w,793's,794D,795F,796impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,797>798where799K: Ord,800{801self.sort_impl::<L>(move |keyed_query| {802keyed_query.sort_unstable_by_key(|(lens, _)| f(lens));803})804}805806/// Sort all query items into a new iterator with a key extraction function over the query lens.807///808/// This sort is stable (i.e., does not reorder equal elements).809///810/// This uses [`slice::sort_by_cached_key`] internally.811///812/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).813/// This includes the allowed parameter type changes listed under [allowed transmutes].814/// However, the lens uses the filter of the original query when present.815///816/// The sort is not cached across system runs.817///818/// [allowed transmutes]: crate::system::Query#allowed-transmutes819///820/// # Panics821///822/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.823pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(824self,825mut f: impl FnMut(&L::Item<'_, '_>) -> K,826) -> QuerySortedIter<827'w,828's,829D,830F,831impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,832>833where834K: Ord,835{836self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_cached_key(|(lens, _)| f(lens)))837}838839/// Shared implementation for the various `sort` methods.840/// This uses the lens to collect the items for sorting, but delegates the actual sorting to the provided closure.841///842/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).843/// This includes the allowed parameter type changes listed under [allowed transmutes].844/// However, the lens uses the filter of the original query when present.845///846/// The sort is not cached across system runs.847///848/// [allowed transmutes]: crate::system::Query#allowed-transmutes849///850/// # Panics851///852/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.853fn sort_impl<L: ReadOnlyQueryData + 'w>(854self,855f: impl FnOnce(&mut Vec<(L::Item<'_, '_>, NeutralOrd<Entity>)>),856) -> QuerySortedIter<857'w,858's,859D,860F,861impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,862> {863// On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`864// will be set to a non-zero value. The correctness of this method relies on this.865// I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a866// non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.867if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {868panic!("it is not valid to call sort() after next()")869}870871let world = self.world;872873let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);874875// SAFETY:876// `self.world` has permission to access the required components.877// The original query iter has not been iterated on, so no items are aliased from it.878// `QueryIter::new` ensures `world` is the same one used to initialize `query_state`.879let query_lens = unsafe { query_lens_state.query_unchecked_manual(world) }.into_iter();880let mut keyed_query: Vec<_> = query_lens881.map(|(key, entity)| (key, NeutralOrd(entity)))882.collect();883f(&mut keyed_query);884let entity_iter = keyed_query885.into_iter()886.map(|(.., entity)| entity.0)887.collect::<Vec<_>>()888.into_iter();889// SAFETY:890// `self.world` has permission to access the required components.891// Each lens query item is dropped before the respective actual query item is accessed.892unsafe {893QuerySortedIter::new(894world,895self.query_state,896entity_iter,897world.last_change_tick(),898world.change_tick(),899)900}901}902}903904impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F> {905type Item = D::Item<'w, 's>;906907#[inline(always)]908fn next(&mut self) -> Option<Self::Item> {909// SAFETY:910// `tables` and `archetypes` belong to the same world that the cursor was initialized for.911// `query_state` is the state that was passed to `QueryIterationCursor::init`.912unsafe {913self.cursor914.next(self.tables, self.archetypes, self.query_state)915}916}917918fn size_hint(&self) -> (usize, Option<usize>) {919let max_size = self.cursor.max_remaining(self.tables, self.archetypes);920let archetype_query = F::IS_ARCHETYPAL;921let min_size = if archetype_query { max_size } else { 0 };922(min_size as usize, Some(max_size as usize))923}924925#[inline]926fn fold<B, Func>(mut self, init: B, mut func: Func) -> B927where928Func: FnMut(B, Self::Item) -> B,929{930let mut accum = init;931// Empty any remaining uniterated values from the current table/archetype932while self.cursor.current_row != self.cursor.current_len {933let Some(item) = self.next() else { break };934accum = func(accum, item);935}936937for id in self.cursor.storage_id_iter.clone().copied() {938// SAFETY:939// - The range(None) is equivalent to [0, storage.entity_count)940accum = unsafe { self.fold_over_storage_range(accum, &mut func, id, None) };941}942accum943}944}945946// This is correct as [`QueryIter`] always returns `None` once exhausted.947impl<'w, 's, D: QueryData, F: QueryFilter> FusedIterator for QueryIter<'w, 's, D, F> {}948949// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.950unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator for QueryIter<'w, 's, Entity, F> {}951952// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.953unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator for QueryIter<'w, 's, EntityRef<'_>, F> {}954955// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.956unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator for QueryIter<'w, 's, EntityMut<'_>, F> {}957958// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.959unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator960for QueryIter<'w, 's, FilteredEntityRef<'_, '_>, F>961{962}963964// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.965unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator966for QueryIter<'w, 's, FilteredEntityMut<'_, '_>, F>967{968}969970// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.971unsafe impl<'w, 's, F: QueryFilter, B: Bundle> EntitySetIterator972for QueryIter<'w, 's, EntityRefExcept<'_, '_, B>, F>973{974}975976// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.977unsafe impl<'w, 's, F: QueryFilter, B: Bundle> EntitySetIterator978for QueryIter<'w, 's, EntityMutExcept<'_, '_, B>, F>979{980}981982impl<'w, 's, D: QueryData, F: QueryFilter> Debug for QueryIter<'w, 's, D, F> {983fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {984f.debug_struct("QueryIter").finish()985}986}987988impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Clone for QueryIter<'w, 's, D, F> {989fn clone(&self) -> Self {990self.remaining()991}992}993994/// An [`Iterator`] over sorted query results of a [`Query`](crate::system::Query).995///996/// This struct is created by the [`QueryIter::sort`], [`QueryIter::sort_unstable`],997/// [`QueryIter::sort_by`], [`QueryIter::sort_unstable_by`], [`QueryIter::sort_by_key`],998/// [`QueryIter::sort_unstable_by_key`], and [`QueryIter::sort_by_cached_key`] methods.999pub struct QuerySortedIter<'w, 's, D: QueryData, F: QueryFilter, I>1000where1001I: Iterator<Item = Entity>,1002{1003entity_iter: I,1004entities: &'w Entities,1005tables: &'w Tables,1006archetypes: &'w Archetypes,1007fetch: D::Fetch<'w>,1008query_state: &'s QueryState<D, F>,1009}10101011impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> QuerySortedIter<'w, 's, D, F, I>1012where1013I: Iterator<Item = Entity>,1014{1015/// # Safety1016/// - `world` must have permission to access any of the components registered in `query_state`.1017/// - `world` must be the same one used to initialize `query_state`.1018/// - `entity_list` must only contain unique entities or be empty.1019pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(1020world: UnsafeWorldCell<'w>,1021query_state: &'s QueryState<D, F>,1022entity_list: EntityList,1023last_run: Tick,1024this_run: Tick,1025) -> QuerySortedIter<'w, 's, D, F, I> {1026let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);1027QuerySortedIter {1028query_state,1029entities: world.entities(),1030archetypes: world.archetypes(),1031// SAFETY: We only access table data that has been registered in `query_state`.1032// This means `world` has permission to access the data we use.1033tables: &world.storages().tables,1034fetch,1035entity_iter: entity_list.into_iter(),1036}1037}10381039/// # Safety1040/// `entity` must stem from `self.entity_iter`, and not have been passed before.1041#[inline(always)]1042unsafe fn fetch_next(&mut self, entity: Entity) -> D::Item<'w, 's> {1043let (location, archetype, table);1044// SAFETY:1045// `tables` and `archetypes` belong to the same world that the [`QueryIter`]1046// was initialized for.1047unsafe {1048location = self.entities.get(entity).debug_checked_unwrap();1049archetype = self1050.archetypes1051.get(location.archetype_id)1052.debug_checked_unwrap();1053table = self.tables.get(location.table_id).debug_checked_unwrap();1054}10551056// SAFETY: `archetype` is from the world that `fetch` was created for,1057// `fetch_state` is the state that `fetch` was initialized with1058unsafe {1059D::set_archetype(1060&mut self.fetch,1061&self.query_state.fetch_state,1062archetype,1063table,1064);1065}10661067// The entity list has already been filtered by the query lens, so we forego filtering here.1068// SAFETY:1069// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype1070// - fetch is only called once for each entity.1071unsafe {1072D::fetch(1073&self.query_state.fetch_state,1074&mut self.fetch,1075entity,1076location.table_row,1077)1078}1079}1080}10811082impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> Iterator1083for QuerySortedIter<'w, 's, D, F, I>1084where1085I: Iterator<Item = Entity>,1086{1087type Item = D::Item<'w, 's>;10881089#[inline(always)]1090fn next(&mut self) -> Option<Self::Item> {1091let entity = self.entity_iter.next()?;1092// SAFETY: `entity` is passed from `entity_iter` the first time.1093unsafe { self.fetch_next(entity).into() }1094}10951096fn size_hint(&self) -> (usize, Option<usize>) {1097self.entity_iter.size_hint()1098}1099}11001101impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> DoubleEndedIterator1102for QuerySortedIter<'w, 's, D, F, I>1103where1104I: DoubleEndedIterator<Item = Entity>,1105{1106#[inline(always)]1107fn next_back(&mut self) -> Option<Self::Item> {1108let entity = self.entity_iter.next_back()?;1109// SAFETY: `entity` is passed from `entity_iter` the first time.1110unsafe { self.fetch_next(entity).into() }1111}1112}11131114impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> ExactSizeIterator1115for QuerySortedIter<'w, 's, D, F, I>1116where1117I: ExactSizeIterator<Item = Entity>,1118{1119}11201121// This is correct as [`QuerySortedIter`] returns `None` once exhausted if `entity_iter` does.1122impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> FusedIterator1123for QuerySortedIter<'w, 's, D, F, I>1124where1125I: FusedIterator<Item = Entity>,1126{1127}11281129// SAFETY:1130// `I` stems from a collected and sorted `EntitySetIterator` ([`QueryIter`]).1131// Fetching unique entities maintains uniqueness.1132unsafe impl<'w, 's, F: QueryFilter, I: Iterator<Item = Entity>> EntitySetIterator1133for QuerySortedIter<'w, 's, Entity, F, I>1134{1135}11361137impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> Debug1138for QuerySortedIter<'w, 's, D, F, I>1139{1140fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {1141f.debug_struct("QuerySortedIter").finish()1142}1143}11441145/// An [`Iterator`] over the query items generated from an iterator of [`Entity`]s.1146///1147/// Items are returned in the order of the provided iterator.1148/// Entities that don't match the query are skipped.1149///1150/// 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.1151pub struct QueryManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>1152{1153world: UnsafeWorldCell<'w>,1154entity_iter: I,1155entities: &'w Entities,1156tables: &'w Tables,1157archetypes: &'w Archetypes,1158fetch: D::Fetch<'w>,1159filter: F::Fetch<'w>,1160query_state: &'s QueryState<D, F>,1161}11621163impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>1164QueryManyIter<'w, 's, D, F, I>1165{1166/// # Safety1167/// - `world` must have permission to access any of the components registered in `query_state`.1168/// - `world` must be the same one used to initialize `query_state`.1169pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(1170world: UnsafeWorldCell<'w>,1171query_state: &'s QueryState<D, F>,1172entity_list: EntityList,1173last_run: Tick,1174this_run: Tick,1175) -> QueryManyIter<'w, 's, D, F, I> {1176let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);1177let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);1178QueryManyIter {1179world,1180query_state,1181entities: world.entities(),1182archetypes: world.archetypes(),1183// SAFETY: We only access table data that has been registered in `query_state`.1184// This means `world` has permission to access the data we use.1185tables: &world.storages().tables,1186fetch,1187filter,1188entity_iter: entity_list.into_iter(),1189}1190}11911192/// # Safety1193/// All arguments must stem from the same valid `QueryManyIter`.1194///1195/// The lifetime here is not restrictive enough for Fetch with &mut access,1196/// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple1197/// references to the same component, leading to unique reference aliasing.1198///1199/// It is always safe for shared access.1200#[inline(always)]1201unsafe fn fetch_next_aliased_unchecked(1202entity_iter: impl Iterator<Item: EntityEquivalent>,1203entities: &'w Entities,1204tables: &'w Tables,1205archetypes: &'w Archetypes,1206fetch: &mut D::Fetch<'w>,1207filter: &mut F::Fetch<'w>,1208query_state: &'s QueryState<D, F>,1209) -> Option<D::Item<'w, 's>> {1210for entity_borrow in entity_iter {1211let entity = entity_borrow.entity();1212let Some(location) = entities.get(entity) else {1213continue;1214};12151216if !query_state1217.matched_archetypes1218.contains(location.archetype_id.index())1219{1220continue;1221}12221223let archetype = archetypes.get(location.archetype_id).debug_checked_unwrap();1224let table = tables.get(location.table_id).debug_checked_unwrap();12251226// SAFETY: `archetype` is from the world that `fetch/filter` were created for,1227// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with1228unsafe {1229D::set_archetype(fetch, &query_state.fetch_state, archetype, table);1230}1231// SAFETY: `table` is from the world that `fetch/filter` were created for,1232// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with1233unsafe {1234F::set_archetype(filter, &query_state.filter_state, archetype, table);1235}12361237// SAFETY: set_archetype was called prior.1238// `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`d1239if unsafe {1240F::filter_fetch(1241&query_state.filter_state,1242filter,1243entity,1244location.table_row,1245)1246} {1247// SAFETY:1248// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype1249// - fetch is only called once for each entity.1250return Some(unsafe {1251D::fetch(&query_state.fetch_state, fetch, entity, location.table_row)1252});1253}1254}1255None1256}12571258/// Get next result from the query1259#[inline(always)]1260pub fn fetch_next(&mut self) -> Option<D::Item<'_, 's>> {1261// SAFETY:1262// All arguments stem from self.1263// We are limiting the returned reference to self,1264// making sure this method cannot be called multiple times without getting rid1265// of any previously returned unique references first, thus preventing aliasing.1266unsafe {1267Self::fetch_next_aliased_unchecked(1268&mut self.entity_iter,1269self.entities,1270self.tables,1271self.archetypes,1272&mut self.fetch,1273&mut self.filter,1274self.query_state,1275)1276.map(D::shrink)1277}1278}12791280/// Sorts all query items into a new iterator, using the query lens as a key.1281///1282/// This sort is stable (i.e., does not reorder equal elements).1283///1284/// This uses [`slice::sort`] internally.1285///1286/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1287/// This includes the allowed parameter type changes listed under [allowed transmutes].1288/// However, the lens uses the filter of the original query when present.1289///1290/// The sort is not cached across system runs.1291///1292/// [allowed transmutes]: crate::system::Query#allowed-transmutes1293///1294/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1295/// called on [`QueryManyIter`] before.1296///1297/// # Examples1298/// ```rust1299/// # use bevy_ecs::prelude::*;1300/// # use std::{ops::{Deref, DerefMut}, iter::Sum};1301/// #1302/// # #[derive(Component)]1303/// # struct PartMarker;1304/// #1305/// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]1306/// # struct PartIndex(usize);1307/// #1308/// # #[derive(Component, Clone, Copy)]1309/// # struct PartValue(usize);1310/// #1311/// # impl Deref for PartValue {1312/// # type Target = usize;1313/// #1314/// # fn deref(&self) -> &Self::Target {1315/// # &self.01316/// # }1317/// # }1318/// #1319/// # impl DerefMut for PartValue {1320/// # fn deref_mut(&mut self) -> &mut Self::Target {1321/// # &mut self.01322/// # }1323/// # }1324/// #1325/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]1326/// # struct Length(usize);1327/// #1328/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]1329/// # struct Width(usize);1330/// #1331/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]1332/// # struct Height(usize);1333/// #1334/// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]1335/// # struct ParentEntity(Entity);1336/// #1337/// # let mut world = World::new();1338/// // We can ensure that a query always returns in the same order.1339/// fn system_1(query: Query<(Entity, &PartIndex)>) {1340/// # let entity_list: Vec<Entity> = Vec::new();1341/// let parts: Vec<(Entity, &PartIndex)> = query.iter_many(entity_list).sort::<&PartIndex>().collect();1342/// }1343///1344/// // We can freely rearrange query components in the key.1345/// fn system_2(query: Query<(&Length, &Width, &Height), With<PartMarker>>) {1346/// # let entity_list: Vec<Entity> = Vec::new();1347/// for (length, width, height) in query.iter_many(entity_list).sort::<(&Height, &Length, &Width)>() {1348/// println!("height: {height:?}, width: {width:?}, length: {length:?}")1349/// }1350/// }1351///1352/// // You can use `fetch_next_back` to obtain mutable references in reverse order.1353/// fn system_3(1354/// mut query: Query<&mut PartValue>,1355/// ) {1356/// # let entity_list: Vec<Entity> = Vec::new();1357/// // We need to collect the internal iterator before iterating mutably1358/// let mut parent_query_iter = query.iter_many_mut(entity_list)1359/// .sort::<Entity>();1360///1361/// let mut scratch_value = 0;1362/// while let Some(mut part_value) = parent_query_iter.fetch_next_back()1363/// {1364/// // some order-dependent operation, here bitwise XOR1365/// **part_value ^= scratch_value;1366/// scratch_value = **part_value;1367/// }1368/// }1369/// #1370/// # let mut schedule = Schedule::default();1371/// # schedule.add_systems((system_1, system_2, system_3));1372/// # schedule.run(&mut world);1373/// ```1374pub fn sort<L: ReadOnlyQueryData + 'w>(1375self,1376) -> QuerySortedManyIter<1377'w,1378's,1379D,1380F,1381impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1382>1383where1384for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,1385{1386self.sort_impl::<L>(|keyed_query| keyed_query.sort())1387}13881389/// Sorts all query items into a new iterator, using the query lens as a key.1390///1391/// This sort is unstable (i.e., may reorder equal elements).1392///1393/// This uses [`slice::sort_unstable`] internally.1394///1395/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1396/// This includes the allowed parameter type changes listed under [allowed transmutes]..1397/// However, the lens uses the filter of the original query when present.1398///1399/// The sort is not cached across system runs.1400///1401/// [allowed transmutes]: crate::system::Query#allowed-transmutes1402///1403/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1404/// called on [`QueryManyIter`] before.1405///1406/// # Example1407/// ```1408/// # use bevy_ecs::prelude::*;1409/// #1410/// # let mut world = World::new();1411/// #1412/// # #[derive(Component)]1413/// # struct PartMarker;1414/// #1415/// # let entity_list: Vec<Entity> = Vec::new();1416/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]1417/// enum Flying {1418/// Enabled,1419/// Disabled1420/// };1421///1422/// // We perform an unstable sort by a Component with few values.1423/// fn system_1(query: Query<&Flying, With<PartMarker>>) {1424/// # let entity_list: Vec<Entity> = Vec::new();1425/// let part_values: Vec<&Flying> = query.iter_many(entity_list).sort_unstable::<&Flying>().collect();1426/// }1427/// #1428/// # let mut schedule = Schedule::default();1429/// # schedule.add_systems((system_1));1430/// # schedule.run(&mut world);1431/// ```1432pub fn sort_unstable<L: ReadOnlyQueryData + 'w>(1433self,1434) -> QuerySortedManyIter<1435'w,1436's,1437D,1438F,1439impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1440>1441where1442for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,1443{1444self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())1445}14461447/// Sorts all query items into a new iterator with a comparator function over the query lens.1448///1449/// This sort is stable (i.e., does not reorder equal elements).1450///1451/// This uses [`slice::sort_by`] internally.1452///1453/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1454/// This includes the allowed parameter type changes listed under [allowed transmutes].1455/// However, the lens uses the filter of the original query when present.1456///1457/// The sort is not cached across system runs.1458///1459/// [allowed transmutes]: crate::system::Query#allowed-transmutes1460///1461/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1462/// called on [`QueryManyIter`] before.1463///1464/// # Example1465/// ```1466/// # use bevy_ecs::prelude::*;1467/// # use std::ops::Deref;1468/// #1469/// # impl Deref for PartValue {1470/// # type Target = f32;1471/// #1472/// # fn deref(&self) -> &Self::Target {1473/// # &self.01474/// # }1475/// # }1476/// #1477/// # let mut world = World::new();1478/// # let entity_list: Vec<Entity> = Vec::new();1479/// #1480/// #[derive(Component)]1481/// struct PartValue(f32);1482///1483/// // We can use a cmp function on components do not implement Ord.1484/// fn system_1(query: Query<&PartValue>) {1485/// # let entity_list: Vec<Entity> = Vec::new();1486/// // Sort part values according to `f32::total_comp`.1487/// let part_values: Vec<&PartValue> = query1488/// .iter_many(entity_list)1489/// .sort_by::<&PartValue>(|value_1, value_2| value_1.total_cmp(*value_2))1490/// .collect();1491/// }1492/// #1493/// # let mut schedule = Schedule::default();1494/// # schedule.add_systems((system_1));1495/// # schedule.run(&mut world);1496/// ```1497pub fn sort_by<L: ReadOnlyQueryData + 'w>(1498self,1499mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,1500) -> QuerySortedManyIter<1501'w,1502's,1503D,1504F,1505impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1506> {1507self.sort_impl::<L>(move |keyed_query| {1508keyed_query.sort_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));1509})1510}15111512/// Sorts all query items into a new iterator with a comparator function over the query lens.1513///1514/// This sort is unstable (i.e., may reorder equal elements).1515///1516/// This uses [`slice::sort_unstable_by`] internally.1517///1518/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1519/// This includes the allowed parameter type changes listed under [allowed transmutes].1520/// However, the lens uses the filter of the original query when present.1521///1522/// The sort is not cached across system runs.1523///1524/// [allowed transmutes]: crate::system::Query#allowed-transmutes1525///1526/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1527/// called on [`QueryManyIter`] before.1528pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(1529self,1530mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,1531) -> QuerySortedManyIter<1532'w,1533's,1534D,1535F,1536impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1537> {1538self.sort_impl::<L>(move |keyed_query| {1539keyed_query.sort_unstable_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));1540})1541}15421543/// Sorts all query items into a new iterator with a key extraction function over the query lens.1544///1545/// This sort is stable (i.e., does not reorder equal elements).1546///1547/// This uses [`slice::sort_by_key`] internally.1548///1549/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1550/// This includes the allowed parameter type changes listed under [allowed transmutes].1551/// However, the lens uses the filter of the original query when present.1552///1553/// The sort is not cached across system runs.1554///1555/// [allowed transmutes]: crate::system::Query#allowed-transmutes1556///1557/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1558/// called on [`QueryManyIter`] before.1559///1560/// # Example1561/// ```1562/// # use bevy_ecs::prelude::*;1563/// # use std::ops::Deref;1564/// #1565/// # #[derive(Component)]1566/// # struct PartMarker;1567/// #1568/// # impl Deref for PartValue {1569/// # type Target = f32;1570/// #1571/// # fn deref(&self) -> &Self::Target {1572/// # &self.01573/// # }1574/// # }1575/// #1576/// # let mut world = World::new();1577/// # let entity_list: Vec<Entity> = Vec::new();1578/// #1579/// #[derive(Component)]1580/// struct AvailableMarker;1581///1582/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]1583/// enum Rarity {1584/// Common,1585/// Rare,1586/// Epic,1587/// Legendary1588/// };1589///1590/// #[derive(Component)]1591/// struct PartValue(f32);1592///1593/// // We can sort with the internals of components that do not implement Ord.1594/// fn system_1(query: Query<(Entity, &PartValue)>) {1595/// # let entity_list: Vec<Entity> = Vec::new();1596/// // Sort by the sines of the part values.1597/// let parts: Vec<(Entity, &PartValue)> = query1598/// .iter_many(entity_list)1599/// .sort_by_key::<&PartValue, _>(|value| value.sin() as usize)1600/// .collect();1601/// }1602///1603/// // We can define our own custom comparison functions over an EntityRef.1604/// fn system_2(query: Query<EntityRef, With<PartMarker>>) {1605/// # let entity_list: Vec<Entity> = Vec::new();1606/// // Sort by whether parts are available and their rarity.1607/// // We want the available legendaries to come first, so we reverse the iterator.1608/// let parts: Vec<EntityRef> = query.iter_many(entity_list)1609/// .sort_by_key::<EntityRef, _>(|entity_ref| {1610/// (1611/// entity_ref.contains::<AvailableMarker>(),1612// entity_ref.get::<Rarity>().copied()1613/// )1614/// })1615/// .rev()1616/// .collect();1617/// }1618/// # let mut schedule = Schedule::default();1619/// # schedule.add_systems((system_1, system_2));1620/// # schedule.run(&mut world);1621/// ```1622pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(1623self,1624mut f: impl FnMut(&L::Item<'_, '_>) -> K,1625) -> QuerySortedManyIter<1626'w,1627's,1628D,1629F,1630impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1631>1632where1633K: Ord,1634{1635self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_key(|(lens, _)| f(lens)))1636}16371638/// Sorts all query items into a new iterator with a key extraction function over the query lens.1639///1640/// This sort is unstable (i.e., may reorder equal elements).1641///1642/// This uses [`slice::sort_unstable_by_key`] internally.1643///1644/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1645/// This includes the allowed parameter type changes listed under [allowed transmutes].1646/// However, the lens uses the filter of the original query when present.1647///1648/// The sort is not cached across system runs.1649///1650/// [allowed transmutes]: crate::system::Query#allowed-transmutes1651///1652/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1653/// called on [`QueryManyIter`] before.1654pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(1655self,1656mut f: impl FnMut(&L::Item<'_, '_>) -> K,1657) -> QuerySortedManyIter<1658'w,1659's,1660D,1661F,1662impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1663>1664where1665K: Ord,1666{1667self.sort_impl::<L>(move |keyed_query| {1668keyed_query.sort_unstable_by_key(|(lens, _)| f(lens));1669})1670}16711672/// Sort all query items into a new iterator with a key extraction function over the query lens.1673///1674/// This sort is stable (i.e., does not reorder equal elements).1675///1676/// This uses [`slice::sort_by_cached_key`] internally.1677///1678/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1679/// This includes the allowed parameter type changes listed under [allowed transmutes].1680/// However, the lens uses the filter of the original query when present.1681///1682/// The sort is not cached across system runs.1683///1684/// [allowed transmutes]: crate::system::Query#allowed-transmutes1685///1686/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1687/// called on [`QueryManyIter`] before.1688pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(1689self,1690mut f: impl FnMut(&L::Item<'_, '_>) -> K,1691) -> QuerySortedManyIter<1692'w,1693's,1694D,1695F,1696impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1697>1698where1699K: Ord,1700{1701self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_cached_key(|(lens, _)| f(lens)))1702}17031704/// Shared implementation for the various `sort` methods.1705/// This uses the lens to collect the items for sorting, but delegates the actual sorting to the provided closure.1706///1707/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1708/// This includes the allowed parameter type changes listed under [allowed transmutes].1709/// However, the lens uses the filter of the original query when present.1710///1711/// The sort is not cached across system runs.1712///1713/// [allowed transmutes]: crate::system::Query#allowed-transmutes1714///1715/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1716/// called on [`QueryManyIter`] before.1717fn sort_impl<L: ReadOnlyQueryData + 'w>(1718self,1719f: impl FnOnce(&mut Vec<(L::Item<'_, '_>, NeutralOrd<Entity>)>),1720) -> QuerySortedManyIter<1721'w,1722's,1723D,1724F,1725impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1726> {1727let world = self.world;17281729let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);17301731// SAFETY:1732// `self.world` has permission to access the required components.1733// The original query iter has not been iterated on, so no items are aliased from it.1734// `QueryIter::new` ensures `world` is the same one used to initialize `query_state`.1735let query_lens = unsafe { query_lens_state.query_unchecked_manual(world) }1736.iter_many_inner(self.entity_iter);1737let mut keyed_query: Vec<_> = query_lens1738.map(|(key, entity)| (key, NeutralOrd(entity)))1739.collect();1740f(&mut keyed_query);1741// Re-collect into a `Vec` to eagerly drop the lens items.1742// They must be dropped before `fetch_next` is called since they may alias1743// with other data items if there are duplicate entities in `entity_iter`.1744let entity_iter = keyed_query1745.into_iter()1746.map(|(.., entity)| entity.0)1747.collect::<Vec<_>>()1748.into_iter();1749// SAFETY:1750// `self.world` has permission to access the required components.1751// Each lens query item is dropped before the respective actual query item is accessed.1752unsafe {1753QuerySortedManyIter::new(1754world,1755self.query_state,1756entity_iter,1757world.last_change_tick(),1758world.change_tick(),1759)1760}1761}1762}17631764impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item: EntityEquivalent>>1765QueryManyIter<'w, 's, D, F, I>1766{1767/// Get next result from the back of the query1768#[inline(always)]1769pub fn fetch_next_back(&mut self) -> Option<D::Item<'_, 's>> {1770// SAFETY:1771// All arguments stem from self.1772// We are limiting the returned reference to self,1773// making sure this method cannot be called multiple times without getting rid1774// of any previously returned unique references first, thus preventing aliasing.1775unsafe {1776Self::fetch_next_aliased_unchecked(1777self.entity_iter.by_ref().rev(),1778self.entities,1779self.tables,1780self.archetypes,1781&mut self.fetch,1782&mut self.filter,1783self.query_state,1784)1785.map(D::shrink)1786}1787}1788}17891790impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>> Iterator1791for QueryManyIter<'w, 's, D, F, I>1792{1793type Item = D::Item<'w, 's>;17941795#[inline(always)]1796fn next(&mut self) -> Option<Self::Item> {1797// SAFETY:1798// All arguments stem from self.1799// It is safe to alias for ReadOnlyWorldQuery.1800unsafe {1801Self::fetch_next_aliased_unchecked(1802&mut self.entity_iter,1803self.entities,1804self.tables,1805self.archetypes,1806&mut self.fetch,1807&mut self.filter,1808self.query_state,1809)1810}1811}18121813fn size_hint(&self) -> (usize, Option<usize>) {1814let (_, max_size) = self.entity_iter.size_hint();1815(0, max_size)1816}1817}18181819impl<1820'w,1821's,1822D: ReadOnlyQueryData,1823F: QueryFilter,1824I: DoubleEndedIterator<Item: EntityEquivalent>,1825> DoubleEndedIterator for QueryManyIter<'w, 's, D, F, I>1826{1827#[inline(always)]1828fn next_back(&mut self) -> Option<Self::Item> {1829// SAFETY:1830// All arguments stem from self.1831// It is safe to alias for ReadOnlyWorldQuery.1832unsafe {1833Self::fetch_next_aliased_unchecked(1834self.entity_iter.by_ref().rev(),1835self.entities,1836self.tables,1837self.archetypes,1838&mut self.fetch,1839&mut self.filter,1840self.query_state,1841)1842}1843}1844}18451846// This is correct as [`QueryManyIter`] always returns `None` once exhausted.1847impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>1848FusedIterator for QueryManyIter<'w, 's, D, F, I>1849{1850}18511852// SAFETY: Fetching unique entities maintains uniqueness.1853unsafe impl<'w, 's, F: QueryFilter, I: EntitySetIterator> EntitySetIterator1854for QueryManyIter<'w, 's, Entity, F, I>1855{1856}18571858impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>> Debug1859for QueryManyIter<'w, 's, D, F, I>1860{1861fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {1862f.debug_struct("QueryManyIter").finish()1863}1864}18651866/// An [`Iterator`] over the query items generated from an iterator of unique [`Entity`]s.1867///1868/// Items are returned in the order of the provided iterator.1869/// Entities that don't match the query are skipped.1870///1871/// In contrast with [`QueryManyIter`], this allows for mutable iteration without a [`fetch_next`] method.1872///1873/// This struct is created by the [`iter_many_unique`] and [`iter_many_unique_mut`] methods on [`Query`].1874///1875/// [`fetch_next`]: QueryManyIter::fetch_next1876/// [`iter_many_unique`]: crate::system::Query::iter_many1877/// [`iter_many_unique_mut`]: crate::system::Query::iter_many_mut1878/// [`Query`]: crate::system::Query1879pub struct QueryManyUniqueIter<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator>(1880QueryManyIter<'w, 's, D, F, I>,1881);18821883impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator>1884QueryManyUniqueIter<'w, 's, D, F, I>1885{1886/// # Safety1887/// - `world` must have permission to access any of the components registered in `query_state`.1888/// - `world` must be the same one used to initialize `query_state`.1889pub(crate) unsafe fn new<EntityList: EntitySet<IntoIter = I>>(1890world: UnsafeWorldCell<'w>,1891query_state: &'s QueryState<D, F>,1892entity_list: EntityList,1893last_run: Tick,1894this_run: Tick,1895) -> QueryManyUniqueIter<'w, 's, D, F, I> {1896QueryManyUniqueIter(QueryManyIter::new(1897world,1898query_state,1899entity_list,1900last_run,1901this_run,1902))1903}1904}19051906impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> Iterator1907for QueryManyUniqueIter<'w, 's, D, F, I>1908{1909type Item = D::Item<'w, 's>;19101911#[inline(always)]1912fn next(&mut self) -> Option<Self::Item> {1913// SAFETY: Entities are guaranteed to be unique, thus do not alias.1914unsafe {1915QueryManyIter::<'w, 's, D, F, I>::fetch_next_aliased_unchecked(1916&mut self.0.entity_iter,1917self.0.entities,1918self.0.tables,1919self.0.archetypes,1920&mut self.0.fetch,1921&mut self.0.filter,1922self.0.query_state,1923)1924}1925}19261927fn size_hint(&self) -> (usize, Option<usize>) {1928let (_, max_size) = self.0.entity_iter.size_hint();1929(0, max_size)1930}1931}19321933// This is correct as [`QueryManyIter`] always returns `None` once exhausted.1934impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> FusedIterator1935for QueryManyUniqueIter<'w, 's, D, F, I>1936{1937}19381939// SAFETY: Fetching unique entities maintains uniqueness.1940unsafe impl<'w, 's, F: QueryFilter, I: EntitySetIterator> EntitySetIterator1941for QueryManyUniqueIter<'w, 's, Entity, F, I>1942{1943}19441945impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> Debug1946for QueryManyUniqueIter<'w, 's, D, F, I>1947{1948fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {1949f.debug_struct("QueryManyUniqueIter").finish()1950}1951}19521953/// An [`Iterator`] over sorted query results of a [`QueryManyIter`].1954///1955/// This struct is created by the [`sort`](QueryManyIter), [`sort_unstable`](QueryManyIter),1956/// [`sort_by`](QueryManyIter), [`sort_unstable_by`](QueryManyIter), [`sort_by_key`](QueryManyIter),1957/// [`sort_unstable_by_key`](QueryManyIter), and [`sort_by_cached_key`](QueryManyIter) methods of [`QueryManyIter`].1958pub struct QuerySortedManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> {1959entity_iter: I,1960entities: &'w Entities,1961tables: &'w Tables,1962archetypes: &'w Archetypes,1963fetch: D::Fetch<'w>,1964query_state: &'s QueryState<D, F>,1965}19661967impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>>1968QuerySortedManyIter<'w, 's, D, F, I>1969{1970/// # Safety1971/// - `world` must have permission to access any of the components registered in `query_state`.1972/// - `world` must be the same one used to initialize `query_state`.1973/// - `entity_list` must only contain unique entities or be empty.1974pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(1975world: UnsafeWorldCell<'w>,1976query_state: &'s QueryState<D, F>,1977entity_list: EntityList,1978last_run: Tick,1979this_run: Tick,1980) -> QuerySortedManyIter<'w, 's, D, F, I> {1981let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);1982QuerySortedManyIter {1983query_state,1984entities: world.entities(),1985archetypes: world.archetypes(),1986// SAFETY: We only access table data that has been registered in `query_state`.1987// This means `world` has permission to access the data we use.1988tables: &world.storages().tables,1989fetch,1990entity_iter: entity_list.into_iter(),1991}1992}19931994/// # Safety1995/// The lifetime here is not restrictive enough for Fetch with &mut access,1996/// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple1997/// references to the same component, leading to unique reference aliasing.1998///1999/// It is always safe for shared access.2000/// `entity` must stem from `self.entity_iter`, and not have been passed before.2001#[inline(always)]2002unsafe fn fetch_next_aliased_unchecked(&mut self, entity: Entity) -> D::Item<'w, 's> {2003let (location, archetype, table);2004// SAFETY:2005// `tables` and `archetypes` belong to the same world that the [`QueryIter`]2006// was initialized for.2007unsafe {2008location = self.entities.get(entity).debug_checked_unwrap();2009archetype = self2010.archetypes2011.get(location.archetype_id)2012.debug_checked_unwrap();2013table = self.tables.get(location.table_id).debug_checked_unwrap();2014}20152016// SAFETY: `archetype` is from the world that `fetch` was created for,2017// `fetch_state` is the state that `fetch` was initialized with2018unsafe {2019D::set_archetype(2020&mut self.fetch,2021&self.query_state.fetch_state,2022archetype,2023table,2024);2025}20262027// The entity list has already been filtered by the query lens, so we forego filtering here.2028// SAFETY:2029// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype2030// - fetch is only called once for each entity.2031unsafe {2032D::fetch(2033&self.query_state.fetch_state,2034&mut self.fetch,2035entity,2036location.table_row,2037)2038}2039}20402041/// Get next result from the query2042#[inline(always)]2043pub fn fetch_next(&mut self) -> Option<D::Item<'_, 's>> {2044let entity = self.entity_iter.next()?;20452046// SAFETY:2047// We have collected the entity_iter once to drop all internal lens query item2048// references.2049// We are limiting the returned reference to self,2050// making sure this method cannot be called multiple times without getting rid2051// of any previously returned unique references first, thus preventing aliasing.2052// `entity` is passed from `entity_iter` the first time.2053unsafe { D::shrink(self.fetch_next_aliased_unchecked(entity)).into() }2054}2055}20562057impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item = Entity>>2058QuerySortedManyIter<'w, 's, D, F, I>2059{2060/// Get next result from the query2061#[inline(always)]2062pub fn fetch_next_back(&mut self) -> Option<D::Item<'_, 's>> {2063let entity = self.entity_iter.next_back()?;20642065// SAFETY:2066// We have collected the entity_iter once to drop all internal lens query item2067// references.2068// We are limiting the returned reference to self,2069// making sure this method cannot be called multiple times without getting rid2070// of any previously returned unique references first, thus preventing aliasing.2071// `entity` is passed from `entity_iter` the first time.2072unsafe { D::shrink(self.fetch_next_aliased_unchecked(entity)).into() }2073}2074}20752076impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item = Entity>> Iterator2077for QuerySortedManyIter<'w, 's, D, F, I>2078{2079type Item = D::Item<'w, 's>;20802081#[inline(always)]2082fn next(&mut self) -> Option<Self::Item> {2083let entity = self.entity_iter.next()?;2084// SAFETY:2085// It is safe to alias for ReadOnlyWorldQuery.2086// `entity` is passed from `entity_iter` the first time.2087unsafe { self.fetch_next_aliased_unchecked(entity).into() }2088}20892090fn size_hint(&self) -> (usize, Option<usize>) {2091self.entity_iter.size_hint()2092}2093}20942095impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: DoubleEndedIterator<Item = Entity>>2096DoubleEndedIterator for QuerySortedManyIter<'w, 's, D, F, I>2097{2098#[inline(always)]2099fn next_back(&mut self) -> Option<Self::Item> {2100let entity = self.entity_iter.next_back()?;2101// SAFETY:2102// It is safe to alias for ReadOnlyWorldQuery.2103// `entity` is passed from `entity_iter` the first time.2104unsafe { self.fetch_next_aliased_unchecked(entity).into() }2105}2106}21072108impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: ExactSizeIterator<Item = Entity>>2109ExactSizeIterator for QuerySortedManyIter<'w, 's, D, F, I>2110{2111}21122113impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> Debug2114for QuerySortedManyIter<'w, 's, D, F, I>2115{2116fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {2117f.debug_struct("QuerySortedManyIter").finish()2118}2119}21202121/// An iterator over `K`-sized combinations of query items without repetition.2122///2123/// A combination is an arrangement of a collection of items where order does not matter.2124///2125/// `K` is the number of items that make up each subset, and the number of items returned by the iterator.2126/// `N` is the number of total entities output by the query.2127///2128/// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are2129/// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].2130/// And in this case, `N` would be defined as 4 since the size of the input list is 4.2131///2132/// The number of combinations depend on how `K` relates to the number of entities matching the [`Query`]:2133/// - if `K = N`, only one combination exists,2134/// - if `K < N`, there are <sub>N</sub>C<sub>K</sub> combinations (see the [performance section] of `Query`),2135/// - if `K > N`, there are no combinations.2136///2137/// The output combination is not guaranteed to have any order of iteration.2138///2139/// # Usage2140///2141/// This type is returned by calling [`Query::iter_combinations`] or [`Query::iter_combinations_mut`].2142///2143/// It implements [`Iterator`] only if it iterates over read-only query items ([learn more]).2144///2145/// In the case of mutable query items, it can be iterated by calling [`fetch_next`] in a `while let` loop.2146///2147/// # Examples2148///2149/// The following example shows how to traverse the iterator when the query items are read-only.2150///2151/// ```2152/// # use bevy_ecs::prelude::*;2153/// # #[derive(Component)]2154/// # struct ComponentA;2155/// #2156/// fn some_system(query: Query<&ComponentA>) {2157/// for [a1, a2] in query.iter_combinations() {2158/// // ...2159/// }2160/// }2161/// ```2162///2163/// 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.2164///2165/// ```2166/// # use bevy_ecs::prelude::*;2167/// # #[derive(Component)]2168/// # struct ComponentA;2169/// #2170/// fn some_system(mut query: Query<&mut ComponentA>) {2171/// let mut combinations = query.iter_combinations_mut();2172/// while let Some([a1, a2]) = combinations.fetch_next() {2173/// // ...2174/// }2175/// }2176/// ```2177///2178/// [`fetch_next`]: Self::fetch_next2179/// [learn more]: Self#impl-Iterator2180/// [performance section]: crate::system::Query#performance2181/// [`Query`]: crate::system::Query2182/// [`Query::iter_combinations`]: crate::system::Query::iter_combinations2183/// [`Query::iter_combinations_mut`]: crate::system::Query::iter_combinations_mut2184pub struct QueryCombinationIter<'w, 's, D: QueryData, F: QueryFilter, const K: usize> {2185tables: &'w Tables,2186archetypes: &'w Archetypes,2187query_state: &'s QueryState<D, F>,2188cursors: [QueryIterationCursor<'w, 's, D, F>; K],2189}21902191impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<'w, 's, D, F, K> {2192/// # Safety2193/// - `world` must have permission to access any of the components registered in `query_state`.2194/// - `world` must be the same one used to initialize `query_state`.2195pub(crate) unsafe fn new(2196world: UnsafeWorldCell<'w>,2197query_state: &'s QueryState<D, F>,2198last_run: Tick,2199this_run: Tick,2200) -> Self {2201assert!(K != 0, "K should not equal to zero");2202// Initialize array with cursors.2203// There is no FromIterator on arrays, so instead initialize it manually with MaybeUninit22042205let mut array: MaybeUninit<[QueryIterationCursor<'w, 's, D, F>; K]> = MaybeUninit::uninit();2206let ptr = array2207.as_mut_ptr()2208.cast::<QueryIterationCursor<'w, 's, D, F>>();2209ptr.write(QueryIterationCursor::init(2210world,2211query_state,2212last_run,2213this_run,2214));2215for slot in (1..K).map(|offset| ptr.add(offset)) {2216slot.write(QueryIterationCursor::init_empty(2217world,2218query_state,2219last_run,2220this_run,2221));2222}22232224QueryCombinationIter {2225query_state,2226// SAFETY: We only access table data that has been registered in `query_state`.2227tables: unsafe { &world.storages().tables },2228archetypes: world.archetypes(),2229cursors: array.assume_init(),2230}2231}22322233/// # Safety2234/// The lifetime here is not restrictive enough for Fetch with &mut access,2235/// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple2236/// references to the same component, leading to unique reference aliasing.2237/// .2238/// It is always safe for shared access.2239#[inline]2240unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<[D::Item<'w, 's>; K]> {2241// PERF: can speed up the following code using `cursor.remaining()` instead of `next_item.is_none()`2242// when D::IS_ARCHETYPAL && F::IS_ARCHETYPAL2243//2244// let `i` be the index of `c`, the last cursor in `self.cursors` that2245// returns `K-i` or more elements.2246// Make cursor in index `j` for all `j` in `[i, K)` a copy of `c` advanced `j-i+1` times.2247// If no such `c` exists, return `None`2248'outer: for i in (0..K).rev() {2249match self.cursors[i].next(self.tables, self.archetypes, self.query_state) {2250Some(_) => {2251for j in (i + 1)..K {2252self.cursors[j] = self.cursors[j - 1].clone();2253match self.cursors[j].next(self.tables, self.archetypes, self.query_state) {2254Some(_) => {}2255None if i > 0 => continue 'outer,2256None => return None,2257}2258}2259break;2260}2261None if i > 0 => continue,2262None => return None,2263}2264}22652266let mut values = MaybeUninit::<[D::Item<'w, 's>; K]>::uninit();22672268let ptr = values.as_mut_ptr().cast::<D::Item<'w, 's>>();2269for (offset, cursor) in self.cursors.iter_mut().enumerate() {2270ptr.add(offset)2271.write(cursor.peek_last(self.query_state).unwrap());2272}22732274Some(values.assume_init())2275}22762277/// Get next combination of queried components2278#[inline]2279pub fn fetch_next(&mut self) -> Option<[D::Item<'_, 's>; K]> {2280// SAFETY: we are limiting the returned reference to self,2281// making sure this method cannot be called multiple times without getting rid2282// of any previously returned unique references first, thus preventing aliasing.2283unsafe {2284self.fetch_next_aliased_unchecked()2285.map(|array| array.map(D::shrink))2286}2287}2288}22892290// Iterator type is intentionally implemented only for read-only access.2291// Doing so for mutable references would be unsound, because calling `next`2292// multiple times would allow multiple owned references to the same data to exist.2293impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator2294for QueryCombinationIter<'w, 's, D, F, K>2295{2296type Item = [D::Item<'w, 's>; K];22972298#[inline]2299fn next(&mut self) -> Option<Self::Item> {2300// Safety: it is safe to alias for ReadOnlyWorldQuery2301unsafe { QueryCombinationIter::fetch_next_aliased_unchecked(self) }2302}23032304fn size_hint(&self) -> (usize, Option<usize>) {2305// binomial coefficient: (n ; k) = n! / k!(n-k)! = (n*n-1*...*n-k+1) / k!2306// See https://en.wikipedia.org/wiki/Binomial_coefficient2307// See https://blog.plover.com/math/choose.html for implementation2308// It was chosen to reduce overflow potential.2309fn choose(n: usize, k: usize) -> Option<usize> {2310if k > n || n == 0 {2311return Some(0);2312}2313let k = k.min(n - k);2314let ks = 1..=k;2315let ns = (n - k + 1..=n).rev();2316ks.zip(ns)2317.try_fold(1_usize, |acc, (k, n)| Some(acc.checked_mul(n)? / k))2318}2319// sum_i=0..k choose(cursors[i].remaining, k-i)2320let max_combinations = self2321.cursors2322.iter()2323.enumerate()2324.try_fold(0, |acc, (i, cursor)| {2325let n = cursor.max_remaining(self.tables, self.archetypes);2326Some(acc + choose(n as usize, K - i)?)2327});23282329let archetype_query = F::IS_ARCHETYPAL;2330let known_max = max_combinations.unwrap_or(usize::MAX);2331let min_combinations = if archetype_query { known_max } else { 0 };2332(min_combinations, max_combinations)2333}2334}23352336impl<'w, 's, D: QueryData, F: QueryFilter> ExactSizeIterator for QueryIter<'w, 's, D, F>2337where2338F: ArchetypeFilter,2339{2340fn len(&self) -> usize {2341self.size_hint().02342}2343}23442345// This is correct as [`QueryCombinationIter`] always returns `None` once exhausted.2346impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> FusedIterator2347for QueryCombinationIter<'w, 's, D, F, K>2348{2349}23502351impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> Debug2352for QueryCombinationIter<'w, 's, D, F, K>2353{2354fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {2355f.debug_struct("QueryCombinationIter").finish()2356}2357}23582359struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> {2360// whether the query iteration is dense or not. Mirrors QueryState's `is_dense` field.2361is_dense: bool,2362storage_id_iter: core::slice::Iter<'s, StorageId>,2363table_entities: &'w [Entity],2364archetype_entities: &'w [ArchetypeEntity],2365fetch: D::Fetch<'w>,2366filter: F::Fetch<'w>,2367// length of the table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense2368current_len: u32,2369// either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense2370current_row: u32,2371}23722373impl<D: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, D, F> {2374fn clone(&self) -> Self {2375Self {2376is_dense: self.is_dense,2377storage_id_iter: self.storage_id_iter.clone(),2378table_entities: self.table_entities,2379archetype_entities: self.archetype_entities,2380fetch: self.fetch.clone(),2381filter: self.filter.clone(),2382current_len: self.current_len,2383current_row: self.current_row,2384}2385}2386}23872388impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {2389/// # Safety2390/// - `world` must have permission to access any of the components registered in `query_state`.2391/// - `world` must be the same one used to initialize `query_state`.2392unsafe fn init_empty(2393world: UnsafeWorldCell<'w>,2394query_state: &'s QueryState<D, F>,2395last_run: Tick,2396this_run: Tick,2397) -> Self {2398QueryIterationCursor {2399storage_id_iter: [].iter(),2400..Self::init(world, query_state, last_run, this_run)2401}2402}24032404/// # Safety2405/// - `world` must have permission to access any of the components registered in `query_state`.2406/// - `world` must be the same one used to initialize `query_state`.2407unsafe fn init(2408world: UnsafeWorldCell<'w>,2409query_state: &'s QueryState<D, F>,2410last_run: Tick,2411this_run: Tick,2412) -> Self {2413let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);2414let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);2415QueryIterationCursor {2416fetch,2417filter,2418table_entities: &[],2419archetype_entities: &[],2420storage_id_iter: query_state.matched_storage_ids.iter(),2421is_dense: query_state.is_dense,2422current_len: 0,2423current_row: 0,2424}2425}24262427fn reborrow(&mut self) -> QueryIterationCursor<'_, 's, D, F> {2428QueryIterationCursor {2429is_dense: self.is_dense,2430fetch: D::shrink_fetch(self.fetch.clone()),2431filter: F::shrink_fetch(self.filter.clone()),2432table_entities: self.table_entities,2433archetype_entities: self.archetype_entities,2434storage_id_iter: self.storage_id_iter.clone(),2435current_len: self.current_len,2436current_row: self.current_row,2437}2438}24392440/// Retrieve item returned from most recent `next` call again.2441///2442/// # Safety2443/// The result of `next` and any previous calls to `peek_last` with this row must have been2444/// dropped to prevent aliasing mutable references.2445#[inline]2446unsafe fn peek_last(&mut self, query_state: &'s QueryState<D, F>) -> Option<D::Item<'w, 's>> {2447if self.current_row > 0 {2448let index = self.current_row - 1;2449if self.is_dense {2450// SAFETY: This must have been called previously in `next` as `current_row > 0`2451let entity = unsafe { self.table_entities.get_unchecked(index as usize) };2452// SAFETY:2453// - `set_table` must have been called previously either in `next` or before it.2454// - `*entity` and `index` are in the current table.2455unsafe {2456Some(D::fetch(2457&query_state.fetch_state,2458&mut self.fetch,2459*entity,2460// SAFETY: This is from an exclusive range, so it can't be max.2461TableRow::new(NonMaxU32::new_unchecked(index)),2462))2463}2464} else {2465// SAFETY: This must have been called previously in `next` as `current_row > 0`2466let archetype_entity =2467unsafe { self.archetype_entities.get_unchecked(index as usize) };2468// SAFETY:2469// - `set_archetype` must have been called previously either in `next` or before it.2470// - `archetype_entity.id()` and `archetype_entity.table_row()` are in the current archetype.2471unsafe {2472Some(D::fetch(2473&query_state.fetch_state,2474&mut self.fetch,2475archetype_entity.id(),2476archetype_entity.table_row(),2477))2478}2479}2480} else {2481None2482}2483}24842485/// How many values will this cursor return at most?2486///2487/// Note that if `F::IS_ARCHETYPAL`, the return value2488/// will be **the exact count of remaining values**.2489fn max_remaining(&self, tables: &'w Tables, archetypes: &'w Archetypes) -> u32 {2490let ids = self.storage_id_iter.clone();2491let remaining_matched: u32 = if self.is_dense {2492// SAFETY: The if check ensures that storage_id_iter stores TableIds2493unsafe { ids.map(|id| tables[id.table_id].entity_count()).sum() }2494} else {2495// SAFETY: The if check ensures that storage_id_iter stores ArchetypeIds2496unsafe { ids.map(|id| archetypes[id.archetype_id].len()).sum() }2497};2498remaining_matched + self.current_len - self.current_row2499}25002501// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:2502// QueryIter, QueryIterationCursor, QuerySortedIter, QueryManyIter, QuerySortedManyIter, QueryCombinationIter,2503// QueryState::par_fold_init_unchecked_manual, QueryState::par_many_fold_init_unchecked_manual,2504// QueryState::par_many_unique_fold_init_unchecked_manual2505/// # Safety2506/// `tables` and `archetypes` must belong to the same world that the [`QueryIterationCursor`]2507/// was initialized for.2508/// `query_state` must be the same [`QueryState`] that was passed to `init` or `init_empty`.2509#[inline(always)]2510unsafe fn next(2511&mut self,2512tables: &'w Tables,2513archetypes: &'w Archetypes,2514query_state: &'s QueryState<D, F>,2515) -> Option<D::Item<'w, 's>> {2516if self.is_dense {2517loop {2518// we are on the beginning of the query, or finished processing a table, so skip to the next2519if self.current_row == self.current_len {2520let table_id = self.storage_id_iter.next()?.table_id;2521let table = tables.get(table_id).debug_checked_unwrap();2522if table.is_empty() {2523continue;2524}2525// SAFETY: `table` is from the world that `fetch/filter` were created for,2526// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with2527unsafe {2528D::set_table(&mut self.fetch, &query_state.fetch_state, table);2529F::set_table(&mut self.filter, &query_state.filter_state, table);2530}2531self.table_entities = table.entities();2532self.current_len = table.entity_count();2533self.current_row = 0;2534}25352536// SAFETY: set_table was called prior.2537// `current_row` is a table row in range of the current table, because if it was not, then the above would have been executed.2538let entity =2539unsafe { self.table_entities.get_unchecked(self.current_row as usize) };2540// SAFETY: The row is less than the u32 len, so it must not be max.2541let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(self.current_row)) };2542if !F::filter_fetch(&query_state.filter_state, &mut self.filter, *entity, row) {2543self.current_row += 1;2544continue;2545}25462547// SAFETY:2548// - set_table was called prior.2549// - `current_row` must be a table row in range of the current table,2550// because if it was not, then the above would have been executed.2551// - fetch is only called once for each `entity`.2552let item =2553unsafe { D::fetch(&query_state.fetch_state, &mut self.fetch, *entity, row) };25542555self.current_row += 1;2556return Some(item);2557}2558} else {2559loop {2560if self.current_row == self.current_len {2561let archetype_id = self.storage_id_iter.next()?.archetype_id;2562let archetype = archetypes.get(archetype_id).debug_checked_unwrap();2563if archetype.is_empty() {2564continue;2565}2566let table = tables.get(archetype.table_id()).debug_checked_unwrap();2567// SAFETY: `archetype` and `tables` are from the world that `fetch/filter` were created for,2568// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with2569unsafe {2570D::set_archetype(2571&mut self.fetch,2572&query_state.fetch_state,2573archetype,2574table,2575);2576F::set_archetype(2577&mut self.filter,2578&query_state.filter_state,2579archetype,2580table,2581);2582}2583self.archetype_entities = archetype.entities();2584self.current_len = archetype.len();2585self.current_row = 0;2586}25872588// SAFETY: set_archetype was called prior.2589// `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.2590let archetype_entity = unsafe {2591self.archetype_entities2592.get_unchecked(self.current_row as usize)2593};2594if !F::filter_fetch(2595&query_state.filter_state,2596&mut self.filter,2597archetype_entity.id(),2598archetype_entity.table_row(),2599) {2600self.current_row += 1;2601continue;2602}26032604// SAFETY:2605// - set_archetype was called prior.2606// - `current_row` must be an archetype index row in range of the current archetype,2607// because if it was not, then the if above would have been executed.2608// - fetch is only called once for each `archetype_entity`.2609let item = unsafe {2610D::fetch(2611&query_state.fetch_state,2612&mut self.fetch,2613archetype_entity.id(),2614archetype_entity.table_row(),2615)2616};2617self.current_row += 1;2618return Some(item);2619}2620}2621}2622}26232624// A wrapper struct that gives its data a neutral ordering.2625#[derive(Copy, Clone)]2626struct NeutralOrd<T>(T);26272628impl<T> PartialEq for NeutralOrd<T> {2629fn eq(&self, _other: &Self) -> bool {2630true2631}2632}26332634impl<T> Eq for NeutralOrd<T> {}26352636#[expect(2637clippy::non_canonical_partial_ord_impl,2638reason = "`PartialOrd` and `Ord` on this struct must only ever return `Ordering::Equal`, so we prefer clarity"2639)]2640impl<T> PartialOrd for NeutralOrd<T> {2641fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {2642Some(Ordering::Equal)2643}2644}26452646impl<T> Ord for NeutralOrd<T> {2647fn cmp(&self, _other: &Self) -> Ordering {2648Ordering::Equal2649}2650}26512652#[cfg(test)]2653#[expect(clippy::print_stdout, reason = "Allowed in tests.")]2654mod tests {2655use alloc::vec::Vec;2656use std::println;26572658use crate::component::Component;2659use crate::entity::Entity;2660use crate::prelude::World;26612662#[derive(Component, Debug, PartialEq, PartialOrd, Clone, Copy)]2663struct A(f32);2664#[derive(Component, Debug, Eq, PartialEq, Clone, Copy)]2665#[component(storage = "SparseSet")]2666struct Sparse(usize);26672668#[test]2669fn query_iter_sorts() {2670let mut world = World::new();2671for i in 0..100 {2672world.spawn(A(i as f32));2673world.spawn((A(i as f32), Sparse(i)));2674world.spawn(Sparse(i));2675}26762677let mut query = world.query::<Entity>();26782679let sort = query.iter(&world).sort::<Entity>().collect::<Vec<_>>();2680assert_eq!(sort.len(), 300);26812682let sort_unstable = query2683.iter(&world)2684.sort_unstable::<Entity>()2685.collect::<Vec<_>>();26862687let sort_by = query2688.iter(&world)2689.sort_by::<Entity>(Ord::cmp)2690.collect::<Vec<_>>();26912692let sort_unstable_by = query2693.iter(&world)2694.sort_unstable_by::<Entity>(Ord::cmp)2695.collect::<Vec<_>>();26962697let sort_by_key = query2698.iter(&world)2699.sort_by_key::<Entity, _>(|&e| e)2700.collect::<Vec<_>>();27012702let sort_unstable_by_key = query2703.iter(&world)2704.sort_unstable_by_key::<Entity, _>(|&e| e)2705.collect::<Vec<_>>();27062707let sort_by_cached_key = query2708.iter(&world)2709.sort_by_cached_key::<Entity, _>(|&e| e)2710.collect::<Vec<_>>();27112712let mut sort_v2 = query.iter(&world).collect::<Vec<_>>();2713sort_v2.sort();27142715let mut sort_unstable_v2 = query.iter(&world).collect::<Vec<_>>();2716sort_unstable_v2.sort_unstable();27172718let mut sort_by_v2 = query.iter(&world).collect::<Vec<_>>();2719sort_by_v2.sort_by(Ord::cmp);27202721let mut sort_unstable_by_v2 = query.iter(&world).collect::<Vec<_>>();2722sort_unstable_by_v2.sort_unstable_by(Ord::cmp);27232724let mut sort_by_key_v2 = query.iter(&world).collect::<Vec<_>>();2725sort_by_key_v2.sort_by_key(|&e| e);27262727let mut sort_unstable_by_key_v2 = query.iter(&world).collect::<Vec<_>>();2728sort_unstable_by_key_v2.sort_unstable_by_key(|&e| e);27292730let mut sort_by_cached_key_v2 = query.iter(&world).collect::<Vec<_>>();2731sort_by_cached_key_v2.sort_by_cached_key(|&e| e);27322733assert_eq!(sort, sort_v2);2734assert_eq!(sort_unstable, sort_unstable_v2);2735assert_eq!(sort_by, sort_by_v2);2736assert_eq!(sort_unstable_by, sort_unstable_by_v2);2737assert_eq!(sort_by_key, sort_by_key_v2);2738assert_eq!(sort_unstable_by_key, sort_unstable_by_key_v2);2739assert_eq!(sort_by_cached_key, sort_by_cached_key_v2);2740}27412742#[test]2743#[should_panic]2744fn query_iter_sort_after_next() {2745let mut world = World::new();2746world.spawn((A(0.),));2747world.spawn((A(1.1),));2748world.spawn((A(2.22),));27492750{2751let mut query = world.query::<&A>();2752let mut iter = query.iter(&world);2753println!(2754"archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2755iter.cursor.archetype_entities.len(),2756iter.cursor.table_entities.len(),2757iter.cursor.current_len,2758iter.cursor.current_row2759);2760_ = iter.next();2761println!(2762"archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2763iter.cursor.archetype_entities.len(),2764iter.cursor.table_entities.len(),2765iter.cursor.current_len,2766iter.cursor.current_row2767);2768println!("{}", iter.sort::<Entity>().len());2769}2770}27712772#[test]2773#[should_panic]2774fn query_iter_sort_after_next_dense() {2775let mut world = World::new();2776world.spawn((Sparse(11),));2777world.spawn((Sparse(22),));2778world.spawn((Sparse(33),));27792780{2781let mut query = world.query::<&Sparse>();2782let mut iter = query.iter(&world);2783println!(2784"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2785iter.cursor.archetype_entities.len(),2786iter.cursor.table_entities.len(),2787iter.cursor.current_len,2788iter.cursor.current_row2789);2790_ = iter.next();2791println!(2792"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2793iter.cursor.archetype_entities.len(),2794iter.cursor.table_entities.len(),2795iter.cursor.current_len,2796iter.cursor.current_row2797);2798println!("{}", iter.sort::<Entity>().len());2799}2800}28012802#[test]2803fn empty_query_iter_sort_after_next_does_not_panic() {2804let mut world = World::new();2805{2806let mut query = world.query::<(&A, &Sparse)>();2807let mut iter = query.iter(&world);2808println!(2809"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2810iter.cursor.archetype_entities.len(),2811iter.cursor.table_entities.len(),2812iter.cursor.current_len,2813iter.cursor.current_row2814);2815_ = iter.next();2816println!(2817"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2818iter.cursor.archetype_entities.len(),2819iter.cursor.table_entities.len(),2820iter.cursor.current_len,2821iter.cursor.current_row2822);2823println!("{}", iter.sort::<Entity>().len());2824}2825}28262827#[test]2828fn query_iter_cursor_state_non_empty_after_next() {2829let mut world = World::new();2830world.spawn((A(0.), Sparse(11)));2831world.spawn((A(1.1), Sparse(22)));2832world.spawn((A(2.22), Sparse(33)));2833{2834let mut query = world.query::<(&A, &Sparse)>();2835let mut iter = query.iter(&world);2836println!(2837"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2838iter.cursor.archetype_entities.len(),2839iter.cursor.table_entities.len(),2840iter.cursor.current_len,2841iter.cursor.current_row2842);2843assert!(iter.cursor.table_entities.len() | iter.cursor.archetype_entities.len() == 0);2844_ = iter.next();2845println!(2846"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2847iter.cursor.archetype_entities.len(),2848iter.cursor.table_entities.len(),2849iter.cursor.current_len,2850iter.cursor.current_row2851);2852assert!(2853(2854iter.cursor.table_entities.len(),2855iter.cursor.archetype_entities.len()2856) != (0, 0)2857);2858}2859}28602861#[test]2862fn query_iter_many_sorts() {2863let mut world = World::new();28642865let entity_list: &Vec<_> = &world2866.spawn_batch([A(0.), A(1.), A(2.), A(3.), A(4.)])2867.collect();28682869let mut query = world.query::<Entity>();28702871let sort = query2872.iter_many(&world, entity_list)2873.sort::<Entity>()2874.collect::<Vec<_>>();28752876let sort_unstable = query2877.iter_many(&world, entity_list)2878.sort_unstable::<Entity>()2879.collect::<Vec<_>>();28802881let sort_by = query2882.iter_many(&world, entity_list)2883.sort_by::<Entity>(Ord::cmp)2884.collect::<Vec<_>>();28852886let sort_unstable_by = query2887.iter_many(&world, entity_list)2888.sort_unstable_by::<Entity>(Ord::cmp)2889.collect::<Vec<_>>();28902891let sort_by_key = query2892.iter_many(&world, entity_list)2893.sort_by_key::<Entity, _>(|&e| e)2894.collect::<Vec<_>>();28952896let sort_unstable_by_key = query2897.iter_many(&world, entity_list)2898.sort_unstable_by_key::<Entity, _>(|&e| e)2899.collect::<Vec<_>>();29002901let sort_by_cached_key = query2902.iter_many(&world, entity_list)2903.sort_by_cached_key::<Entity, _>(|&e| e)2904.collect::<Vec<_>>();29052906let mut sort_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();2907sort_v2.sort();29082909let mut sort_unstable_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();2910sort_unstable_v2.sort_unstable();29112912let mut sort_by_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();2913sort_by_v2.sort_by(Ord::cmp);29142915let mut sort_unstable_by_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();2916sort_unstable_by_v2.sort_unstable_by(Ord::cmp);29172918let mut sort_by_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();2919sort_by_key_v2.sort_by_key(|&e| e);29202921let mut sort_unstable_by_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();2922sort_unstable_by_key_v2.sort_unstable_by_key(|&e| e);29232924let mut sort_by_cached_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();2925sort_by_cached_key_v2.sort_by_cached_key(|&e| e);29262927assert_eq!(sort, sort_v2);2928assert_eq!(sort_unstable, sort_unstable_v2);2929assert_eq!(sort_by, sort_by_v2);2930assert_eq!(sort_unstable_by, sort_unstable_by_v2);2931assert_eq!(sort_by_key, sort_by_key_v2);2932assert_eq!(sort_unstable_by_key, sort_unstable_by_key_v2);2933assert_eq!(sort_by_cached_key, sort_by_cached_key_v2);2934}29352936#[test]2937fn query_iter_many_sort_doesnt_panic_after_next() {2938let mut world = World::new();29392940let entity_list: &Vec<_> = &world2941.spawn_batch([A(0.), A(1.), A(2.), A(3.), A(4.)])2942.collect();29432944let mut query = world.query::<Entity>();2945let mut iter = query.iter_many(&world, entity_list);29462947_ = iter.next();29482949iter.sort::<Entity>();29502951let mut query_2 = world.query::<&mut A>();2952let mut iter_2 = query_2.iter_many_mut(&mut world, entity_list);29532954_ = iter_2.fetch_next();29552956iter_2.sort::<Entity>();2957}29582959// This test should be run with miri to check for UB caused by aliasing.2960// The lens items created during the sort must not be live at the same time as the mutable references returned from the iterator.2961#[test]2962fn query_iter_many_sorts_duplicate_entities_no_ub() {2963#[derive(Component, Ord, PartialOrd, Eq, PartialEq)]2964struct C(usize);29652966let mut world = World::new();2967let id = world.spawn(C(10)).id();2968let mut query_state = world.query::<&mut C>();29692970{2971let mut query = query_state.iter_many_mut(&mut world, [id, id]).sort::<&C>();2972while query.fetch_next().is_some() {}2973}2974{2975let mut query = query_state2976.iter_many_mut(&mut world, [id, id])2977.sort_unstable::<&C>();2978while query.fetch_next().is_some() {}2979}2980{2981let mut query = query_state2982.iter_many_mut(&mut world, [id, id])2983.sort_by::<&C>(|l, r| Ord::cmp(l, r));2984while query.fetch_next().is_some() {}2985}2986{2987let mut query = query_state2988.iter_many_mut(&mut world, [id, id])2989.sort_unstable_by::<&C>(|l, r| Ord::cmp(l, r));2990while query.fetch_next().is_some() {}2991}2992{2993let mut query = query_state2994.iter_many_mut(&mut world, [id, id])2995.sort_by_key::<&C, _>(|d| d.0);2996while query.fetch_next().is_some() {}2997}2998{2999let mut query = query_state3000.iter_many_mut(&mut world, [id, id])3001.sort_unstable_by_key::<&C, _>(|d| d.0);3002while query.fetch_next().is_some() {}3003}3004{3005let mut query = query_state3006.iter_many_mut(&mut world, [id, id])3007.sort_by_cached_key::<&C, _>(|d| d.0);3008while query.fetch_next().is_some() {}3009}3010}3011}301230133014