use super::{QueryData, QueryFilter, ReadOnlyQueryData};1use crate::{2archetype::{Archetype, ArchetypeEntity, Archetypes},3bundle::Bundle,4change_detection::Tick,5entity::{ContainsEntity, Entities, Entity, EntityEquivalent, EntitySet, EntitySetIterator},6query::{7ArchetypeFilter, ArchetypeQueryData, ContiguousQueryData, DebugCheckedUnwrap, QueryState,8StorageId,9},10storage::{Table, TableRow, Tables},11world::{12unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,13FilteredEntityMut, FilteredEntityRef,14},15};16use alloc::vec::Vec;17use core::{18cmp::Ordering,19fmt::{self, Debug, Formatter},20iter::FusedIterator,21mem::MaybeUninit,22ops::Range,23};24use nonmax::NonMaxU32;2526/// An [`Iterator`] over query results of a [`Query`](crate::system::Query).27///28/// This struct is created by the [`Query::iter`](crate::system::Query::iter) and29/// [`Query::iter_mut`](crate::system::Query::iter_mut) methods.30pub struct QueryIter<'w, 's, D: QueryData, F: QueryFilter> {31world: UnsafeWorldCell<'w>,32tables: &'w Tables,33archetypes: &'w Archetypes,34query_state: &'s QueryState<D, F>,35cursor: QueryIterationCursor<'w, 's, D, F>,36}3738impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {39/// # Safety40/// - `world` must have permission to access any of the components registered in `query_state`.41/// - `world` must be the same one used to initialize `query_state`.42pub(crate) unsafe fn new(43world: UnsafeWorldCell<'w>,44query_state: &'s QueryState<D, F>,45last_run: Tick,46this_run: Tick,47) -> Self {48QueryIter {49world,50query_state,51// SAFETY: We only access table data that has been registered in `query_state`.52tables: unsafe { &world.storages().tables },53archetypes: world.archetypes(),54// SAFETY: The invariants are upheld by the caller.55cursor: unsafe { QueryIterationCursor::init(world, query_state, last_run, this_run) },56}57}5859/// Creates a new separate iterator yielding the same remaining items of the current one.60/// Advancing the new iterator will not advance the original one, which will resume at the61/// point it was left at.62///63/// Differently from [`remaining_mut`](QueryIter::remaining_mut) the new iterator does not64/// borrow from the original one. However it can only be called from an iterator over read only65/// items.66///67/// # Example68///69/// ```70/// # use bevy_ecs::prelude::*;71/// #72/// # #[derive(Component)]73/// # struct ComponentA;74///75/// fn combinations(query: Query<&ComponentA>) {76/// let mut iter = query.iter();77/// while let Some(a) = iter.next() {78/// for b in iter.remaining() {79/// // Check every combination (a, b)80/// }81/// }82/// }83/// ```84pub fn remaining(&self) -> QueryIter<'w, 's, D, F>85where86D: ReadOnlyQueryData,87{88QueryIter {89world: self.world,90tables: self.tables,91archetypes: self.archetypes,92query_state: self.query_state,93cursor: self.cursor.clone(),94}95}9697/// Creates a new separate iterator yielding the same remaining items of the current one.98/// Advancing the new iterator will not advance the original one, which will resume at the99/// point it was left at.100///101/// This method can be called on iterators over mutable items. However the original iterator102/// will be borrowed while the new iterator exists and will thus not be usable in that timespan.103///104/// # Example105///106/// ```107/// # use bevy_ecs::prelude::*;108/// #109/// # #[derive(Component)]110/// # struct ComponentA;111///112/// fn combinations(mut query: Query<&mut ComponentA>) {113/// let mut iter = query.iter_mut();114/// while let Some(a) = iter.next() {115/// for b in iter.remaining_mut() {116/// // Check every combination (a, b)117/// }118/// }119/// }120/// ```121pub fn remaining_mut(&mut self) -> QueryIter<'_, 's, D, F> {122QueryIter {123world: self.world,124tables: self.tables,125archetypes: self.archetypes,126query_state: self.query_state,127cursor: self.cursor.reborrow(),128}129}130131/// Executes the equivalent of [`Iterator::fold`] over a contiguous segment132/// from a storage.133///134/// # Safety135/// - `range` must be in `[0, storage::entity_count)` or None.136#[inline]137pub(super) unsafe fn fold_over_storage_range<B, Func>(138&mut self,139mut accum: B,140func: &mut Func,141storage: StorageId,142range: Option<Range<u32>>,143) -> B144where145Func: FnMut(B, D::Item<'w, 's>) -> B,146{147if self.cursor.is_dense {148// SAFETY: `self.cursor.is_dense` is true, so storage ids are guaranteed to be table ids.149let table_id = unsafe { storage.table_id };150// SAFETY: Matched table IDs are guaranteed to still exist.151let table = unsafe { self.tables.get(table_id).debug_checked_unwrap() };152153let range = range.unwrap_or(0..table.entity_count());154accum =155// SAFETY:156// - The fetched table matches both D and F157// - caller ensures `range` is within `[0, table.entity_count)`158// - The if block ensures that the query iteration is dense159unsafe { self.fold_over_table_range(accum, func, table, range) };160} else {161// SAFETY: `self.cursor.is_dense` is false, so storage ids are guaranteed to be archetype ids.162let archetype_id = unsafe { storage.archetype_id };163// SAFETY: Matched archetype IDs are guaranteed to still exist.164let archetype = unsafe { self.archetypes.get(archetype_id).debug_checked_unwrap() };165// SAFETY: Matched table IDs are guaranteed to still exist.166let table = unsafe { self.tables.get(archetype.table_id()).debug_checked_unwrap() };167168let range = range.unwrap_or(0..archetype.len());169170// When an archetype and its table have equal entity counts, dense iteration can be safely used.171// this leverages cache locality to optimize performance.172if table.entity_count() == archetype.len() {173accum =174// SAFETY:175// - The fetched archetype matches both D and F176// - The provided archetype and its' table have the same length.177// - caller ensures `range` is within `[0, archetype.len)`178// - The if block ensures that the query iteration is not dense.179unsafe { self.fold_over_dense_archetype_range(accum, func, archetype,range) };180} else {181accum =182// SAFETY:183// - The fetched archetype matches both D and F184// - caller ensures `range` is within `[0, archetype.len)`185// - The if block ensures that the query iteration is not dense.186unsafe { self.fold_over_archetype_range(accum, func, archetype,range) };187}188}189accum190}191192/// Executes the equivalent of [`Iterator::fold`] over a contiguous segment193/// from a table.194///195/// # Safety196/// - all `rows` must be in `[0, table.entity_count)`.197/// - `table` must match D and F198/// - The query iteration must be dense (i.e. `self.query_state.is_dense` must be true).199#[inline]200pub(super) unsafe fn fold_over_table_range<B, Func>(201&mut self,202mut accum: B,203func: &mut Func,204table: &'w Table,205rows: Range<u32>,206) -> B207where208Func: FnMut(B, D::Item<'w, 's>) -> B,209{210if table.is_empty() {211return accum;212}213214D::set_table(&mut self.cursor.fetch, &self.query_state.fetch_state, table);215F::set_table(216&mut self.cursor.filter,217&self.query_state.filter_state,218table,219);220221let entities = table.entities();222for row in rows {223// SAFETY: Caller assures `row` in range of the current archetype.224let entity = unsafe { entities.get_unchecked(row as usize) };225// SAFETY: This is from an exclusive range, so it can't be max.226let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(row)) };227228// SAFETY: set_table was called prior.229// Caller assures `row` in range of the current archetype.230let fetched = unsafe {231!F::filter_fetch(232&self.query_state.filter_state,233&mut self.cursor.filter,234*entity,235row,236)237};238if fetched {239continue;240}241242// SAFETY: set_table was called prior.243// Caller assures `row` in range of the current archetype.244if let Some(item) = D::fetch(245&self.query_state.fetch_state,246&mut self.cursor.fetch,247*entity,248row,249) {250accum = func(accum, item);251}252}253accum254}255256/// Executes the equivalent of [`Iterator::fold`] over a contiguous segment257/// from an archetype.258///259/// # Safety260/// - all `indices` must be in `[0, archetype.len())`.261/// - `archetype` must match D and F262/// - The query iteration must not be dense (i.e. `self.query_state.is_dense` must be false).263#[inline]264pub(super) unsafe fn fold_over_archetype_range<B, Func>(265&mut self,266mut accum: B,267func: &mut Func,268archetype: &'w Archetype,269indices: Range<u32>,270) -> B271where272Func: FnMut(B, D::Item<'w, 's>) -> B,273{274if archetype.is_empty() {275return accum;276}277let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();278D::set_archetype(279&mut self.cursor.fetch,280&self.query_state.fetch_state,281archetype,282table,283);284F::set_archetype(285&mut self.cursor.filter,286&self.query_state.filter_state,287archetype,288table,289);290291let entities = archetype.entities();292for index in indices {293// SAFETY: Caller assures `index` in range of the current archetype.294let archetype_entity = unsafe { entities.get_unchecked(index as usize) };295296// SAFETY: set_archetype was called prior.297// Caller assures `index` in range of the current archetype.298let fetched = unsafe {299!F::filter_fetch(300&self.query_state.filter_state,301&mut self.cursor.filter,302archetype_entity.id(),303archetype_entity.table_row(),304)305};306if fetched {307continue;308}309310// SAFETY: set_archetype was called prior, `index` is an archetype index in range of the current archetype311// Caller assures `index` in range of the current archetype.312if let Some(item) = unsafe {313D::fetch(314&self.query_state.fetch_state,315&mut self.cursor.fetch,316archetype_entity.id(),317archetype_entity.table_row(),318)319} {320accum = func(accum, item);321}322}323accum324}325326/// Executes the equivalent of [`Iterator::fold`] over a contiguous segment327/// from an archetype which has the same entity count as its table.328///329/// # Safety330/// - all `indices` must be in `[0, archetype.len())`.331/// - `archetype` must match D and F332/// - `archetype` must have the same length as its table.333/// - The query iteration must not be dense (i.e. `self.query_state.is_dense` must be false).334#[inline]335pub(super) unsafe fn fold_over_dense_archetype_range<B, Func>(336&mut self,337mut accum: B,338func: &mut Func,339archetype: &'w Archetype,340rows: Range<u32>,341) -> B342where343Func: FnMut(B, D::Item<'w, 's>) -> B,344{345if archetype.is_empty() {346return accum;347}348let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();349debug_assert!(350archetype.len() == table.entity_count(),351"archetype and its table must have the same length. "352);353354D::set_archetype(355&mut self.cursor.fetch,356&self.query_state.fetch_state,357archetype,358table,359);360F::set_archetype(361&mut self.cursor.filter,362&self.query_state.filter_state,363archetype,364table,365);366let entities = table.entities();367for row in rows {368// SAFETY: Caller assures `row` in range of the current archetype.369let entity = unsafe { *entities.get_unchecked(row as usize) };370// SAFETY: This is from an exclusive range, so it can't be max.371let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(row)) };372373// SAFETY: set_table was called prior.374// Caller assures `row` in range of the current archetype.375let filter_matched = unsafe {376F::filter_fetch(377&self.query_state.filter_state,378&mut self.cursor.filter,379entity,380row,381)382};383if !filter_matched {384continue;385}386387// SAFETY: set_table was called prior.388// Caller assures `row` in range of the current archetype.389if let Some(item) = D::fetch(390&self.query_state.fetch_state,391&mut self.cursor.fetch,392entity,393row,394) {395accum = func(accum, item);396}397}398accum399}400401/// Sorts all query items into a new iterator, using the query lens as a key.402///403/// This sort is stable (i.e., does not reorder equal elements).404///405/// This uses [`slice::sort`] internally.406///407/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).408/// This includes the allowed parameter type changes listed under [allowed transmutes].409/// However, the lens uses the filter of the original query when present.410///411/// The sort is not cached across system runs.412///413/// [allowed transmutes]: crate::system::Query#allowed-transmutes414///415/// # Panics416///417/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.418///419/// # Examples420/// ```rust421/// # use bevy_ecs::prelude::*;422/// # use std::{ops::{Deref, DerefMut}, iter::Sum};423/// #424/// # #[derive(Component)]425/// # struct PartMarker;426/// #427/// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]428/// # struct PartIndex(usize);429/// #430/// # #[derive(Component, Clone, Copy)]431/// # struct PartValue(f32);432/// #433/// # impl Deref for PartValue {434/// # type Target = f32;435/// #436/// # fn deref(&self) -> &Self::Target {437/// # &self.0438/// # }439/// # }440/// #441/// # #[derive(Component)]442/// # struct ParentValue(f32);443/// #444/// # impl Deref for ParentValue {445/// # type Target = f32;446/// #447/// # fn deref(&self) -> &Self::Target {448/// # &self.0449/// # }450/// # }451/// #452/// # impl DerefMut for ParentValue {453/// # fn deref_mut(&mut self) -> &mut Self::Target {454/// # &mut self.0455/// # }456/// # }457/// #458/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]459/// # struct Length(usize);460/// #461/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]462/// # struct Width(usize);463/// #464/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]465/// # struct Height(usize);466/// #467/// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]468/// # struct ParentEntity(Entity);469/// #470/// # #[derive(Component, Clone, Copy)]471/// # struct ChildPartCount(usize);472/// #473/// # impl Deref for ChildPartCount {474/// # type Target = usize;475/// #476/// # fn deref(&self) -> &Self::Target {477/// # &self.0478/// # }479/// # }480/// # let mut world = World::new();481/// // We can ensure that a query always returns in the same order.482/// fn system_1(query: Query<(Entity, &PartIndex)>) {483/// let parts: Vec<(Entity, &PartIndex)> = query.iter().sort::<&PartIndex>().collect();484/// }485///486/// // We can freely rearrange query components in the key.487/// fn system_2(query: Query<(&Length, &Width, &Height), With<PartMarker>>) {488/// for (length, width, height) in query.iter().sort::<(&Height, &Length, &Width)>() {489/// println!("height: {height:?}, width: {width:?}, length: {length:?}")490/// }491/// }492///493/// // We can sort by Entity without including it in the original Query.494/// // Here, we match iteration orders between query iterators.495/// fn system_3(496/// part_query: Query<(&PartValue, &ParentEntity)>,497/// mut parent_query: Query<(&ChildPartCount, &mut ParentValue)>,498/// ) {499/// let part_values = &mut part_query500/// .into_iter()501/// .sort::<&ParentEntity>()502/// .map(|(&value, parent_entity)| *value);503///504/// for (&child_count, mut parent_value) in parent_query.iter_mut().sort::<Entity>() {505/// **parent_value = part_values.take(*child_count).sum();506/// }507/// }508/// #509/// # let mut schedule = Schedule::default();510/// # schedule.add_systems((system_1, system_2, system_3));511/// # schedule.run(&mut world);512/// ```513pub fn sort<L: ReadOnlyQueryData + 'w>(514self,515) -> QuerySortedIter<516'w,517's,518D,519F,520impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,521>522where523for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,524{525self.sort_impl::<L>(|keyed_query| keyed_query.sort())526}527528/// Sorts all query items into a new iterator, using the query lens as a key.529///530/// This sort is unstable (i.e., may reorder equal elements).531///532/// This uses [`slice::sort_unstable`] internally.533///534/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).535/// This includes the allowed parameter type changes listed under [allowed transmutes]..536/// However, the lens uses the filter of the original query when present.537///538/// The sort is not cached across system runs.539///540/// [allowed transmutes]: crate::system::Query#allowed-transmutes541///542/// # Panics543///544/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.545///546/// # Example547/// ```548/// # use bevy_ecs::prelude::*;549/// #550/// # let mut world = World::new();551/// #552/// # #[derive(Component)]553/// # struct PartMarker;554/// #555/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]556/// enum Flying {557/// Enabled,558/// Disabled559/// };560///561/// // We perform an unstable sort by a Component with few values.562/// fn system_1(query: Query<&Flying, With<PartMarker>>) {563/// let part_values: Vec<&Flying> = query.iter().sort_unstable::<&Flying>().collect();564/// }565/// #566/// # let mut schedule = Schedule::default();567/// # schedule.add_systems((system_1));568/// # schedule.run(&mut world);569/// ```570pub fn sort_unstable<L: ReadOnlyQueryData + 'w>(571self,572) -> QuerySortedIter<573'w,574's,575D,576F,577impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,578>579where580for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,581{582self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())583}584585/// Sorts all query items into a new iterator with a comparator function over the query lens.586///587/// This sort is stable (i.e., does not reorder equal elements).588///589/// This uses [`slice::sort_by`] internally.590///591/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).592/// This includes the allowed parameter type changes listed under [allowed transmutes].593/// However, the lens uses the filter of the original query when present.594///595/// The sort is not cached across system runs.596///597/// [allowed transmutes]: crate::system::Query#allowed-transmutes598///599/// # Panics600///601/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.602///603/// # Example604/// ```605/// # use bevy_ecs::prelude::*;606/// # use std::ops::Deref;607/// #608/// # impl Deref for PartValue {609/// # type Target = f32;610/// #611/// # fn deref(&self) -> &Self::Target {612/// # &self.0613/// # }614/// # }615/// #616/// # let mut world = World::new();617/// #618/// #[derive(Component)]619/// struct PartValue(f32);620///621/// // We can use a cmp function on components do not implement Ord.622/// fn system_1(query: Query<&PartValue>) {623/// // Sort part values according to `f32::total_comp`.624/// let part_values: Vec<&PartValue> = query625/// .iter()626/// .sort_by::<&PartValue>(|value_1, value_2| value_1.total_cmp(*value_2))627/// .collect();628/// }629/// #630/// # let mut schedule = Schedule::default();631/// # schedule.add_systems((system_1));632/// # schedule.run(&mut world);633/// ```634pub fn sort_by<L: ReadOnlyQueryData + 'w>(635self,636mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,637) -> QuerySortedIter<638'w,639's,640D,641F,642impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,643> {644self.sort_impl::<L>(move |keyed_query| {645keyed_query.sort_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));646})647}648649/// Sorts all query items into a new iterator with a comparator function over the query lens.650///651/// This sort is unstable (i.e., may reorder equal elements).652///653/// This uses [`slice::sort_unstable_by`] internally.654///655/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).656/// This includes the allowed parameter type changes listed under [allowed transmutes].657/// However, the lens uses the filter of the original query when present.658///659/// The sort is not cached across system runs.660///661/// [allowed transmutes]: crate::system::Query#allowed-transmutes662///663/// # Panics664///665/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.666pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(667self,668mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,669) -> QuerySortedIter<670'w,671's,672D,673F,674impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,675> {676self.sort_impl::<L>(move |keyed_query| {677keyed_query.sort_unstable_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));678})679}680681/// Sorts all query items into a new iterator with a key extraction function over the query lens.682///683/// This sort is stable (i.e., does not reorder equal elements).684///685/// This uses [`slice::sort_by_key`] internally.686///687/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).688/// This includes the allowed parameter type changes listed under [allowed transmutes].689/// However, the lens uses the filter of the original query when present.690///691/// The sort is not cached across system runs.692///693/// [allowed transmutes]: crate::system::Query#allowed-transmutes694///695/// # Panics696///697/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.698///699/// # Example700/// ```701/// # use bevy_ecs::prelude::*;702/// # use std::ops::Deref;703/// #704/// # #[derive(Component)]705/// # struct PartMarker;706/// #707/// # impl Deref for PartValue {708/// # type Target = f32;709/// #710/// # fn deref(&self) -> &Self::Target {711/// # &self.0712/// # }713/// # }714/// #715/// # let mut world = World::new();716/// #717/// #[derive(Component)]718/// struct AvailableMarker;719///720/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]721/// enum Rarity {722/// Common,723/// Rare,724/// Epic,725/// Legendary726/// };727///728/// #[derive(Component)]729/// struct PartValue(f32);730///731/// // We can sort with the internals of components that do not implement Ord.732/// fn system_1(query: Query<(Entity, &PartValue)>) {733/// // Sort by the sines of the part values.734/// let parts: Vec<(Entity, &PartValue)> = query735/// .iter()736/// .sort_by_key::<&PartValue, _>(|value| value.sin() as usize)737/// .collect();738/// }739///740/// // We can define our own custom comparison functions over an EntityRef.741/// fn system_2(query: Query<EntityRef, With<PartMarker>>) {742/// // Sort by whether parts are available and their rarity.743/// // We want the available legendaries to come first, so we reverse the iterator.744/// let parts: Vec<EntityRef> = query.iter()745/// .sort_by_key::<EntityRef, _>(|entity_ref| {746/// (747/// entity_ref.contains::<AvailableMarker>(),748/// entity_ref.get::<Rarity>().copied()749/// )750/// })751/// .rev()752/// .collect();753/// }754/// # let mut schedule = Schedule::default();755/// # schedule.add_systems((system_1, system_2));756/// # schedule.run(&mut world);757/// ```758pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(759self,760mut f: impl FnMut(&L::Item<'_, '_>) -> K,761) -> QuerySortedIter<762'w,763's,764D,765F,766impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,767>768where769K: Ord,770{771self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_key(|(lens, _)| f(lens)))772}773774/// Sorts all query items into a new iterator with a key extraction function over the query lens.775///776/// This sort is unstable (i.e., may reorder equal elements).777///778/// This uses [`slice::sort_unstable_by_key`] internally.779///780/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).781/// This includes the allowed parameter type changes listed under [allowed transmutes].782/// However, the lens uses the filter of the original query when present.783///784/// The sort is not cached across system runs.785///786/// [allowed transmutes]: crate::system::Query#allowed-transmutes787///788/// # Panics789///790/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.791pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(792self,793mut f: impl FnMut(&L::Item<'_, '_>) -> K,794) -> QuerySortedIter<795'w,796's,797D,798F,799impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,800>801where802K: Ord,803{804self.sort_impl::<L>(move |keyed_query| {805keyed_query.sort_unstable_by_key(|(lens, _)| f(lens));806})807}808809/// Sort all query items into a new iterator with a key extraction function over the query lens.810///811/// This sort is stable (i.e., does not reorder equal elements).812///813/// This uses [`slice::sort_by_cached_key`] internally.814///815/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).816/// This includes the allowed parameter type changes listed under [allowed transmutes].817/// However, the lens uses the filter of the original query when present.818///819/// The sort is not cached across system runs.820///821/// [allowed transmutes]: crate::system::Query#allowed-transmutes822///823/// # Panics824///825/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.826pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(827self,828mut f: impl FnMut(&L::Item<'_, '_>) -> K,829) -> QuerySortedIter<830'w,831's,832D,833F,834impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,835>836where837K: Ord,838{839self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_cached_key(|(lens, _)| f(lens)))840}841842/// Shared implementation for the various `sort` methods.843/// This uses the lens to collect the items for sorting, but delegates the actual sorting to the provided closure.844///845/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).846/// This includes the allowed parameter type changes listed under [allowed transmutes].847/// However, the lens uses the filter of the original query when present.848///849/// The sort is not cached across system runs.850///851/// [allowed transmutes]: crate::system::Query#allowed-transmutes852///853/// # Panics854///855/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.856fn sort_impl<L: ReadOnlyQueryData + 'w>(857self,858f: impl FnOnce(&mut Vec<(L::Item<'_, '_>, NeutralOrd<Entity>)>),859) -> QuerySortedIter<860'w,861's,862D,863F,864impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,865> {866// On the first successful iteration of `QueryIterationCursor`, `archetype_entities` or `table_entities`867// will be set to a non-zero value. The correctness of this method relies on this.868// I.e. this sort method will execute if and only if `next` on `QueryIterationCursor` of a869// non-empty `QueryIter` has not yet been called. When empty, this sort method will not panic.870if !self.cursor.archetype_entities.is_empty() || !self.cursor.table_entities.is_empty() {871panic!("it is not valid to call sort() after next()")872}873874let world = self.world;875876let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);877878// SAFETY:879// `self.world` has permission to access the required components.880// The original query iter has not been iterated on, so no items are aliased from it.881// `QueryIter::new` ensures `world` is the same one used to initialize `query_state`.882let query_lens = unsafe { query_lens_state.query_unchecked_manual(world) }.into_iter();883let mut keyed_query: Vec<_> = query_lens884.map(|(key, entity)| (key, NeutralOrd(entity)))885.collect();886f(&mut keyed_query);887let entity_iter = keyed_query888.into_iter()889.map(|(.., entity)| entity.0)890.collect::<Vec<_>>()891.into_iter();892// SAFETY:893// `self.world` has permission to access the required components.894// Each lens query item is dropped before the respective actual query item is accessed.895unsafe {896QuerySortedIter::new(897world,898self.query_state,899entity_iter,900world.last_change_tick(),901world.change_tick(),902)903}904}905}906907impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F> {908type Item = D::Item<'w, 's>;909910#[inline(always)]911fn next(&mut self) -> Option<Self::Item> {912// SAFETY:913// `tables` and `archetypes` belong to the same world that the cursor was initialized for.914// `query_state` is the state that was passed to `QueryIterationCursor::init`.915unsafe {916self.cursor917.next(self.tables, self.archetypes, self.query_state)918}919}920921fn size_hint(&self) -> (usize, Option<usize>) {922let max_size = self.cursor.max_remaining(self.tables, self.archetypes);923let archetype_query = D::IS_ARCHETYPAL && F::IS_ARCHETYPAL;924let min_size = if archetype_query { max_size } else { 0 };925(min_size as usize, Some(max_size as usize))926}927928#[inline]929fn fold<B, Func>(mut self, init: B, mut func: Func) -> B930where931Func: FnMut(B, Self::Item) -> B,932{933let mut accum = init;934// Empty any remaining uniterated values from the current table/archetype935while self.cursor.current_row != self.cursor.current_len {936let Some(item) = self.next() else { break };937accum = func(accum, item);938}939940for id in self.cursor.storage_id_iter.clone().copied() {941// SAFETY:942// - The range(None) is equivalent to [0, storage.entity_count)943accum = unsafe { self.fold_over_storage_range(accum, &mut func, id, None) };944}945accum946}947}948949// This is correct as [`QueryIter`] always returns `None` once exhausted.950impl<'w, 's, D: QueryData, F: QueryFilter> FusedIterator for QueryIter<'w, 's, D, 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, Entity, 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, EntityRef<'_>, F> {}957958// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.959unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator for QueryIter<'w, 's, EntityMut<'_>, F> {}960961// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.962unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator963for QueryIter<'w, 's, FilteredEntityRef<'_, '_>, F>964{965}966967// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.968unsafe impl<'w, 's, F: QueryFilter> EntitySetIterator969for QueryIter<'w, 's, FilteredEntityMut<'_, '_>, F>970{971}972973// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.974unsafe impl<'w, 's, F: QueryFilter, B: Bundle> EntitySetIterator975for QueryIter<'w, 's, EntityRefExcept<'_, '_, B>, F>976{977}978979// SAFETY: [`QueryIter`] is guaranteed to return every matching entity once and only once.980unsafe impl<'w, 's, F: QueryFilter, B: Bundle> EntitySetIterator981for QueryIter<'w, 's, EntityMutExcept<'_, '_, B>, F>982{983}984985impl<'w, 's, D: QueryData, F: QueryFilter> Debug for QueryIter<'w, 's, D, F> {986fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {987f.debug_struct("QueryIter").finish()988}989}990991impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Clone for QueryIter<'w, 's, D, F> {992fn clone(&self) -> Self {993self.remaining()994}995}996997/// Iterator for contiguous chunks of memory998pub struct QueryContiguousIter<'w, 's, D: ContiguousQueryData, F: ArchetypeFilter> {999tables: &'w Tables,1000storage_id_iter: core::slice::Iter<'s, StorageId>,1001query_state: &'s QueryState<D, F>,1002fetch: D::Fetch<'w>,1003// NOTE: no need for F::Fetch because it always returns true1004}10051006impl<'w, 's, D: ContiguousQueryData, F: ArchetypeFilter> QueryContiguousIter<'w, 's, D, F> {1007/// # Safety1008/// - `world` must have permission to access any of the components registered in `query_state`.1009/// - `world` must be the same one used to initialize `query_state`.1010pub(crate) unsafe fn new(1011world: UnsafeWorldCell<'w>,1012query_state: &'s QueryState<D, F>,1013last_run: Tick,1014this_run: Tick,1015) -> Option<Self> {1016query_state.is_dense.then(|| Self {1017// SAFETY: We only access table data that has been registered in `query_state`1018tables: unsafe { &world.storages().tables },1019storage_id_iter: query_state.matched_storage_ids.iter(),1020// SAFETY: The invariants are upheld by the caller.1021fetch: unsafe { D::init_fetch(world, &query_state.fetch_state, last_run, this_run) },1022query_state,1023})1024}1025}10261027impl<'w, 's, D: ContiguousQueryData, F: ArchetypeFilter> Iterator1028for QueryContiguousIter<'w, 's, D, F>1029{1030type Item = D::Contiguous<'w, 's>;10311032#[inline(always)]1033fn next(&mut self) -> Option<Self::Item> {1034loop {1035// SAFETY: Query is dense1036let table_id = unsafe { self.storage_id_iter.next()?.table_id };1037// SAFETY: `table_id` was returned by `self.storage_id_iter` which always returns a1038// valid id1039let table = unsafe { self.tables.get(table_id).debug_checked_unwrap() };1040if table.is_empty() {1041continue;1042}1043// SAFETY:1044// - `table` is from the same world as `self.query_state` (`self.storage_id_iter` is1045// from the same world as `self.query_state`, see [`Self::new`])1046// - `self.fetch` was initialized with `self.query_state` (in [`Self::new`])1047unsafe {1048D::set_table(&mut self.fetch, &self.query_state.fetch_state, table);1049}10501051// no filtering because `F` implements `ArchetypeFilter` which ensures that `QueryFilter::fetch`1052// always returns true10531054// SAFETY:1055// - [`D::set_table`] is executed prior.1056// - `table.entities()` return a valid entity array1057// - the caller of [`Self::new`] ensures that the world has permission to access any of1058// the components registered in `self.query_state`1059let item = unsafe {1060D::fetch_contiguous(1061&self.query_state.fetch_state,1062&mut self.fetch,1063table.entities(),1064)1065};10661067return Some(item);1068}1069}10701071fn size_hint(&self) -> (usize, Option<usize>) {1072(0, self.storage_id_iter.size_hint().1)1073}1074}10751076// [`QueryIterationCursor::next_contiguous`] always returns None when exhausted1077impl<'w, 's, D: ContiguousQueryData, F: ArchetypeFilter> FusedIterator1078for QueryContiguousIter<'w, 's, D, F>1079{1080}10811082/// An [`Iterator`] over sorted query results of a [`Query`](crate::system::Query).1083///1084/// This struct is created by the [`QueryIter::sort`], [`QueryIter::sort_unstable`],1085/// [`QueryIter::sort_by`], [`QueryIter::sort_unstable_by`], [`QueryIter::sort_by_key`],1086/// [`QueryIter::sort_unstable_by_key`], and [`QueryIter::sort_by_cached_key`] methods.1087pub struct QuerySortedIter<'w, 's, D: QueryData, F: QueryFilter, I>1088where1089I: Iterator<Item = Entity>,1090{1091entity_iter: I,1092entities: &'w Entities,1093tables: &'w Tables,1094archetypes: &'w Archetypes,1095fetch: D::Fetch<'w>,1096query_state: &'s QueryState<D, F>,1097}10981099impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> QuerySortedIter<'w, 's, D, F, I>1100where1101I: Iterator<Item = Entity>,1102{1103/// # Safety1104/// - `world` must have permission to access any of the components registered in `query_state`.1105/// - `world` must be the same one used to initialize `query_state`.1106/// - `entity_list` must only contain unique entities or be empty.1107pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(1108world: UnsafeWorldCell<'w>,1109query_state: &'s QueryState<D, F>,1110entity_list: EntityList,1111last_run: Tick,1112this_run: Tick,1113) -> QuerySortedIter<'w, 's, D, F, I> {1114let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);1115QuerySortedIter {1116query_state,1117entities: world.entities(),1118archetypes: world.archetypes(),1119// SAFETY: We only access table data that has been registered in `query_state`.1120// This means `world` has permission to access the data we use.1121tables: &world.storages().tables,1122fetch,1123entity_iter: entity_list.into_iter(),1124}1125}11261127/// # Safety1128/// `entity` must stem from `self.entity_iter`, and not have been passed before.1129#[inline(always)]1130unsafe fn fetch_next(&mut self, entity: Entity) -> Option<D::Item<'w, 's>> {1131let (location, archetype, table);1132// SAFETY:1133// `tables` and `archetypes` belong to the same world that the [`QueryIter`]1134// was initialized for.1135unsafe {1136location = self.entities.get_spawned(entity).debug_checked_unwrap();1137archetype = self1138.archetypes1139.get(location.archetype_id)1140.debug_checked_unwrap();1141table = self.tables.get(location.table_id).debug_checked_unwrap();1142}11431144// SAFETY: `archetype` is from the world that `fetch` was created for,1145// `fetch_state` is the state that `fetch` was initialized with1146unsafe {1147D::set_archetype(1148&mut self.fetch,1149&self.query_state.fetch_state,1150archetype,1151table,1152);1153}11541155// The entity list has already been filtered by the query lens, so we forego filtering here.1156// SAFETY:1157// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype1158// - fetch is only called once for each entity.1159unsafe {1160D::fetch(1161&self.query_state.fetch_state,1162&mut self.fetch,1163entity,1164location.table_row,1165)1166}1167}1168}11691170impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> Iterator1171for QuerySortedIter<'w, 's, D, F, I>1172where1173I: Iterator<Item = Entity>,1174{1175type Item = D::Item<'w, 's>;11761177#[inline(always)]1178fn next(&mut self) -> Option<Self::Item> {1179while let Some(entity) = self.entity_iter.next() {1180// SAFETY: `entity` is passed from `entity_iter` the first time.1181if let Some(item) = unsafe { self.fetch_next(entity) } {1182return Some(item);1183}1184}1185None1186}11871188fn size_hint(&self) -> (usize, Option<usize>) {1189let (min_size, max_size) = self.entity_iter.size_hint();1190let archetype_query = D::IS_ARCHETYPAL;1191let min_size = if archetype_query { min_size } else { 0 };1192(min_size, max_size)1193}1194}11951196impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> DoubleEndedIterator1197for QuerySortedIter<'w, 's, D, F, I>1198where1199I: DoubleEndedIterator<Item = Entity>,1200{1201#[inline(always)]1202fn next_back(&mut self) -> Option<Self::Item> {1203while let Some(entity) = self.entity_iter.next_back() {1204// SAFETY: `entity` is passed from `entity_iter` the first time.1205if let Some(item) = unsafe { self.fetch_next(entity) } {1206return Some(item);1207}1208}1209None1210}1211}12121213impl<D: ArchetypeQueryData, F: QueryFilter, I: ExactSizeIterator<Item = Entity>> ExactSizeIterator1214for QuerySortedIter<'_, '_, D, F, I>1215{1216}12171218// This is correct as [`QuerySortedIter`] returns `None` once exhausted if `entity_iter` does.1219impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> FusedIterator1220for QuerySortedIter<'w, 's, D, F, I>1221where1222I: FusedIterator<Item = Entity>,1223{1224}12251226// SAFETY:1227// `I` stems from a collected and sorted `EntitySetIterator` ([`QueryIter`]).1228// Fetching unique entities maintains uniqueness.1229unsafe impl<'w, 's, F: QueryFilter, I: Iterator<Item = Entity>> EntitySetIterator1230for QuerySortedIter<'w, 's, Entity, F, I>1231{1232}12331234impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> Debug1235for QuerySortedIter<'w, 's, D, F, I>1236{1237fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {1238f.debug_struct("QuerySortedIter").finish()1239}1240}12411242/// An [`Iterator`] over the query items generated from an iterator of [`Entity`]s.1243///1244/// Items are returned in the order of the provided iterator.1245/// Entities that don't match the query are skipped.1246///1247/// 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.1248pub struct QueryManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>1249{1250world: UnsafeWorldCell<'w>,1251entity_iter: I,1252entities: &'w Entities,1253tables: &'w Tables,1254archetypes: &'w Archetypes,1255fetch: D::Fetch<'w>,1256filter: F::Fetch<'w>,1257query_state: &'s QueryState<D, F>,1258}12591260impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>1261QueryManyIter<'w, 's, D, F, I>1262{1263/// # Safety1264/// - `world` must have permission to access any of the components registered in `query_state`.1265/// - `world` must be the same one used to initialize `query_state`.1266pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(1267world: UnsafeWorldCell<'w>,1268query_state: &'s QueryState<D, F>,1269entity_list: EntityList,1270last_run: Tick,1271this_run: Tick,1272) -> QueryManyIter<'w, 's, D, F, I> {1273let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);1274let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);1275QueryManyIter {1276world,1277query_state,1278entities: world.entities(),1279archetypes: world.archetypes(),1280// SAFETY: We only access table data that has been registered in `query_state`.1281// This means `world` has permission to access the data we use.1282tables: &world.storages().tables,1283fetch,1284filter,1285entity_iter: entity_list.into_iter(),1286}1287}12881289/// # Safety1290/// All arguments must stem from the same valid `QueryManyIter`.1291///1292/// The lifetime here is not restrictive enough for Fetch with &mut access,1293/// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple1294/// references to the same component, leading to unique reference aliasing.1295///1296/// It is always safe for shared access.1297#[inline(always)]1298unsafe fn fetch_next_aliased_unchecked(1299entity_iter: impl Iterator<Item: EntityEquivalent>,1300entities: &'w Entities,1301tables: &'w Tables,1302archetypes: &'w Archetypes,1303fetch: &mut D::Fetch<'w>,1304filter: &mut F::Fetch<'w>,1305query_state: &'s QueryState<D, F>,1306) -> Option<D::Item<'w, 's>> {1307for entity_borrow in entity_iter {1308let entity = entity_borrow.entity();1309let Ok(location) = entities.get_spawned(entity) else {1310continue;1311};13121313if !query_state1314.matched_archetypes1315.contains(location.archetype_id.index())1316{1317continue;1318}13191320let archetype = archetypes.get(location.archetype_id).debug_checked_unwrap();1321let table = tables.get(location.table_id).debug_checked_unwrap();13221323// SAFETY: `archetype` is from the world that `fetch/filter` were created for,1324// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with1325unsafe {1326D::set_archetype(fetch, &query_state.fetch_state, archetype, table);1327}1328// SAFETY: `table` is from the world that `fetch/filter` were created for,1329// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with1330unsafe {1331F::set_archetype(filter, &query_state.filter_state, archetype, table);1332}13331334// SAFETY: set_archetype was called prior.1335// `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`d1336if unsafe {1337F::filter_fetch(1338&query_state.filter_state,1339filter,1340entity,1341location.table_row,1342)1343} {1344// SAFETY:1345// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype1346// - fetch is only called once for each entity.1347let item = unsafe {1348D::fetch(&query_state.fetch_state, fetch, entity, location.table_row)1349};1350if let Some(item) = item {1351return Some(item);1352}1353}1354}1355None1356}13571358/// Get next result from the query1359#[inline(always)]1360pub fn fetch_next(&mut self) -> Option<D::Item<'_, 's>> {1361// SAFETY:1362// All arguments stem from self.1363// We are limiting the returned reference to self,1364// making sure this method cannot be called multiple times without getting rid1365// of any previously returned unique references first, thus preventing aliasing.1366unsafe {1367Self::fetch_next_aliased_unchecked(1368&mut self.entity_iter,1369self.entities,1370self.tables,1371self.archetypes,1372&mut self.fetch,1373&mut self.filter,1374self.query_state,1375)1376.map(D::shrink)1377}1378}13791380/// Sorts all query items into a new iterator, using the query lens as a key.1381///1382/// This sort is stable (i.e., does not reorder equal elements).1383///1384/// This uses [`slice::sort`] internally.1385///1386/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1387/// This includes the allowed parameter type changes listed under [allowed transmutes].1388/// However, the lens uses the filter of the original query when present.1389///1390/// The sort is not cached across system runs.1391///1392/// [allowed transmutes]: crate::system::Query#allowed-transmutes1393///1394/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1395/// called on [`QueryManyIter`] before.1396///1397/// # Examples1398/// ```rust1399/// # use bevy_ecs::prelude::*;1400/// # use std::{ops::{Deref, DerefMut}, iter::Sum};1401/// #1402/// # #[derive(Component)]1403/// # struct PartMarker;1404/// #1405/// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]1406/// # struct PartIndex(usize);1407/// #1408/// # #[derive(Component, Clone, Copy)]1409/// # struct PartValue(usize);1410/// #1411/// # impl Deref for PartValue {1412/// # type Target = usize;1413/// #1414/// # fn deref(&self) -> &Self::Target {1415/// # &self.01416/// # }1417/// # }1418/// #1419/// # impl DerefMut for PartValue {1420/// # fn deref_mut(&mut self) -> &mut Self::Target {1421/// # &mut self.01422/// # }1423/// # }1424/// #1425/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]1426/// # struct Length(usize);1427/// #1428/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]1429/// # struct Width(usize);1430/// #1431/// # #[derive(Component, Debug, PartialEq, Eq, PartialOrd, Ord)]1432/// # struct Height(usize);1433/// #1434/// # #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]1435/// # struct ParentEntity(Entity);1436/// #1437/// # let mut world = World::new();1438/// // We can ensure that a query always returns in the same order.1439/// fn system_1(query: Query<(Entity, &PartIndex)>) {1440/// # let entity_list: Vec<Entity> = Vec::new();1441/// let parts: Vec<(Entity, &PartIndex)> = query.iter_many(entity_list).sort::<&PartIndex>().collect();1442/// }1443///1444/// // We can freely rearrange query components in the key.1445/// fn system_2(query: Query<(&Length, &Width, &Height), With<PartMarker>>) {1446/// # let entity_list: Vec<Entity> = Vec::new();1447/// for (length, width, height) in query.iter_many(entity_list).sort::<(&Height, &Length, &Width)>() {1448/// println!("height: {height:?}, width: {width:?}, length: {length:?}")1449/// }1450/// }1451///1452/// // You can use `fetch_next_back` to obtain mutable references in reverse order.1453/// fn system_3(1454/// mut query: Query<&mut PartValue>,1455/// ) {1456/// # let entity_list: Vec<Entity> = Vec::new();1457/// // We need to collect the internal iterator before iterating mutably1458/// let mut parent_query_iter = query.iter_many_mut(entity_list)1459/// .sort::<Entity>();1460///1461/// let mut scratch_value = 0;1462/// while let Some(mut part_value) = parent_query_iter.fetch_next_back()1463/// {1464/// // some order-dependent operation, here bitwise XOR1465/// **part_value ^= scratch_value;1466/// scratch_value = **part_value;1467/// }1468/// }1469/// #1470/// # let mut schedule = Schedule::default();1471/// # schedule.add_systems((system_1, system_2, system_3));1472/// # schedule.run(&mut world);1473/// ```1474pub fn sort<L: ReadOnlyQueryData + 'w>(1475self,1476) -> QuerySortedManyIter<1477'w,1478's,1479D,1480F,1481impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1482>1483where1484for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,1485{1486self.sort_impl::<L>(|keyed_query| keyed_query.sort())1487}14881489/// Sorts all query items into a new iterator, using the query lens as a key.1490///1491/// This sort is unstable (i.e., may reorder equal elements).1492///1493/// This uses [`slice::sort_unstable`] internally.1494///1495/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1496/// This includes the allowed parameter type changes listed under [allowed transmutes]..1497/// However, the lens uses the filter of the original query when present.1498///1499/// The sort is not cached across system runs.1500///1501/// [allowed transmutes]: crate::system::Query#allowed-transmutes1502///1503/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1504/// called on [`QueryManyIter`] before.1505///1506/// # Example1507/// ```1508/// # use bevy_ecs::prelude::*;1509/// #1510/// # let mut world = World::new();1511/// #1512/// # #[derive(Component)]1513/// # struct PartMarker;1514/// #1515/// # let entity_list: Vec<Entity> = Vec::new();1516/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord)]1517/// enum Flying {1518/// Enabled,1519/// Disabled1520/// };1521///1522/// // We perform an unstable sort by a Component with few values.1523/// fn system_1(query: Query<&Flying, With<PartMarker>>) {1524/// # let entity_list: Vec<Entity> = Vec::new();1525/// let part_values: Vec<&Flying> = query.iter_many(entity_list).sort_unstable::<&Flying>().collect();1526/// }1527/// #1528/// # let mut schedule = Schedule::default();1529/// # schedule.add_systems((system_1));1530/// # schedule.run(&mut world);1531/// ```1532pub fn sort_unstable<L: ReadOnlyQueryData + 'w>(1533self,1534) -> QuerySortedManyIter<1535'w,1536's,1537D,1538F,1539impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1540>1541where1542for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,1543{1544self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())1545}15461547/// Sorts all query items into a new iterator with a comparator function over the query lens.1548///1549/// This sort is stable (i.e., does not reorder equal elements).1550///1551/// This uses [`slice::sort_by`] internally.1552///1553/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1554/// This includes the allowed parameter type changes listed under [allowed transmutes].1555/// However, the lens uses the filter of the original query when present.1556///1557/// The sort is not cached across system runs.1558///1559/// [allowed transmutes]: crate::system::Query#allowed-transmutes1560///1561/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1562/// called on [`QueryManyIter`] before.1563///1564/// # Example1565/// ```1566/// # use bevy_ecs::prelude::*;1567/// # use std::ops::Deref;1568/// #1569/// # impl Deref for PartValue {1570/// # type Target = f32;1571/// #1572/// # fn deref(&self) -> &Self::Target {1573/// # &self.01574/// # }1575/// # }1576/// #1577/// # let mut world = World::new();1578/// # let entity_list: Vec<Entity> = Vec::new();1579/// #1580/// #[derive(Component)]1581/// struct PartValue(f32);1582///1583/// // We can use a cmp function on components do not implement Ord.1584/// fn system_1(query: Query<&PartValue>) {1585/// # let entity_list: Vec<Entity> = Vec::new();1586/// // Sort part values according to `f32::total_comp`.1587/// let part_values: Vec<&PartValue> = query1588/// .iter_many(entity_list)1589/// .sort_by::<&PartValue>(|value_1, value_2| value_1.total_cmp(*value_2))1590/// .collect();1591/// }1592/// #1593/// # let mut schedule = Schedule::default();1594/// # schedule.add_systems((system_1));1595/// # schedule.run(&mut world);1596/// ```1597pub fn sort_by<L: ReadOnlyQueryData + 'w>(1598self,1599mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,1600) -> QuerySortedManyIter<1601'w,1602's,1603D,1604F,1605impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1606> {1607self.sort_impl::<L>(move |keyed_query| {1608keyed_query.sort_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));1609})1610}16111612/// Sorts all query items into a new iterator with a comparator function over the query lens.1613///1614/// This sort is unstable (i.e., may reorder equal elements).1615///1616/// This uses [`slice::sort_unstable_by`] internally.1617///1618/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1619/// This includes the allowed parameter type changes listed under [allowed transmutes].1620/// However, the lens uses the filter of the original query when present.1621///1622/// The sort is not cached across system runs.1623///1624/// [allowed transmutes]: crate::system::Query#allowed-transmutes1625///1626/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1627/// called on [`QueryManyIter`] before.1628pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(1629self,1630mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,1631) -> QuerySortedManyIter<1632'w,1633's,1634D,1635F,1636impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1637> {1638self.sort_impl::<L>(move |keyed_query| {1639keyed_query.sort_unstable_by(|(key_1, _), (key_2, _)| compare(key_1, key_2));1640})1641}16421643/// Sorts all query items into a new iterator with a key extraction function over the query lens.1644///1645/// This sort is stable (i.e., does not reorder equal elements).1646///1647/// This uses [`slice::sort_by_key`] internally.1648///1649/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1650/// This includes the allowed parameter type changes listed under [allowed transmutes].1651/// However, the lens uses the filter of the original query when present.1652///1653/// The sort is not cached across system runs.1654///1655/// [allowed transmutes]: crate::system::Query#allowed-transmutes1656///1657/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1658/// called on [`QueryManyIter`] before.1659///1660/// # Example1661/// ```1662/// # use bevy_ecs::prelude::*;1663/// # use std::ops::Deref;1664/// #1665/// # #[derive(Component)]1666/// # struct PartMarker;1667/// #1668/// # impl Deref for PartValue {1669/// # type Target = f32;1670/// #1671/// # fn deref(&self) -> &Self::Target {1672/// # &self.01673/// # }1674/// # }1675/// #1676/// # let mut world = World::new();1677/// # let entity_list: Vec<Entity> = Vec::new();1678/// #1679/// #[derive(Component)]1680/// struct AvailableMarker;1681///1682/// #[derive(Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]1683/// enum Rarity {1684/// Common,1685/// Rare,1686/// Epic,1687/// Legendary1688/// };1689///1690/// #[derive(Component)]1691/// struct PartValue(f32);1692///1693/// // We can sort with the internals of components that do not implement Ord.1694/// fn system_1(query: Query<(Entity, &PartValue)>) {1695/// # let entity_list: Vec<Entity> = Vec::new();1696/// // Sort by the sines of the part values.1697/// let parts: Vec<(Entity, &PartValue)> = query1698/// .iter_many(entity_list)1699/// .sort_by_key::<&PartValue, _>(|value| value.sin() as usize)1700/// .collect();1701/// }1702///1703/// // We can define our own custom comparison functions over an EntityRef.1704/// fn system_2(query: Query<EntityRef, With<PartMarker>>) {1705/// # let entity_list: Vec<Entity> = Vec::new();1706/// // Sort by whether parts are available and their rarity.1707/// // We want the available legendaries to come first, so we reverse the iterator.1708/// let parts: Vec<EntityRef> = query.iter_many(entity_list)1709/// .sort_by_key::<EntityRef, _>(|entity_ref| {1710/// (1711/// entity_ref.contains::<AvailableMarker>(),1712// entity_ref.get::<Rarity>().copied()1713/// )1714/// })1715/// .rev()1716/// .collect();1717/// }1718/// # let mut schedule = Schedule::default();1719/// # schedule.add_systems((system_1, system_2));1720/// # schedule.run(&mut world);1721/// ```1722pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(1723self,1724mut f: impl FnMut(&L::Item<'_, '_>) -> K,1725) -> QuerySortedManyIter<1726'w,1727's,1728D,1729F,1730impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1731>1732where1733K: Ord,1734{1735self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_key(|(lens, _)| f(lens)))1736}17371738/// Sorts all query items into a new iterator with a key extraction function over the query lens.1739///1740/// This sort is unstable (i.e., may reorder equal elements).1741///1742/// This uses [`slice::sort_unstable_by_key`] internally.1743///1744/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1745/// This includes the allowed parameter type changes listed under [allowed transmutes].1746/// However, the lens uses the filter of the original query when present.1747///1748/// The sort is not cached across system runs.1749///1750/// [allowed transmutes]: crate::system::Query#allowed-transmutes1751///1752/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1753/// called on [`QueryManyIter`] before.1754pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(1755self,1756mut f: impl FnMut(&L::Item<'_, '_>) -> K,1757) -> QuerySortedManyIter<1758'w,1759's,1760D,1761F,1762impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1763>1764where1765K: Ord,1766{1767self.sort_impl::<L>(move |keyed_query| {1768keyed_query.sort_unstable_by_key(|(lens, _)| f(lens));1769})1770}17711772/// Sort all query items into a new iterator with a key extraction function over the query lens.1773///1774/// This sort is stable (i.e., does not reorder equal elements).1775///1776/// This uses [`slice::sort_by_cached_key`] internally.1777///1778/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1779/// This includes the allowed parameter type changes listed under [allowed transmutes].1780/// However, the lens uses the filter of the original query when present.1781///1782/// The sort is not cached across system runs.1783///1784/// [allowed transmutes]: crate::system::Query#allowed-transmutes1785///1786/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1787/// called on [`QueryManyIter`] before.1788pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(1789self,1790mut f: impl FnMut(&L::Item<'_, '_>) -> K,1791) -> QuerySortedManyIter<1792'w,1793's,1794D,1795F,1796impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1797>1798where1799K: Ord,1800{1801self.sort_impl::<L>(move |keyed_query| keyed_query.sort_by_cached_key(|(lens, _)| f(lens)))1802}18031804/// Shared implementation for the various `sort` methods.1805/// This uses the lens to collect the items for sorting, but delegates the actual sorting to the provided closure.1806///1807/// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens).1808/// This includes the allowed parameter type changes listed under [allowed transmutes].1809/// However, the lens uses the filter of the original query when present.1810///1811/// The sort is not cached across system runs.1812///1813/// [allowed transmutes]: crate::system::Query#allowed-transmutes1814///1815/// Unlike the sort methods on [`QueryIter`], this does NOT panic if `next`/`fetch_next` has been1816/// called on [`QueryManyIter`] before.1817fn sort_impl<L: ReadOnlyQueryData + 'w>(1818self,1819f: impl FnOnce(&mut Vec<(L::Item<'_, '_>, NeutralOrd<Entity>)>),1820) -> QuerySortedManyIter<1821'w,1822's,1823D,1824F,1825impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,1826> {1827let world = self.world;18281829let query_lens_state = self.query_state.transmute_filtered::<(L, Entity), F>(world);18301831// SAFETY:1832// `self.world` has permission to access the required components.1833// The original query iter has not been iterated on, so no items are aliased from it.1834// `QueryIter::new` ensures `world` is the same one used to initialize `query_state`.1835let query_lens = unsafe { query_lens_state.query_unchecked_manual(world) }1836.iter_many_inner(self.entity_iter);1837let mut keyed_query: Vec<_> = query_lens1838.map(|(key, entity)| (key, NeutralOrd(entity)))1839.collect();1840f(&mut keyed_query);1841// Re-collect into a `Vec` to eagerly drop the lens items.1842// They must be dropped before `fetch_next` is called since they may alias1843// with other data items if there are duplicate entities in `entity_iter`.1844let entity_iter = keyed_query1845.into_iter()1846.map(|(.., entity)| entity.0)1847.collect::<Vec<_>>()1848.into_iter();1849// SAFETY:1850// `self.world` has permission to access the required components.1851// Each lens query item is dropped before the respective actual query item is accessed.1852unsafe {1853QuerySortedManyIter::new(1854world,1855self.query_state,1856entity_iter,1857world.last_change_tick(),1858world.change_tick(),1859)1860}1861}1862}18631864impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item: EntityEquivalent>>1865QueryManyIter<'w, 's, D, F, I>1866{1867/// Get next result from the back of the query1868#[inline(always)]1869pub fn fetch_next_back(&mut self) -> Option<D::Item<'_, 's>> {1870// SAFETY:1871// All arguments stem from self.1872// We are limiting the returned reference to self,1873// making sure this method cannot be called multiple times without getting rid1874// of any previously returned unique references first, thus preventing aliasing.1875unsafe {1876Self::fetch_next_aliased_unchecked(1877self.entity_iter.by_ref().rev(),1878self.entities,1879self.tables,1880self.archetypes,1881&mut self.fetch,1882&mut self.filter,1883self.query_state,1884)1885.map(D::shrink)1886}1887}1888}18891890impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>> Iterator1891for QueryManyIter<'w, 's, D, F, I>1892{1893type Item = D::Item<'w, 's>;18941895#[inline(always)]1896fn next(&mut self) -> Option<Self::Item> {1897// SAFETY:1898// All arguments stem from self.1899// It is safe to alias for ReadOnlyWorldQuery.1900unsafe {1901Self::fetch_next_aliased_unchecked(1902&mut self.entity_iter,1903self.entities,1904self.tables,1905self.archetypes,1906&mut self.fetch,1907&mut self.filter,1908self.query_state,1909)1910}1911}19121913fn size_hint(&self) -> (usize, Option<usize>) {1914let (_, max_size) = self.entity_iter.size_hint();1915(0, max_size)1916}1917}19181919impl<1920'w,1921's,1922D: ReadOnlyQueryData,1923F: QueryFilter,1924I: DoubleEndedIterator<Item: EntityEquivalent>,1925> DoubleEndedIterator for QueryManyIter<'w, 's, D, F, I>1926{1927#[inline(always)]1928fn next_back(&mut self) -> Option<Self::Item> {1929// SAFETY:1930// All arguments stem from self.1931// It is safe to alias for ReadOnlyWorldQuery.1932unsafe {1933Self::fetch_next_aliased_unchecked(1934self.entity_iter.by_ref().rev(),1935self.entities,1936self.tables,1937self.archetypes,1938&mut self.fetch,1939&mut self.filter,1940self.query_state,1941)1942}1943}1944}19451946// This is correct as [`QueryManyIter`] always returns `None` once exhausted.1947impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>1948FusedIterator for QueryManyIter<'w, 's, D, F, I>1949{1950}19511952// SAFETY: Fetching unique entities maintains uniqueness.1953unsafe impl<'w, 's, F: QueryFilter, I: EntitySetIterator> EntitySetIterator1954for QueryManyIter<'w, 's, Entity, F, I>1955{1956}19571958impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>> Debug1959for QueryManyIter<'w, 's, D, F, I>1960{1961fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {1962f.debug_struct("QueryManyIter").finish()1963}1964}19651966/// An [`Iterator`] over the query items generated from an iterator of unique [`Entity`]s.1967///1968/// Items are returned in the order of the provided iterator.1969/// Entities that don't match the query are skipped.1970///1971/// In contrast with [`QueryManyIter`], this allows for mutable iteration without a [`fetch_next`] method.1972///1973/// This struct is created by the [`iter_many_unique`] and [`iter_many_unique_mut`] methods on [`Query`].1974///1975/// [`fetch_next`]: QueryManyIter::fetch_next1976/// [`iter_many_unique`]: crate::system::Query::iter_many1977/// [`iter_many_unique_mut`]: crate::system::Query::iter_many_mut1978/// [`Query`]: crate::system::Query1979pub struct QueryManyUniqueIter<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator>(1980QueryManyIter<'w, 's, D, F, I>,1981);19821983impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator>1984QueryManyUniqueIter<'w, 's, D, F, I>1985{1986/// # Safety1987/// - `world` must have permission to access any of the components registered in `query_state`.1988/// - `world` must be the same one used to initialize `query_state`.1989pub(crate) unsafe fn new<EntityList: EntitySet<IntoIter = I>>(1990world: UnsafeWorldCell<'w>,1991query_state: &'s QueryState<D, F>,1992entity_list: EntityList,1993last_run: Tick,1994this_run: Tick,1995) -> QueryManyUniqueIter<'w, 's, D, F, I> {1996QueryManyUniqueIter(QueryManyIter::new(1997world,1998query_state,1999entity_list,2000last_run,2001this_run,2002))2003}2004}20052006impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> Iterator2007for QueryManyUniqueIter<'w, 's, D, F, I>2008{2009type Item = D::Item<'w, 's>;20102011#[inline(always)]2012fn next(&mut self) -> Option<Self::Item> {2013// SAFETY: Entities are guaranteed to be unique, thus do not alias.2014unsafe {2015QueryManyIter::<'w, 's, D, F, I>::fetch_next_aliased_unchecked(2016&mut self.0.entity_iter,2017self.0.entities,2018self.0.tables,2019self.0.archetypes,2020&mut self.0.fetch,2021&mut self.0.filter,2022self.0.query_state,2023)2024}2025}20262027fn size_hint(&self) -> (usize, Option<usize>) {2028let (_, max_size) = self.0.entity_iter.size_hint();2029(0, max_size)2030}2031}20322033// This is correct as [`QueryManyIter`] always returns `None` once exhausted.2034impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> FusedIterator2035for QueryManyUniqueIter<'w, 's, D, F, I>2036{2037}20382039// SAFETY: Fetching unique entities maintains uniqueness.2040unsafe impl<'w, 's, F: QueryFilter, I: EntitySetIterator> EntitySetIterator2041for QueryManyUniqueIter<'w, 's, Entity, F, I>2042{2043}20442045impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> Debug2046for QueryManyUniqueIter<'w, 's, D, F, I>2047{2048fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {2049f.debug_struct("QueryManyUniqueIter").finish()2050}2051}20522053/// An [`Iterator`] over sorted query results of a [`QueryManyIter`].2054///2055/// This struct is created by the [`sort`](QueryManyIter), [`sort_unstable`](QueryManyIter),2056/// [`sort_by`](QueryManyIter), [`sort_unstable_by`](QueryManyIter), [`sort_by_key`](QueryManyIter),2057/// [`sort_unstable_by_key`](QueryManyIter), and [`sort_by_cached_key`](QueryManyIter) methods of [`QueryManyIter`].2058pub struct QuerySortedManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> {2059entity_iter: I,2060entities: &'w Entities,2061tables: &'w Tables,2062archetypes: &'w Archetypes,2063fetch: D::Fetch<'w>,2064query_state: &'s QueryState<D, F>,2065}20662067impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>>2068QuerySortedManyIter<'w, 's, D, F, I>2069{2070/// # Safety2071/// - `world` must have permission to access any of the components registered in `query_state`.2072/// - `world` must be the same one used to initialize `query_state`.2073/// - `entity_list` must only contain unique entities or be empty.2074pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(2075world: UnsafeWorldCell<'w>,2076query_state: &'s QueryState<D, F>,2077entity_list: EntityList,2078last_run: Tick,2079this_run: Tick,2080) -> QuerySortedManyIter<'w, 's, D, F, I> {2081let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);2082QuerySortedManyIter {2083query_state,2084entities: world.entities(),2085archetypes: world.archetypes(),2086// SAFETY: We only access table data that has been registered in `query_state`.2087// This means `world` has permission to access the data we use.2088tables: &world.storages().tables,2089fetch,2090entity_iter: entity_list.into_iter(),2091}2092}20932094/// # Safety2095/// The lifetime here is not restrictive enough for Fetch with &mut access,2096/// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple2097/// references to the same component, leading to unique reference aliasing.2098///2099/// It is always safe for shared access.2100/// `entity` must stem from `self.entity_iter`, and not have been passed before.2101#[inline(always)]2102unsafe fn fetch_next_aliased_unchecked(&mut self, entity: Entity) -> Option<D::Item<'w, 's>> {2103let (location, archetype, table);2104// SAFETY:2105// `tables` and `archetypes` belong to the same world that the [`QueryIter`]2106// was initialized for.2107unsafe {2108location = self.entities.get_spawned(entity).debug_checked_unwrap();2109archetype = self2110.archetypes2111.get(location.archetype_id)2112.debug_checked_unwrap();2113table = self.tables.get(location.table_id).debug_checked_unwrap();2114}21152116// SAFETY: `archetype` is from the world that `fetch` was created for,2117// `fetch_state` is the state that `fetch` was initialized with2118unsafe {2119D::set_archetype(2120&mut self.fetch,2121&self.query_state.fetch_state,2122archetype,2123table,2124);2125}21262127// The entity list has already been filtered by the query lens, so we forego filtering here.2128// SAFETY:2129// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype2130// - fetch is only called once for each entity.2131unsafe {2132D::fetch(2133&self.query_state.fetch_state,2134&mut self.fetch,2135entity,2136location.table_row,2137)2138}2139}21402141/// Get next result from the query2142#[inline(always)]2143pub fn fetch_next(&mut self) -> Option<D::Item<'_, 's>> {2144while let Some(entity) = self.entity_iter.next() {2145// SAFETY:2146// We have collected the entity_iter once to drop all internal lens query item2147// references.2148// We are limiting the returned reference to self,2149// making sure this method cannot be called multiple times without getting rid2150// of any previously returned unique references first, thus preventing aliasing.2151// `entity` is passed from `entity_iter` the first time.2152if let Some(item) = unsafe { self.fetch_next_aliased_unchecked(entity) } {2153return Some(D::shrink(item));2154}2155}2156None2157}2158}21592160impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item = Entity>>2161QuerySortedManyIter<'w, 's, D, F, I>2162{2163/// Get next result from the query2164#[inline(always)]2165pub fn fetch_next_back(&mut self) -> Option<D::Item<'_, 's>> {2166while let Some(entity) = self.entity_iter.next_back() {2167// SAFETY:2168// We have collected the entity_iter once to drop all internal lens query item2169// references.2170// We are limiting the returned reference to self,2171// making sure this method cannot be called multiple times without getting rid2172// of any previously returned unique references first, thus preventing aliasing.2173// `entity` is passed from `entity_iter` the first time.2174if let Some(item) = unsafe { self.fetch_next_aliased_unchecked(entity) } {2175return Some(D::shrink(item));2176}2177}2178None2179}2180}21812182impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item = Entity>> Iterator2183for QuerySortedManyIter<'w, 's, D, F, I>2184{2185type Item = D::Item<'w, 's>;21862187#[inline(always)]2188fn next(&mut self) -> Option<Self::Item> {2189while let Some(entity) = self.entity_iter.next() {2190// SAFETY:2191// It is safe to alias for ReadOnlyWorldQuery.2192// `entity` is passed from `entity_iter` the first time.2193if let Some(item) = unsafe { self.fetch_next_aliased_unchecked(entity) } {2194return Some(D::shrink(item));2195}2196}2197None2198}21992200fn size_hint(&self) -> (usize, Option<usize>) {2201let (min_size, max_size) = self.entity_iter.size_hint();2202let archetype_query = D::IS_ARCHETYPAL;2203let min_size = if archetype_query { min_size } else { 0 };2204(min_size, max_size)2205}2206}22072208impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: DoubleEndedIterator<Item = Entity>>2209DoubleEndedIterator for QuerySortedManyIter<'w, 's, D, F, I>2210{2211#[inline(always)]2212fn next_back(&mut self) -> Option<Self::Item> {2213while let Some(entity) = self.entity_iter.next_back() {2214// SAFETY:2215// It is safe to alias for ReadOnlyWorldQuery.2216// `entity` is passed from `entity_iter` the first time.2217if let Some(item) = unsafe { self.fetch_next_aliased_unchecked(entity) } {2218return Some(D::shrink(item));2219}2220}2221None2222}2223}22242225impl<2226D: ReadOnlyQueryData + ArchetypeQueryData,2227F: QueryFilter,2228I: ExactSizeIterator<Item = Entity>,2229> ExactSizeIterator for QuerySortedManyIter<'_, '_, D, F, I>2230{2231}22322233impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>> Debug2234for QuerySortedManyIter<'w, 's, D, F, I>2235{2236fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {2237f.debug_struct("QuerySortedManyIter").finish()2238}2239}22402241/// An iterator over `K`-sized combinations of query items without repetition.2242///2243/// A combination is an arrangement of a collection of items where order does not matter.2244///2245/// `K` is the number of items that make up each subset, and the number of items returned by the iterator.2246/// `N` is the number of total entities output by the query.2247///2248/// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are2249/// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].2250/// And in this case, `N` would be defined as 4 since the size of the input list is 4.2251///2252/// The number of combinations depend on how `K` relates to the number of entities matching the [`Query`]:2253/// - if `K = N`, only one combination exists,2254/// - if `K < N`, there are <sub>N</sub>C<sub>K</sub> combinations (see the [performance section] of `Query`),2255/// - if `K > N`, there are no combinations.2256///2257/// The output combination is not guaranteed to have any order of iteration.2258///2259/// # Usage2260///2261/// This type is returned by calling [`Query::iter_combinations`] or [`Query::iter_combinations_mut`].2262///2263/// It implements [`Iterator`] only if it iterates over read-only query items ([learn more]).2264///2265/// In the case of mutable query items, it can be iterated by calling [`fetch_next`] in a `while let` loop.2266///2267/// # Examples2268///2269/// The following example shows how to traverse the iterator when the query items are read-only.2270///2271/// ```2272/// # use bevy_ecs::prelude::*;2273/// # #[derive(Component)]2274/// # struct ComponentA;2275/// #2276/// fn some_system(query: Query<&ComponentA>) {2277/// for [a1, a2] in query.iter_combinations() {2278/// // ...2279/// }2280/// }2281/// ```2282///2283/// 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.2284///2285/// ```2286/// # use bevy_ecs::prelude::*;2287/// # #[derive(Component)]2288/// # struct ComponentA;2289/// #2290/// fn some_system(mut query: Query<&mut ComponentA>) {2291/// let mut combinations = query.iter_combinations_mut();2292/// while let Some([a1, a2]) = combinations.fetch_next() {2293/// // ...2294/// }2295/// }2296/// ```2297///2298/// [`fetch_next`]: Self::fetch_next2299/// [learn more]: Self#impl-Iterator2300/// [performance section]: crate::system::Query#performance2301/// [`Query`]: crate::system::Query2302/// [`Query::iter_combinations`]: crate::system::Query::iter_combinations2303/// [`Query::iter_combinations_mut`]: crate::system::Query::iter_combinations_mut2304pub struct QueryCombinationIter<'w, 's, D: QueryData, F: QueryFilter, const K: usize> {2305tables: &'w Tables,2306archetypes: &'w Archetypes,2307query_state: &'s QueryState<D, F>,2308cursors: [QueryIterationCursor<'w, 's, D, F>; K],2309}23102311impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<'w, 's, D, F, K> {2312/// # Safety2313/// - `world` must have permission to access any of the components registered in `query_state`.2314/// - `world` must be the same one used to initialize `query_state`.2315pub(crate) unsafe fn new(2316world: UnsafeWorldCell<'w>,2317query_state: &'s QueryState<D, F>,2318last_run: Tick,2319this_run: Tick,2320) -> Self {2321assert!(K != 0, "K should not equal to zero");2322// Initialize array with cursors.2323// There is no FromIterator on arrays, so instead initialize it manually with MaybeUninit23242325let mut array: MaybeUninit<[QueryIterationCursor<'w, 's, D, F>; K]> = MaybeUninit::uninit();2326let ptr = array2327.as_mut_ptr()2328.cast::<QueryIterationCursor<'w, 's, D, F>>();2329ptr.write(QueryIterationCursor::init(2330world,2331query_state,2332last_run,2333this_run,2334));2335for slot in (1..K).map(|offset| ptr.add(offset)) {2336slot.write(QueryIterationCursor::init_empty(2337world,2338query_state,2339last_run,2340this_run,2341));2342}23432344QueryCombinationIter {2345query_state,2346// SAFETY: We only access table data that has been registered in `query_state`.2347tables: unsafe { &world.storages().tables },2348archetypes: world.archetypes(),2349cursors: array.assume_init(),2350}2351}23522353/// # Safety2354/// The lifetime here is not restrictive enough for Fetch with &mut access,2355/// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple2356/// references to the same component, leading to unique reference aliasing.2357/// .2358/// It is always safe for shared access.2359#[inline]2360unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<[D::Item<'w, 's>; K]> {2361// PERF: can speed up the following code using `cursor.remaining()` instead of `next_item.is_none()`2362// when D::IS_ARCHETYPAL && F::IS_ARCHETYPAL2363//2364// let `i` be the index of `c`, the last cursor in `self.cursors` that2365// returns `K-i` or more elements.2366// Make cursor in index `j` for all `j` in `[i, K)` a copy of `c` advanced `j-i+1` times.2367// If no such `c` exists, return `None`2368'outer: for i in (0..K).rev() {2369match self.cursors[i].next(self.tables, self.archetypes, self.query_state) {2370Some(_) => {2371for j in (i + 1)..K {2372self.cursors[j] = self.cursors[j - 1].clone();2373match self.cursors[j].next(self.tables, self.archetypes, self.query_state) {2374Some(_) => {}2375None if i > 0 => continue 'outer,2376None => return None,2377}2378}2379break;2380}2381None if i > 0 => continue,2382None => return None,2383}2384}23852386let mut values = MaybeUninit::<[D::Item<'w, 's>; K]>::uninit();23872388let ptr = values.as_mut_ptr().cast::<D::Item<'w, 's>>();2389for (offset, cursor) in self.cursors.iter_mut().enumerate() {2390ptr.add(offset)2391.write(cursor.peek_last(self.query_state).unwrap());2392}23932394Some(values.assume_init())2395}23962397/// Get next combination of queried components2398#[inline]2399pub fn fetch_next(&mut self) -> Option<[D::Item<'_, 's>; K]> {2400// SAFETY: we are limiting the returned reference to self,2401// making sure this method cannot be called multiple times without getting rid2402// of any previously returned unique references first, thus preventing aliasing.2403unsafe {2404self.fetch_next_aliased_unchecked()2405.map(|array| array.map(D::shrink))2406}2407}2408}24092410// Iterator type is intentionally implemented only for read-only access.2411// Doing so for mutable references would be unsound, because calling `next`2412// multiple times would allow multiple owned references to the same data to exist.2413impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator2414for QueryCombinationIter<'w, 's, D, F, K>2415{2416type Item = [D::Item<'w, 's>; K];24172418#[inline]2419fn next(&mut self) -> Option<Self::Item> {2420// Safety: it is safe to alias for ReadOnlyWorldQuery2421unsafe { QueryCombinationIter::fetch_next_aliased_unchecked(self) }2422}24232424fn size_hint(&self) -> (usize, Option<usize>) {2425// binomial coefficient: (n ; k) = n! / k!(n-k)! = (n*n-1*...*n-k+1) / k!2426// See https://en.wikipedia.org/wiki/Binomial_coefficient2427// See https://blog.plover.com/math/choose.html for implementation2428// It was chosen to reduce overflow potential.2429fn choose(n: usize, k: usize) -> Option<usize> {2430if k > n || n == 0 {2431return Some(0);2432}2433let k = k.min(n - k);2434let ks = 1..=k;2435let ns = (n - k + 1..=n).rev();2436ks.zip(ns)2437.try_fold(1_usize, |acc, (k, n)| Some(acc.checked_mul(n)? / k))2438}2439// sum_i=0..k choose(cursors[i].remaining, k-i)2440let max_combinations = self2441.cursors2442.iter()2443.enumerate()2444.try_fold(0, |acc, (i, cursor)| {2445let n = cursor.max_remaining(self.tables, self.archetypes);2446Some(acc + choose(n as usize, K - i)?)2447});24482449let archetype_query = D::IS_ARCHETYPAL && F::IS_ARCHETYPAL;2450let known_max = max_combinations.unwrap_or(usize::MAX);2451let min_combinations = if archetype_query { known_max } else { 0 };2452(min_combinations, max_combinations)2453}2454}24552456impl<'w, 's, D: ArchetypeQueryData, F: ArchetypeFilter> ExactSizeIterator2457for QueryIter<'w, 's, D, F>2458{2459fn len(&self) -> usize {2460self.size_hint().02461}2462}24632464// This is correct as [`QueryCombinationIter`] always returns `None` once exhausted.2465impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> FusedIterator2466for QueryCombinationIter<'w, 's, D, F, K>2467{2468}24692470impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> Debug2471for QueryCombinationIter<'w, 's, D, F, K>2472{2473fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {2474f.debug_struct("QueryCombinationIter").finish()2475}2476}24772478struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> {2479// whether the query iteration is dense or not. Mirrors QueryState's `is_dense` field.2480is_dense: bool,2481storage_id_iter: core::slice::Iter<'s, StorageId>,2482table_entities: &'w [Entity],2483archetype_entities: &'w [ArchetypeEntity],2484fetch: D::Fetch<'w>,2485filter: F::Fetch<'w>,2486// length of the table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense2487current_len: u32,2488// either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense2489current_row: u32,2490}24912492impl<D: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, D, F> {2493fn clone(&self) -> Self {2494Self {2495is_dense: self.is_dense,2496storage_id_iter: self.storage_id_iter.clone(),2497table_entities: self.table_entities,2498archetype_entities: self.archetype_entities,2499fetch: self.fetch.clone(),2500filter: self.filter.clone(),2501current_len: self.current_len,2502current_row: self.current_row,2503}2504}2505}25062507impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {2508/// # Safety2509/// - `world` must have permission to access any of the components registered in `query_state`.2510/// - `world` must be the same one used to initialize `query_state`.2511unsafe fn init_empty(2512world: UnsafeWorldCell<'w>,2513query_state: &'s QueryState<D, F>,2514last_run: Tick,2515this_run: Tick,2516) -> Self {2517QueryIterationCursor {2518storage_id_iter: [].iter(),2519..Self::init(world, query_state, last_run, this_run)2520}2521}25222523/// # Safety2524/// - `world` must have permission to access any of the components registered in `query_state`.2525/// - `world` must be the same one used to initialize `query_state`.2526unsafe fn init(2527world: UnsafeWorldCell<'w>,2528query_state: &'s QueryState<D, F>,2529last_run: Tick,2530this_run: Tick,2531) -> Self {2532let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);2533let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);2534QueryIterationCursor {2535fetch,2536filter,2537table_entities: &[],2538archetype_entities: &[],2539storage_id_iter: query_state.matched_storage_ids.iter(),2540is_dense: query_state.is_dense,2541current_len: 0,2542current_row: 0,2543}2544}25452546fn reborrow(&mut self) -> QueryIterationCursor<'_, 's, D, F> {2547QueryIterationCursor {2548is_dense: self.is_dense,2549fetch: D::shrink_fetch(self.fetch.clone()),2550filter: F::shrink_fetch(self.filter.clone()),2551table_entities: self.table_entities,2552archetype_entities: self.archetype_entities,2553storage_id_iter: self.storage_id_iter.clone(),2554current_len: self.current_len,2555current_row: self.current_row,2556}2557}25582559/// Retrieve item returned from most recent `next` call again.2560///2561/// # Safety2562/// The result of `next` and any previous calls to `peek_last` with this row must have been2563/// dropped to prevent aliasing mutable references.2564#[inline]2565unsafe fn peek_last(&mut self, query_state: &'s QueryState<D, F>) -> Option<D::Item<'w, 's>> {2566if self.current_row > 0 {2567let index = self.current_row - 1;2568if self.is_dense {2569// SAFETY: This must have been called previously in `next` as `current_row > 0`2570let entity = unsafe { self.table_entities.get_unchecked(index as usize) };2571// SAFETY:2572// - `set_table` must have been called previously either in `next` or before it.2573// - `*entity` and `index` are in the current table.2574unsafe {2575D::fetch(2576&query_state.fetch_state,2577&mut self.fetch,2578*entity,2579// SAFETY: This is from an exclusive range, so it can't be max.2580TableRow::new(NonMaxU32::new_unchecked(index)),2581)2582}2583} else {2584// SAFETY: This must have been called previously in `next` as `current_row > 0`2585let archetype_entity =2586unsafe { self.archetype_entities.get_unchecked(index as usize) };2587// SAFETY:2588// - `set_archetype` must have been called previously either in `next` or before it.2589// - `archetype_entity.id()` and `archetype_entity.table_row()` are in the current archetype.2590unsafe {2591D::fetch(2592&query_state.fetch_state,2593&mut self.fetch,2594archetype_entity.id(),2595archetype_entity.table_row(),2596)2597}2598}2599} else {2600None2601}2602}26032604/// How many values will this cursor return at most?2605///2606/// Note that if `D::IS_ARCHETYPAL && F::IS_ARCHETYPAL`, the return value2607/// will be **the exact count of remaining values**.2608fn max_remaining(&self, tables: &'w Tables, archetypes: &'w Archetypes) -> u32 {2609let ids = self.storage_id_iter.clone();2610let remaining_matched: u32 = if self.is_dense {2611// SAFETY: The if check ensures that storage_id_iter stores TableIds2612unsafe { ids.map(|id| tables[id.table_id].entity_count()).sum() }2613} else {2614// SAFETY: The if check ensures that storage_id_iter stores ArchetypeIds2615unsafe { ids.map(|id| archetypes[id.archetype_id].len()).sum() }2616};2617remaining_matched + self.current_len - self.current_row2618}26192620// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:2621// QueryIter, QueryIterationCursor, QuerySortedIter, QueryManyIter, QuerySortedManyIter, QueryCombinationIter,2622// QueryState::par_fold_init_unchecked_manual, QueryState::par_many_fold_init_unchecked_manual,2623// QueryState::par_many_unique_fold_init_unchecked_manual, QueryContiguousIter::next2624/// # Safety2625/// `tables` and `archetypes` must belong to the same world that the [`QueryIterationCursor`]2626/// was initialized for.2627/// `query_state` must be the same [`QueryState`] that was passed to `init` or `init_empty`.2628#[inline(always)]2629unsafe fn next(2630&mut self,2631tables: &'w Tables,2632archetypes: &'w Archetypes,2633query_state: &'s QueryState<D, F>,2634) -> Option<D::Item<'w, 's>> {2635if self.is_dense {2636// NOTE: if you are changing this branch you would probably have to change2637// QueryContiguousIter::next as well2638loop {2639// we are on the beginning of the query, or finished processing a table, so skip to the next2640if self.current_row == self.current_len {2641let table_id = self.storage_id_iter.next()?.table_id;2642let table = tables.get(table_id).debug_checked_unwrap();2643if table.is_empty() {2644continue;2645}2646// SAFETY: `table` is from the world that `fetch/filter` were created for,2647// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with2648unsafe {2649D::set_table(&mut self.fetch, &query_state.fetch_state, table);2650F::set_table(&mut self.filter, &query_state.filter_state, table);2651}2652self.table_entities = table.entities();2653self.current_len = table.entity_count();2654self.current_row = 0;2655}26562657// SAFETY: set_table was called prior.2658// `current_row` is a table row in range of the current table, because if it was not, then the above would have been executed.2659let entity =2660unsafe { self.table_entities.get_unchecked(self.current_row as usize) };2661// SAFETY: The row is less than the u32 len, so it must not be max.2662let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(self.current_row)) };2663self.current_row += 1;26642665if !F::filter_fetch(&query_state.filter_state, &mut self.filter, *entity, row) {2666continue;2667}26682669// SAFETY:2670// - set_table was called prior.2671// - `current_row` must be a table row in range of the current table,2672// because if it was not, then the above would have been executed.2673// - fetch is only called once for each `entity`.2674let item =2675unsafe { D::fetch(&query_state.fetch_state, &mut self.fetch, *entity, row) };2676if let Some(item) = item {2677return Some(item);2678}2679}2680} else {2681loop {2682if self.current_row == self.current_len {2683let archetype_id = self.storage_id_iter.next()?.archetype_id;2684let archetype = archetypes.get(archetype_id).debug_checked_unwrap();2685if archetype.is_empty() {2686continue;2687}2688let table = tables.get(archetype.table_id()).debug_checked_unwrap();2689// SAFETY: `archetype` and `tables` are from the world that `fetch/filter` were created for,2690// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with2691unsafe {2692D::set_archetype(2693&mut self.fetch,2694&query_state.fetch_state,2695archetype,2696table,2697);2698F::set_archetype(2699&mut self.filter,2700&query_state.filter_state,2701archetype,2702table,2703);2704}2705self.archetype_entities = archetype.entities();2706self.current_len = archetype.len();2707self.current_row = 0;2708}27092710// SAFETY: set_archetype was called prior.2711// `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.2712let archetype_entity = unsafe {2713self.archetype_entities2714.get_unchecked(self.current_row as usize)2715};2716self.current_row += 1;27172718if !F::filter_fetch(2719&query_state.filter_state,2720&mut self.filter,2721archetype_entity.id(),2722archetype_entity.table_row(),2723) {2724continue;2725}27262727// SAFETY:2728// - set_archetype was called prior.2729// - `current_row` must be an archetype index row in range of the current archetype,2730// because if it was not, then the if above would have been executed.2731// - fetch is only called once for each `archetype_entity`.2732let item = unsafe {2733D::fetch(2734&query_state.fetch_state,2735&mut self.fetch,2736archetype_entity.id(),2737archetype_entity.table_row(),2738)2739};2740if let Some(item) = item {2741return Some(item);2742}2743}2744}2745}2746}27472748// A wrapper struct that gives its data a neutral ordering.2749#[derive(Copy, Clone)]2750struct NeutralOrd<T>(T);27512752impl<T> PartialEq for NeutralOrd<T> {2753fn eq(&self, _other: &Self) -> bool {2754true2755}2756}27572758impl<T> Eq for NeutralOrd<T> {}27592760#[expect(2761clippy::non_canonical_partial_ord_impl,2762reason = "`PartialOrd` and `Ord` on this struct must only ever return `Ordering::Equal`, so we prefer clarity"2763)]2764impl<T> PartialOrd for NeutralOrd<T> {2765fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {2766Some(Ordering::Equal)2767}2768}27692770impl<T> Ord for NeutralOrd<T> {2771fn cmp(&self, _other: &Self) -> Ordering {2772Ordering::Equal2773}2774}27752776#[cfg(test)]2777#[expect(clippy::print_stdout, reason = "Allowed in tests.")]2778mod tests {2779use alloc::vec::Vec;2780use std::println;27812782use crate::component::Component;2783use crate::entity::Entity;2784use crate::prelude::{With, World};27852786#[derive(Component, Debug, PartialEq, PartialOrd, Clone, Copy)]2787struct A(f32);2788#[derive(Component, Debug, Eq, PartialEq, Clone, Copy)]2789#[component(storage = "SparseSet")]2790struct Sparse(usize);27912792#[derive(Component)]2793struct Marker;27942795#[test]2796fn query_iter_sorts() {2797let mut world = World::new();2798for i in 0..100 {2799world.spawn((A(i as f32), Marker));2800world.spawn((A(i as f32), Sparse(i), Marker));2801world.spawn((Sparse(i), Marker));2802}28032804let mut query = world.query_filtered::<Entity, With<Marker>>();28052806let sort = query.iter(&world).sort::<Entity>().collect::<Vec<_>>();2807assert_eq!(sort.len(), 300);28082809let sort_unstable = query2810.iter(&world)2811.sort_unstable::<Entity>()2812.collect::<Vec<_>>();28132814let sort_by = query2815.iter(&world)2816.sort_by::<Entity>(Ord::cmp)2817.collect::<Vec<_>>();28182819let sort_unstable_by = query2820.iter(&world)2821.sort_unstable_by::<Entity>(Ord::cmp)2822.collect::<Vec<_>>();28232824let sort_by_key = query2825.iter(&world)2826.sort_by_key::<Entity, _>(|&e| e)2827.collect::<Vec<_>>();28282829let sort_unstable_by_key = query2830.iter(&world)2831.sort_unstable_by_key::<Entity, _>(|&e| e)2832.collect::<Vec<_>>();28332834let sort_by_cached_key = query2835.iter(&world)2836.sort_by_cached_key::<Entity, _>(|&e| e)2837.collect::<Vec<_>>();28382839let mut sort_v2 = query.iter(&world).collect::<Vec<_>>();2840sort_v2.sort();28412842let mut sort_unstable_v2 = query.iter(&world).collect::<Vec<_>>();2843sort_unstable_v2.sort_unstable();28442845let mut sort_by_v2 = query.iter(&world).collect::<Vec<_>>();2846sort_by_v2.sort_by(Ord::cmp);28472848let mut sort_unstable_by_v2 = query.iter(&world).collect::<Vec<_>>();2849sort_unstable_by_v2.sort_unstable_by(Ord::cmp);28502851let mut sort_by_key_v2 = query.iter(&world).collect::<Vec<_>>();2852sort_by_key_v2.sort_by_key(|&e| e);28532854let mut sort_unstable_by_key_v2 = query.iter(&world).collect::<Vec<_>>();2855sort_unstable_by_key_v2.sort_unstable_by_key(|&e| e);28562857let mut sort_by_cached_key_v2 = query.iter(&world).collect::<Vec<_>>();2858sort_by_cached_key_v2.sort_by_cached_key(|&e| e);28592860assert_eq!(sort, sort_v2);2861assert_eq!(sort_unstable, sort_unstable_v2);2862assert_eq!(sort_by, sort_by_v2);2863assert_eq!(sort_unstable_by, sort_unstable_by_v2);2864assert_eq!(sort_by_key, sort_by_key_v2);2865assert_eq!(sort_unstable_by_key, sort_unstable_by_key_v2);2866assert_eq!(sort_by_cached_key, sort_by_cached_key_v2);2867}28682869#[test]2870#[should_panic]2871fn query_iter_sort_after_next() {2872let mut world = World::new();2873world.spawn((A(0.),));2874world.spawn((A(1.1),));2875world.spawn((A(2.22),));28762877{2878let mut query = world.query::<&A>();2879let mut iter = query.iter(&world);2880println!(2881"archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2882iter.cursor.archetype_entities.len(),2883iter.cursor.table_entities.len(),2884iter.cursor.current_len,2885iter.cursor.current_row2886);2887_ = iter.next();2888println!(2889"archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2890iter.cursor.archetype_entities.len(),2891iter.cursor.table_entities.len(),2892iter.cursor.current_len,2893iter.cursor.current_row2894);2895println!("{}", iter.sort::<Entity>().len());2896}2897}28982899#[test]2900#[should_panic]2901fn query_iter_sort_after_next_dense() {2902let mut world = World::new();2903world.spawn((Sparse(11),));2904world.spawn((Sparse(22),));2905world.spawn((Sparse(33),));29062907{2908let mut query = world.query::<&Sparse>();2909let mut iter = query.iter(&world);2910println!(2911"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2912iter.cursor.archetype_entities.len(),2913iter.cursor.table_entities.len(),2914iter.cursor.current_len,2915iter.cursor.current_row2916);2917_ = iter.next();2918println!(2919"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2920iter.cursor.archetype_entities.len(),2921iter.cursor.table_entities.len(),2922iter.cursor.current_len,2923iter.cursor.current_row2924);2925println!("{}", iter.sort::<Entity>().len());2926}2927}29282929#[test]2930fn empty_query_iter_sort_after_next_does_not_panic() {2931let mut world = World::new();2932{2933let mut query = world.query::<(&A, &Sparse)>();2934let mut iter = query.iter(&world);2935println!(2936"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2937iter.cursor.archetype_entities.len(),2938iter.cursor.table_entities.len(),2939iter.cursor.current_len,2940iter.cursor.current_row2941);2942_ = iter.next();2943println!(2944"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2945iter.cursor.archetype_entities.len(),2946iter.cursor.table_entities.len(),2947iter.cursor.current_len,2948iter.cursor.current_row2949);2950println!("{}", iter.sort::<Entity>().len());2951}2952}29532954#[test]2955fn query_iter_cursor_state_non_empty_after_next() {2956let mut world = World::new();2957world.spawn((A(0.), Sparse(11)));2958world.spawn((A(1.1), Sparse(22)));2959world.spawn((A(2.22), Sparse(33)));2960{2961let mut query = world.query::<(&A, &Sparse)>();2962let mut iter = query.iter(&world);2963println!(2964"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2965iter.cursor.archetype_entities.len(),2966iter.cursor.table_entities.len(),2967iter.cursor.current_len,2968iter.cursor.current_row2969);2970assert!(iter.cursor.table_entities.len() | iter.cursor.archetype_entities.len() == 0);2971_ = iter.next();2972println!(2973"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",2974iter.cursor.archetype_entities.len(),2975iter.cursor.table_entities.len(),2976iter.cursor.current_len,2977iter.cursor.current_row2978);2979assert!(2980(2981iter.cursor.table_entities.len(),2982iter.cursor.archetype_entities.len()2983) != (0, 0)2984);2985}2986}29872988#[test]2989fn query_iter_many_sorts() {2990let mut world = World::new();29912992let entity_list: &Vec<_> = &world2993.spawn_batch([A(0.), A(1.), A(2.), A(3.), A(4.)])2994.collect();29952996let mut query = world.query::<Entity>();29972998let sort = query2999.iter_many(&world, entity_list)3000.sort::<Entity>()3001.collect::<Vec<_>>();30023003let sort_unstable = query3004.iter_many(&world, entity_list)3005.sort_unstable::<Entity>()3006.collect::<Vec<_>>();30073008let sort_by = query3009.iter_many(&world, entity_list)3010.sort_by::<Entity>(Ord::cmp)3011.collect::<Vec<_>>();30123013let sort_unstable_by = query3014.iter_many(&world, entity_list)3015.sort_unstable_by::<Entity>(Ord::cmp)3016.collect::<Vec<_>>();30173018let sort_by_key = query3019.iter_many(&world, entity_list)3020.sort_by_key::<Entity, _>(|&e| e)3021.collect::<Vec<_>>();30223023let sort_unstable_by_key = query3024.iter_many(&world, entity_list)3025.sort_unstable_by_key::<Entity, _>(|&e| e)3026.collect::<Vec<_>>();30273028let sort_by_cached_key = query3029.iter_many(&world, entity_list)3030.sort_by_cached_key::<Entity, _>(|&e| e)3031.collect::<Vec<_>>();30323033let mut sort_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();3034sort_v2.sort();30353036let mut sort_unstable_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();3037sort_unstable_v2.sort_unstable();30383039let mut sort_by_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();3040sort_by_v2.sort_by(Ord::cmp);30413042let mut sort_unstable_by_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();3043sort_unstable_by_v2.sort_unstable_by(Ord::cmp);30443045let mut sort_by_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();3046sort_by_key_v2.sort_by_key(|&e| e);30473048let mut sort_unstable_by_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();3049sort_unstable_by_key_v2.sort_unstable_by_key(|&e| e);30503051let mut sort_by_cached_key_v2 = query.iter_many(&world, entity_list).collect::<Vec<_>>();3052sort_by_cached_key_v2.sort_by_cached_key(|&e| e);30533054assert_eq!(sort, sort_v2);3055assert_eq!(sort_unstable, sort_unstable_v2);3056assert_eq!(sort_by, sort_by_v2);3057assert_eq!(sort_unstable_by, sort_unstable_by_v2);3058assert_eq!(sort_by_key, sort_by_key_v2);3059assert_eq!(sort_unstable_by_key, sort_unstable_by_key_v2);3060assert_eq!(sort_by_cached_key, sort_by_cached_key_v2);3061}30623063#[test]3064fn query_iter_many_sort_doesnt_panic_after_next() {3065let mut world = World::new();30663067let entity_list: &Vec<_> = &world3068.spawn_batch([A(0.), A(1.), A(2.), A(3.), A(4.)])3069.collect();30703071let mut query = world.query::<Entity>();3072let mut iter = query.iter_many(&world, entity_list);30733074_ = iter.next();30753076iter.sort::<Entity>();30773078let mut query_2 = world.query::<&mut A>();3079let mut iter_2 = query_2.iter_many_mut(&mut world, entity_list);30803081_ = iter_2.fetch_next();30823083iter_2.sort::<Entity>();3084}30853086// This test should be run with miri to check for UB caused by aliasing.3087// The lens items created during the sort must not be live at the same time as the mutable references returned from the iterator.3088#[test]3089fn query_iter_many_sorts_duplicate_entities_no_ub() {3090#[derive(Component, Ord, PartialOrd, Eq, PartialEq)]3091struct C(usize);30923093let mut world = World::new();3094let id = world.spawn(C(10)).id();3095let mut query_state = world.query::<&mut C>();30963097{3098let mut query = query_state.iter_many_mut(&mut world, [id, id]).sort::<&C>();3099while query.fetch_next().is_some() {}3100}3101{3102let mut query = query_state3103.iter_many_mut(&mut world, [id, id])3104.sort_unstable::<&C>();3105while query.fetch_next().is_some() {}3106}3107{3108let mut query = query_state3109.iter_many_mut(&mut world, [id, id])3110.sort_by::<&C>(|l, r| Ord::cmp(l, r));3111while query.fetch_next().is_some() {}3112}3113{3114let mut query = query_state3115.iter_many_mut(&mut world, [id, id])3116.sort_unstable_by::<&C>(|l, r| Ord::cmp(l, r));3117while query.fetch_next().is_some() {}3118}3119{3120let mut query = query_state3121.iter_many_mut(&mut world, [id, id])3122.sort_by_key::<&C, _>(|d| d.0);3123while query.fetch_next().is_some() {}3124}3125{3126let mut query = query_state3127.iter_many_mut(&mut world, [id, id])3128.sort_unstable_by_key::<&C, _>(|d| d.0);3129while query.fetch_next().is_some() {}3130}3131{3132let mut query = query_state3133.iter_many_mut(&mut world, [id, id])3134.sort_by_cached_key::<&C, _>(|d| d.0);3135while query.fetch_next().is_some() {}3136}3137}3138}313931403141