Clean up Fetch code (#4800)
# Objective Clean up code surrounding fetch by pulling out the common parts into the iteration code. ## Solution Merge `Fetch::table_fetch` and `Fetch::archetype_fetch` into a single API: `Fetch::fetch(&mut self, entity: &Entity, table_row: &usize)`. This provides everything any fetch requires to internally decide which storage to read from and get the underlying data. All of these functions are marked as `#[inline(always)]` and the arguments are passed as references to attempt to optimize out the argument that isn't being used. External to `Fetch`, Query iteration has been changed to keep track of the table row and entity outside of fetch, which moves a lot of the expensive bookkeeping `Fetch` structs had previously done internally into the outer loop. ~~TODO: Benchmark, docs~~ Done. --- ## Changelog Changed: `Fetch::table_fetch` and `Fetch::archetype_fetch` have been merged into a single `Fetch::fetch` function. ## Migration Guide TODO Co-authored-by: Brian Merchant <bhmerchang@gmail.com> Co-authored-by: Saverio Miroddi <saverio.pub2@gmail.com>
This commit is contained in:
		
							parent
							
								
									284b1f1302
								
							
						
					
					
						commit
						fe7ebd4326
					
				@ -261,9 +261,9 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream {
 | 
				
			|||||||
                    _fetch: &mut <Self as #path::query::WorldQueryGats<'__w>>::Fetch,
 | 
					                    _fetch: &mut <Self as #path::query::WorldQueryGats<'__w>>::Fetch,
 | 
				
			||||||
                    _state: &Self::State,
 | 
					                    _state: &Self::State,
 | 
				
			||||||
                    _archetype: &'__w #path::archetype::Archetype,
 | 
					                    _archetype: &'__w #path::archetype::Archetype,
 | 
				
			||||||
                    _tables: &'__w #path::storage::Tables
 | 
					                    _table: &'__w #path::storage::Table
 | 
				
			||||||
                ) {
 | 
					                ) {
 | 
				
			||||||
                    #(<#field_types>::set_archetype(&mut _fetch.#field_idents, &_state.#field_idents, _archetype, _tables);)*
 | 
					                    #(<#field_types>::set_archetype(&mut _fetch.#field_idents, &_state.#field_idents, _archetype, _table);)*
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /// SAFETY: we call `set_table` for each member that implements `Fetch`
 | 
					                /// SAFETY: we call `set_table` for each member that implements `Fetch`
 | 
				
			||||||
@ -276,40 +276,27 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream {
 | 
				
			|||||||
                    #(<#field_types>::set_table(&mut _fetch.#field_idents, &_state.#field_idents, _table);)*
 | 
					                    #(<#field_types>::set_table(&mut _fetch.#field_idents, &_state.#field_idents, _table);)*
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /// SAFETY: we call `table_fetch` for each member that implements `Fetch`.
 | 
					                /// SAFETY: we call `fetch` for each member that implements `Fetch`.
 | 
				
			||||||
                #[inline]
 | 
					                #[inline(always)]
 | 
				
			||||||
                unsafe fn table_fetch<'__w>(
 | 
					                unsafe fn fetch<'__w>(
 | 
				
			||||||
                    _fetch: &mut <Self as #path::query::WorldQueryGats<'__w>>::Fetch,
 | 
					                    _fetch: &mut <Self as #path::query::WorldQueryGats<'__w>>::Fetch,
 | 
				
			||||||
 | 
					                    _entity: Entity,
 | 
				
			||||||
                    _table_row: usize
 | 
					                    _table_row: usize
 | 
				
			||||||
                ) -> <Self as #path::query::WorldQueryGats<'__w>>::Item {
 | 
					                ) -> <Self as #path::query::WorldQueryGats<'__w>>::Item {
 | 
				
			||||||
                    Self::Item {
 | 
					                    Self::Item {
 | 
				
			||||||
                        #(#field_idents: <#field_types>::table_fetch(&mut _fetch.#field_idents, _table_row),)*
 | 
					                        #(#field_idents: <#field_types>::fetch(&mut _fetch.#field_idents, _entity, _table_row),)*
 | 
				
			||||||
                        #(#ignored_field_idents: Default::default(),)*
 | 
					                        #(#ignored_field_idents: Default::default(),)*
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /// SAFETY: we call `archetype_fetch` for each member that implements `Fetch`.
 | 
					                #[allow(unused_variables)]
 | 
				
			||||||
                #[inline]
 | 
					                #[inline(always)]
 | 
				
			||||||
                unsafe fn archetype_fetch<'__w>(
 | 
					                unsafe fn filter_fetch<'__w>(
 | 
				
			||||||
                    _fetch: &mut <Self as #path::query::WorldQueryGats<'__w>>::Fetch,
 | 
					                    _fetch: &mut <Self as #path::query::WorldQueryGats<'__w>>::Fetch,
 | 
				
			||||||
                    _archetype_index: usize
 | 
					                    _entity: Entity,
 | 
				
			||||||
                ) -> <Self as #path::query::WorldQueryGats<'__w>>::Item {
 | 
					                    _table_row: usize
 | 
				
			||||||
                    Self::Item {
 | 
					                ) -> bool {
 | 
				
			||||||
                        #(#field_idents: <#field_types>::archetype_fetch(&mut _fetch.#field_idents, _archetype_index),)*
 | 
					                    true #(&& <#field_types>::filter_fetch(&mut _fetch.#field_idents, _entity, _table_row))*
 | 
				
			||||||
                        #(#ignored_field_idents: Default::default(),)*
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                #[allow(unused_variables)]
 | 
					 | 
				
			||||||
                #[inline]
 | 
					 | 
				
			||||||
                unsafe fn table_filter_fetch<'__w>(_fetch: &mut <Self as #path::query::WorldQueryGats<'__w>>::Fetch, _table_row: usize) -> bool {
 | 
					 | 
				
			||||||
                    true #(&& <#field_types>::table_filter_fetch(&mut _fetch.#field_idents, _table_row))*
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                #[allow(unused_variables)]
 | 
					 | 
				
			||||||
                #[inline]
 | 
					 | 
				
			||||||
                unsafe fn archetype_filter_fetch<'__w>(_fetch: &mut <Self as #path::query::WorldQueryGats<'__w>>::Fetch, _archetype_index: usize) -> bool {
 | 
					 | 
				
			||||||
                    true #(&& <#field_types>::archetype_filter_fetch(&mut _fetch.#field_idents, _archetype_index))*
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                fn update_component_access(state: &Self::State, _access: &mut #path::query::FilteredAccess<#path::component::ComponentId>) {
 | 
					                fn update_component_access(state: &Self::State, _access: &mut #path::query::FilteredAccess<#path::component::ComponentId>) {
 | 
				
			||||||
 | 
				
			|||||||
@ -121,9 +121,19 @@ impl Edges {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct TableInfo {
 | 
					pub struct ArchetypeEntity {
 | 
				
			||||||
    id: TableId,
 | 
					    pub(crate) entity: Entity,
 | 
				
			||||||
    entity_rows: Vec<usize>,
 | 
					    pub(crate) table_row: usize,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ArchetypeEntity {
 | 
				
			||||||
 | 
					    pub fn entity(&self) -> Entity {
 | 
				
			||||||
 | 
					        self.entity
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn table_row(&self) -> usize {
 | 
				
			||||||
 | 
					        self.table_row
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) struct ArchetypeSwapRemoveResult {
 | 
					pub(crate) struct ArchetypeSwapRemoveResult {
 | 
				
			||||||
@ -138,9 +148,9 @@ pub(crate) struct ArchetypeComponentInfo {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub struct Archetype {
 | 
					pub struct Archetype {
 | 
				
			||||||
    id: ArchetypeId,
 | 
					    id: ArchetypeId,
 | 
				
			||||||
    entities: Vec<Entity>,
 | 
					    table_id: TableId,
 | 
				
			||||||
    edges: Edges,
 | 
					    edges: Edges,
 | 
				
			||||||
    table_info: TableInfo,
 | 
					    entities: Vec<ArchetypeEntity>,
 | 
				
			||||||
    table_components: Box<[ComponentId]>,
 | 
					    table_components: Box<[ComponentId]>,
 | 
				
			||||||
    sparse_set_components: Box<[ComponentId]>,
 | 
					    sparse_set_components: Box<[ComponentId]>,
 | 
				
			||||||
    components: SparseSet<ComponentId, ArchetypeComponentInfo>,
 | 
					    components: SparseSet<ComponentId, ArchetypeComponentInfo>,
 | 
				
			||||||
@ -183,14 +193,11 @@ impl Archetype {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            id,
 | 
					            id,
 | 
				
			||||||
            table_info: TableInfo {
 | 
					            table_id,
 | 
				
			||||||
                id: table_id,
 | 
					            entities: Vec::new(),
 | 
				
			||||||
                entity_rows: Default::default(),
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            components,
 | 
					            components,
 | 
				
			||||||
            table_components,
 | 
					            table_components,
 | 
				
			||||||
            sparse_set_components,
 | 
					            sparse_set_components,
 | 
				
			||||||
            entities: Default::default(),
 | 
					 | 
				
			||||||
            edges: Default::default(),
 | 
					            edges: Default::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -202,19 +209,14 @@ impl Archetype {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn table_id(&self) -> TableId {
 | 
					    pub fn table_id(&self) -> TableId {
 | 
				
			||||||
        self.table_info.id
 | 
					        self.table_id
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn entities(&self) -> &[Entity] {
 | 
					    pub fn entities(&self) -> &[ArchetypeEntity] {
 | 
				
			||||||
        &self.entities
 | 
					        &self.entities
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn entity_table_rows(&self) -> &[usize] {
 | 
					 | 
				
			||||||
        &self.table_info.entity_rows
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn table_components(&self) -> &[ComponentId] {
 | 
					    pub fn table_components(&self) -> &[ComponentId] {
 | 
				
			||||||
        &self.table_components
 | 
					        &self.table_components
 | 
				
			||||||
@ -242,20 +244,19 @@ impl Archetype {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn entity_table_row(&self, index: usize) -> usize {
 | 
					    pub fn entity_table_row(&self, index: usize) -> usize {
 | 
				
			||||||
        self.table_info.entity_rows[index]
 | 
					        self.entities[index].table_row
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub(crate) fn set_entity_table_row(&mut self, index: usize, table_row: usize) {
 | 
					    pub(crate) fn set_entity_table_row(&mut self, index: usize, table_row: usize) {
 | 
				
			||||||
        self.table_info.entity_rows[index] = table_row;
 | 
					        self.entities[index].table_row = table_row;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// # Safety
 | 
					    /// # Safety
 | 
				
			||||||
    /// valid component values must be immediately written to the relevant storages
 | 
					    /// valid component values must be immediately written to the relevant storages
 | 
				
			||||||
    /// `table_row` must be valid
 | 
					    /// `table_row` must be valid
 | 
				
			||||||
    pub(crate) unsafe fn allocate(&mut self, entity: Entity, table_row: usize) -> EntityLocation {
 | 
					    pub(crate) unsafe fn allocate(&mut self, entity: Entity, table_row: usize) -> EntityLocation {
 | 
				
			||||||
        self.entities.push(entity);
 | 
					        self.entities.push(ArchetypeEntity { entity, table_row });
 | 
				
			||||||
        self.table_info.entity_rows.push(table_row);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        EntityLocation {
 | 
					        EntityLocation {
 | 
				
			||||||
            archetype_id: self.id,
 | 
					            archetype_id: self.id,
 | 
				
			||||||
@ -265,21 +266,20 @@ impl Archetype {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub(crate) fn reserve(&mut self, additional: usize) {
 | 
					    pub(crate) fn reserve(&mut self, additional: usize) {
 | 
				
			||||||
        self.entities.reserve(additional);
 | 
					        self.entities.reserve(additional);
 | 
				
			||||||
        self.table_info.entity_rows.reserve(additional);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Removes the entity at `index` by swapping it out. Returns the table row the entity is stored
 | 
					    /// Removes the entity at `index` by swapping it out. Returns the table row the entity is stored
 | 
				
			||||||
    /// in.
 | 
					    /// in.
 | 
				
			||||||
    pub(crate) fn swap_remove(&mut self, index: usize) -> ArchetypeSwapRemoveResult {
 | 
					    pub(crate) fn swap_remove(&mut self, index: usize) -> ArchetypeSwapRemoveResult {
 | 
				
			||||||
        let is_last = index == self.entities.len() - 1;
 | 
					        let is_last = index == self.entities.len() - 1;
 | 
				
			||||||
        self.entities.swap_remove(index);
 | 
					        let entity = self.entities.swap_remove(index);
 | 
				
			||||||
        ArchetypeSwapRemoveResult {
 | 
					        ArchetypeSwapRemoveResult {
 | 
				
			||||||
            swapped_entity: if is_last {
 | 
					            swapped_entity: if is_last {
 | 
				
			||||||
                None
 | 
					                None
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                Some(self.entities[index])
 | 
					                Some(self.entities[index].entity)
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            table_row: self.table_info.entity_rows.swap_remove(index),
 | 
					            table_row: entity.table_row,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -317,7 +317,6 @@ impl Archetype {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub(crate) fn clear_entities(&mut self) {
 | 
					    pub(crate) fn clear_entities(&mut self) {
 | 
				
			||||||
        self.entities.clear();
 | 
					        self.entities.clear();
 | 
				
			||||||
        self.table_info.entity_rows.clear();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -540,8 +540,8 @@ mod tests {
 | 
				
			|||||||
        let f = world
 | 
					        let f = world
 | 
				
			||||||
            .spawn((TableStored("def"), A(456), SparseStored(1)))
 | 
					            .spawn((TableStored("def"), A(456), SparseStored(1)))
 | 
				
			||||||
            .id();
 | 
					            .id();
 | 
				
			||||||
        // // this should be skipped
 | 
					        // this should be skipped
 | 
				
			||||||
        // SparseStored(1).spawn("abc");
 | 
					        // world.spawn(SparseStored(1));
 | 
				
			||||||
        let ents = world
 | 
					        let ents = world
 | 
				
			||||||
            .query::<(Entity, Option<&SparseStored>, &A)>()
 | 
					            .query::<(Entity, Option<&SparseStored>, &A)>()
 | 
				
			||||||
            .iter(&world)
 | 
					            .iter(&world)
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ use crate::{
 | 
				
			|||||||
    component::{Component, ComponentId, ComponentStorage, ComponentTicks, StorageType},
 | 
					    component::{Component, ComponentId, ComponentStorage, ComponentTicks, StorageType},
 | 
				
			||||||
    entity::Entity,
 | 
					    entity::Entity,
 | 
				
			||||||
    query::{debug_checked_unreachable, Access, FilteredAccess},
 | 
					    query::{debug_checked_unreachable, Access, FilteredAccess},
 | 
				
			||||||
    storage::{ComponentSparseSet, Table, Tables},
 | 
					    storage::{ComponentSparseSet, Table},
 | 
				
			||||||
    world::{Mut, World},
 | 
					    world::{Mut, World},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_ecs_macros::all_tuples;
 | 
					use bevy_ecs_macros::all_tuples;
 | 
				
			||||||
@ -285,11 +285,10 @@ use std::{cell::UnsafeCell, marker::PhantomData};
 | 
				
			|||||||
/// exactly reflects the results of the following methods:
 | 
					/// exactly reflects the results of the following methods:
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// - [`matches_component_set`]
 | 
					/// - [`matches_component_set`]
 | 
				
			||||||
/// - [`archetype_fetch`]
 | 
					/// - [`fetch`]
 | 
				
			||||||
/// - [`table_fetch`]
 | 
					 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// [`Added`]: crate::query::Added
 | 
					/// [`Added`]: crate::query::Added
 | 
				
			||||||
/// [`archetype_fetch`]: Self::archetype_fetch
 | 
					/// [`fetch`]: Self::fetch
 | 
				
			||||||
/// [`Changed`]: crate::query::Changed
 | 
					/// [`Changed`]: crate::query::Changed
 | 
				
			||||||
/// [`Fetch`]: crate::query::WorldQueryGats::Fetch
 | 
					/// [`Fetch`]: crate::query::WorldQueryGats::Fetch
 | 
				
			||||||
/// [`matches_component_set`]: Self::matches_component_set
 | 
					/// [`matches_component_set`]: Self::matches_component_set
 | 
				
			||||||
@ -297,7 +296,6 @@ use std::{cell::UnsafeCell, marker::PhantomData};
 | 
				
			|||||||
/// [`Query`]: crate::system::Query
 | 
					/// [`Query`]: crate::system::Query
 | 
				
			||||||
/// [`ReadOnly`]: Self::ReadOnly
 | 
					/// [`ReadOnly`]: Self::ReadOnly
 | 
				
			||||||
/// [`State`]: Self::State
 | 
					/// [`State`]: Self::State
 | 
				
			||||||
/// [`table_fetch`]: Self::table_fetch
 | 
					 | 
				
			||||||
/// [`update_archetype_component_access`]: Self::update_archetype_component_access
 | 
					/// [`update_archetype_component_access`]: Self::update_archetype_component_access
 | 
				
			||||||
/// [`update_component_access`]: Self::update_component_access
 | 
					/// [`update_component_access`]: Self::update_component_access
 | 
				
			||||||
/// [`With`]: crate::query::With
 | 
					/// [`With`]: crate::query::With
 | 
				
			||||||
@ -339,9 +337,10 @@ pub unsafe trait WorldQuery: for<'w> WorldQueryGats<'w> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Returns true if (and only if) every table of every archetype matched by this fetch contains
 | 
					    /// Returns true if (and only if) every table of every archetype matched by this fetch contains
 | 
				
			||||||
    /// all of the matched components. This is used to select a more efficient "table iterator"
 | 
					    /// all of the matched components. This is used to select a more efficient "table iterator"
 | 
				
			||||||
    /// for "dense" queries. If this returns true, [`WorldQuery::set_table`] and [`WorldQuery::table_fetch`]
 | 
					    /// for "dense" queries. If this returns true, [`WorldQuery::set_table`] must be used before
 | 
				
			||||||
    /// will be called for iterators. If this returns false, [`WorldQuery::set_archetype`] and
 | 
					    /// [`WorldQuery::fetch`] can be called for iterators. If this returns false,
 | 
				
			||||||
    /// [`WorldQuery::archetype_fetch`] will be called for iterators.
 | 
					    /// [`WorldQuery::set_archetype`] must be used before [`WorldQuery::fetch`] can be called for
 | 
				
			||||||
 | 
					    /// iterators.
 | 
				
			||||||
    const IS_DENSE: bool;
 | 
					    const IS_DENSE: bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Returns true if (and only if) this Fetch relies strictly on archetypes to limit which
 | 
					    /// Returns true if (and only if) this Fetch relies strictly on archetypes to limit which
 | 
				
			||||||
@ -362,7 +361,7 @@ pub unsafe trait WorldQuery: for<'w> WorldQueryGats<'w> {
 | 
				
			|||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
        state: &Self::State,
 | 
					        state: &Self::State,
 | 
				
			||||||
        archetype: &'w Archetype,
 | 
					        archetype: &'w Archetype,
 | 
				
			||||||
        tables: &'w Tables,
 | 
					        table: &'w Table,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Adjusts internal state to account for the next [`Table`]. This will always be called on tables
 | 
					    /// Adjusts internal state to account for the next [`Table`]. This will always be called on tables
 | 
				
			||||||
@ -378,51 +377,30 @@ pub unsafe trait WorldQuery: for<'w> WorldQueryGats<'w> {
 | 
				
			|||||||
        table: &'w Table,
 | 
					        table: &'w Table,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Fetch [`Self::Item`](`WorldQueryGats::Item`) for the given `archetype_index` in the current [`Archetype`]. This must
 | 
					    /// Fetch [`Self::Item`](`WorldQueryGats::Item`) for either the given `entity` in the current [`Table`],
 | 
				
			||||||
    /// always be called after [`WorldQuery::set_archetype`] with an `archetype_index` in the range of
 | 
					    /// or for the given `entity` in the current [`Archetype`]. This must always be called after
 | 
				
			||||||
    /// the current [`Archetype`]
 | 
					    /// [`WorldQuery::set_table`] with a `table_row` in the range of the current [`Table`] or after
 | 
				
			||||||
    ///
 | 
					    /// [`WorldQuery::set_archetype`]  with a `entity` in the current archetype.
 | 
				
			||||||
    /// # Safety
 | 
					 | 
				
			||||||
    /// Must always be called _after_ [`WorldQuery::set_archetype`]. `archetype_index` must be in the range
 | 
					 | 
				
			||||||
    /// of the current archetype
 | 
					 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					 | 
				
			||||||
        archetype_index: usize,
 | 
					 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Fetch [`Self::Item`](`WorldQueryGats::Item`) for the given `table_row` in the current [`Table`]. This must always be
 | 
					 | 
				
			||||||
    /// called after [`WorldQuery::set_table`] with a `table_row` in the range of the current [`Table`]
 | 
					 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// # Safety
 | 
					    /// # Safety
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Must always be called _after_ [`WorldQuery::set_table`]. `table_row` must be in the range of the
 | 
					    /// Must always be called _after_ [`WorldQuery::set_table`] or [`WorldQuery::set_archetype`]. `entity` and
 | 
				
			||||||
    /// current table
 | 
					    /// `table_row` must be in the range of the current table and archetype.
 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					        entity: Entity,
 | 
				
			||||||
        table_row: usize,
 | 
					        table_row: usize,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item;
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// # Safety
 | 
					    /// # Safety
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Must always be called _after_ [`WorldQuery::set_archetype`]. `archetype_index` must be in the range
 | 
					    /// Must always be called _after_ [`WorldQuery::set_table`] or [`WorldQuery::set_archetype`]. `entity` and
 | 
				
			||||||
    /// of the current archetype.
 | 
					    /// `table_row` must be in the range of the current table and archetype.
 | 
				
			||||||
    #[allow(unused_variables)]
 | 
					    #[allow(unused_variables)]
 | 
				
			||||||
    #[inline]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn archetype_filter_fetch(
 | 
					    unsafe fn filter_fetch(
 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'_>>::Fetch,
 | 
					 | 
				
			||||||
        archetype_index: usize,
 | 
					 | 
				
			||||||
    ) -> bool {
 | 
					 | 
				
			||||||
        true
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// # Safety
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Must always be called _after_ [`WorldQuery::set_table`]. `table_row` must be in the range of the
 | 
					 | 
				
			||||||
    /// current table.
 | 
					 | 
				
			||||||
    #[allow(unused_variables)]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn table_filter_fetch(
 | 
					 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'_>>::Fetch,
 | 
					        fetch: &mut <Self as WorldQueryGats<'_>>::Fetch,
 | 
				
			||||||
 | 
					        entity: Entity,
 | 
				
			||||||
        table_row: usize,
 | 
					        table_row: usize,
 | 
				
			||||||
    ) -> bool {
 | 
					    ) -> bool {
 | 
				
			||||||
        true
 | 
					        true
 | 
				
			||||||
@ -470,11 +448,6 @@ pub type ROQueryFetch<'w, Q> = QueryFetch<'w, <Q as WorldQuery>::ReadOnly>;
 | 
				
			|||||||
/// The read-only variant of the item type returned when a [`WorldQuery`] is iterated over immutably
 | 
					/// The read-only variant of the item type returned when a [`WorldQuery`] is iterated over immutably
 | 
				
			||||||
pub type ROQueryItem<'w, Q> = QueryItem<'w, <Q as WorldQuery>::ReadOnly>;
 | 
					pub type ROQueryItem<'w, Q> = QueryItem<'w, <Q as WorldQuery>::ReadOnly>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
pub struct EntityFetch<'w> {
 | 
					 | 
				
			||||||
    entities: Option<ThinSlicePtr<'w, Entity>>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// SAFETY: no component or archetype access
 | 
					/// SAFETY: no component or archetype access
 | 
				
			||||||
unsafe impl WorldQuery for Entity {
 | 
					unsafe impl WorldQuery for Entity {
 | 
				
			||||||
    type ReadOnly = Self;
 | 
					    type ReadOnly = Self;
 | 
				
			||||||
@ -490,56 +463,41 @@ unsafe impl WorldQuery for Entity {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    unsafe fn init_fetch<'w>(
 | 
					    unsafe fn init_fetch<'w>(
 | 
				
			||||||
        _world: &'w World,
 | 
					        _world: &'w World,
 | 
				
			||||||
        _state: &(),
 | 
					        _state: &Self::State,
 | 
				
			||||||
        _last_change_tick: u32,
 | 
					        _last_change_tick: u32,
 | 
				
			||||||
        _change_tick: u32,
 | 
					        _change_tick: u32,
 | 
				
			||||||
    ) -> EntityFetch<'w> {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
				
			||||||
        EntityFetch { entities: None }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe fn clone_fetch<'w>(
 | 
					    unsafe fn clone_fetch<'w>(
 | 
				
			||||||
        fetch: &<Self as WorldQueryGats<'w>>::Fetch,
 | 
					        _fetch: &<Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
				
			||||||
        EntityFetch {
 | 
					 | 
				
			||||||
            entities: fetch.entities,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn set_archetype<'w>(
 | 
					    unsafe fn set_archetype<'w>(
 | 
				
			||||||
        fetch: &mut EntityFetch<'w>,
 | 
					        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
        _state: &(),
 | 
					        _state: &Self::State,
 | 
				
			||||||
        archetype: &'w Archetype,
 | 
					        _archetype: &'w Archetype,
 | 
				
			||||||
        _tables: &Tables,
 | 
					        _table: &Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        fetch.entities = Some(archetype.entities().into());
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn set_table<'w>(fetch: &mut EntityFetch<'w>, _state: &(), table: &'w Table) {
 | 
					    unsafe fn set_table<'w>(
 | 
				
			||||||
        fetch.entities = Some(table.entities().into());
 | 
					        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					        _state: &Self::State,
 | 
				
			||||||
 | 
					        _table: &'w Table,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
        table_row: usize,
 | 
					        entity: Entity,
 | 
				
			||||||
    ) -> QueryItem<'w, Self> {
 | 
					        _table_row: usize,
 | 
				
			||||||
        let entities = fetch
 | 
					 | 
				
			||||||
            .entities
 | 
					 | 
				
			||||||
            .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
        *entities.get(table_row)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					 | 
				
			||||||
        archetype_index: usize,
 | 
					 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
        let entities = fetch
 | 
					        entity
 | 
				
			||||||
            .entities
 | 
					 | 
				
			||||||
            .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
        *entities.get(archetype_index)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
 | 
					    fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
 | 
				
			||||||
@ -562,7 +520,7 @@ unsafe impl WorldQuery for Entity {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w> WorldQueryGats<'w> for Entity {
 | 
					impl<'w> WorldQueryGats<'w> for Entity {
 | 
				
			||||||
    type Fetch = EntityFetch<'w>;
 | 
					    type Fetch = ();
 | 
				
			||||||
    type Item = Entity;
 | 
					    type Item = Entity;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -573,9 +531,7 @@ unsafe impl ReadOnlyWorldQuery for Entity {}
 | 
				
			|||||||
pub struct ReadFetch<'w, T> {
 | 
					pub struct ReadFetch<'w, T> {
 | 
				
			||||||
    // T::Storage = TableStorage
 | 
					    // T::Storage = TableStorage
 | 
				
			||||||
    table_components: Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
 | 
					    table_components: Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
 | 
				
			||||||
    entity_table_rows: Option<ThinSlicePtr<'w, usize>>,
 | 
					 | 
				
			||||||
    // T::Storage = SparseStorage
 | 
					    // T::Storage = SparseStorage
 | 
				
			||||||
    entities: Option<ThinSlicePtr<'w, Entity>>,
 | 
					 | 
				
			||||||
    sparse_set: Option<&'w ComponentSparseSet>,
 | 
					    sparse_set: Option<&'w ComponentSparseSet>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -605,10 +561,13 @@ unsafe impl<T: Component> WorldQuery for &T {
 | 
				
			|||||||
    ) -> ReadFetch<'w, T> {
 | 
					    ) -> ReadFetch<'w, T> {
 | 
				
			||||||
        ReadFetch {
 | 
					        ReadFetch {
 | 
				
			||||||
            table_components: None,
 | 
					            table_components: None,
 | 
				
			||||||
            entity_table_rows: None,
 | 
					            sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
 | 
				
			||||||
            entities: None,
 | 
					                world
 | 
				
			||||||
            sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet)
 | 
					                    .storages()
 | 
				
			||||||
                .then(|| world.storages().sparse_sets.get(component_id).unwrap()),
 | 
					                    .sparse_sets
 | 
				
			||||||
 | 
					                    .get(component_id)
 | 
				
			||||||
 | 
					                    .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -617,8 +576,6 @@ unsafe impl<T: Component> WorldQuery for &T {
 | 
				
			|||||||
    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
				
			||||||
        ReadFetch {
 | 
					        ReadFetch {
 | 
				
			||||||
            table_components: fetch.table_components,
 | 
					            table_components: fetch.table_components,
 | 
				
			||||||
            entity_table_rows: fetch.entity_table_rows,
 | 
					 | 
				
			||||||
            entities: fetch.entities,
 | 
					 | 
				
			||||||
            sparse_set: fetch.sparse_set,
 | 
					            sparse_set: fetch.sparse_set,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -626,64 +583,49 @@ unsafe impl<T: Component> WorldQuery for &T {
 | 
				
			|||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn set_archetype<'w>(
 | 
					    unsafe fn set_archetype<'w>(
 | 
				
			||||||
        fetch: &mut ReadFetch<'w, T>,
 | 
					        fetch: &mut ReadFetch<'w, T>,
 | 
				
			||||||
        &component_id: &ComponentId,
 | 
					        component_id: &ComponentId,
 | 
				
			||||||
        archetype: &'w Archetype,
 | 
					        _archetype: &'w Archetype,
 | 
				
			||||||
        tables: &'w Tables,
 | 
					        table: &'w Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        match T::Storage::STORAGE_TYPE {
 | 
					        if Self::IS_DENSE {
 | 
				
			||||||
            StorageType::Table => {
 | 
					            Self::set_table(fetch, component_id, table);
 | 
				
			||||||
                fetch.entity_table_rows = Some(archetype.entity_table_rows().into());
 | 
					 | 
				
			||||||
                let column = tables[archetype.table_id()]
 | 
					 | 
				
			||||||
                    .get_column(component_id)
 | 
					 | 
				
			||||||
                    .unwrap();
 | 
					 | 
				
			||||||
                fetch.table_components = Some(column.get_data_slice().into());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            StorageType::SparseSet => fetch.entities = Some(archetype.entities().into()),
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn set_table<'w>(fetch: &mut ReadFetch<'w, T>, &id: &ComponentId, table: &'w Table) {
 | 
					    unsafe fn set_table<'w>(
 | 
				
			||||||
        fetch.table_components = Some(table.get_column(id).unwrap().get_data_slice().into());
 | 
					        fetch: &mut ReadFetch<'w, T>,
 | 
				
			||||||
 | 
					        &component_id: &ComponentId,
 | 
				
			||||||
 | 
					        table: &'w Table,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        fetch.table_components = Some(
 | 
				
			||||||
 | 
					            table
 | 
				
			||||||
 | 
					                .get_column(component_id)
 | 
				
			||||||
 | 
					                .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                .get_data_slice()
 | 
				
			||||||
 | 
					                .into(),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					 | 
				
			||||||
        archetype_index: usize,
 | 
					 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					 | 
				
			||||||
        match T::Storage::STORAGE_TYPE {
 | 
					 | 
				
			||||||
            StorageType::Table => {
 | 
					 | 
				
			||||||
                let (entity_table_rows, table_components) = fetch
 | 
					 | 
				
			||||||
                    .entity_table_rows
 | 
					 | 
				
			||||||
                    .zip(fetch.table_components)
 | 
					 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
                let table_row = *entity_table_rows.get(archetype_index);
 | 
					 | 
				
			||||||
                table_components.get(table_row).deref()
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            StorageType::SparseSet => {
 | 
					 | 
				
			||||||
                let (entities, sparse_set) = fetch
 | 
					 | 
				
			||||||
                    .entities
 | 
					 | 
				
			||||||
                    .zip(fetch.sparse_set)
 | 
					 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
                let entity = *entities.get(archetype_index);
 | 
					 | 
				
			||||||
                sparse_set
 | 
					 | 
				
			||||||
                    .get(entity)
 | 
					 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable())
 | 
					 | 
				
			||||||
                    .deref::<T>()
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					        entity: Entity,
 | 
				
			||||||
        table_row: usize,
 | 
					        table_row: usize,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
        let components = fetch
 | 
					        match T::Storage::STORAGE_TYPE {
 | 
				
			||||||
            .table_components
 | 
					            StorageType::Table => fetch
 | 
				
			||||||
            .unwrap_or_else(|| debug_checked_unreachable());
 | 
					                .table_components
 | 
				
			||||||
        components.get(table_row).deref()
 | 
					                .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                .get(table_row)
 | 
				
			||||||
 | 
					                .deref(),
 | 
				
			||||||
 | 
					            StorageType::SparseSet => fetch
 | 
				
			||||||
 | 
					                .sparse_set
 | 
				
			||||||
 | 
					                .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                .get(entity)
 | 
				
			||||||
 | 
					                .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                .deref(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn update_component_access(
 | 
					    fn update_component_access(
 | 
				
			||||||
@ -731,11 +673,11 @@ impl<'w, T: Component> WorldQueryGats<'w> for &T {
 | 
				
			|||||||
#[doc(hidden)]
 | 
					#[doc(hidden)]
 | 
				
			||||||
pub struct WriteFetch<'w, T> {
 | 
					pub struct WriteFetch<'w, T> {
 | 
				
			||||||
    // T::Storage = TableStorage
 | 
					    // T::Storage = TableStorage
 | 
				
			||||||
    table_components: Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
 | 
					    table_data: Option<(
 | 
				
			||||||
    table_ticks: Option<ThinSlicePtr<'w, UnsafeCell<ComponentTicks>>>,
 | 
					        ThinSlicePtr<'w, UnsafeCell<T>>,
 | 
				
			||||||
    entity_table_rows: Option<ThinSlicePtr<'w, usize>>,
 | 
					        ThinSlicePtr<'w, UnsafeCell<ComponentTicks>>,
 | 
				
			||||||
 | 
					    )>,
 | 
				
			||||||
    // T::Storage = SparseStorage
 | 
					    // T::Storage = SparseStorage
 | 
				
			||||||
    entities: Option<ThinSlicePtr<'w, Entity>>,
 | 
					 | 
				
			||||||
    sparse_set: Option<&'w ComponentSparseSet>,
 | 
					    sparse_set: Option<&'w ComponentSparseSet>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    last_change_tick: u32,
 | 
					    last_change_tick: u32,
 | 
				
			||||||
@ -767,12 +709,14 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
 | 
				
			|||||||
        change_tick: u32,
 | 
					        change_tick: u32,
 | 
				
			||||||
    ) -> WriteFetch<'w, T> {
 | 
					    ) -> WriteFetch<'w, T> {
 | 
				
			||||||
        WriteFetch {
 | 
					        WriteFetch {
 | 
				
			||||||
            table_components: None,
 | 
					            table_data: None,
 | 
				
			||||||
            entities: None,
 | 
					            sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
 | 
				
			||||||
            entity_table_rows: None,
 | 
					                world
 | 
				
			||||||
            sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet)
 | 
					                    .storages()
 | 
				
			||||||
                .then(|| world.storages().sparse_sets.get(component_id).unwrap()),
 | 
					                    .sparse_sets
 | 
				
			||||||
            table_ticks: None,
 | 
					                    .get(component_id)
 | 
				
			||||||
 | 
					                    .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
            last_change_tick,
 | 
					            last_change_tick,
 | 
				
			||||||
            change_tick,
 | 
					            change_tick,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -782,10 +726,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
 | 
				
			|||||||
        fetch: &<Self as WorldQueryGats<'w>>::Fetch,
 | 
					        fetch: &<Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
				
			||||||
        WriteFetch {
 | 
					        WriteFetch {
 | 
				
			||||||
            table_components: fetch.table_components,
 | 
					            table_data: fetch.table_data,
 | 
				
			||||||
            table_ticks: fetch.table_ticks,
 | 
					 | 
				
			||||||
            entities: fetch.entities,
 | 
					 | 
				
			||||||
            entity_table_rows: fetch.entity_table_rows,
 | 
					 | 
				
			||||||
            sparse_set: fetch.sparse_set,
 | 
					            sparse_set: fetch.sparse_set,
 | 
				
			||||||
            last_change_tick: fetch.last_change_tick,
 | 
					            last_change_tick: fetch.last_change_tick,
 | 
				
			||||||
            change_tick: fetch.change_tick,
 | 
					            change_tick: fetch.change_tick,
 | 
				
			||||||
@ -795,20 +736,12 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
 | 
				
			|||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn set_archetype<'w>(
 | 
					    unsafe fn set_archetype<'w>(
 | 
				
			||||||
        fetch: &mut WriteFetch<'w, T>,
 | 
					        fetch: &mut WriteFetch<'w, T>,
 | 
				
			||||||
        &component_id: &ComponentId,
 | 
					        component_id: &ComponentId,
 | 
				
			||||||
        archetype: &'w Archetype,
 | 
					        _archetype: &'w Archetype,
 | 
				
			||||||
        tables: &'w Tables,
 | 
					        table: &'w Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        match T::Storage::STORAGE_TYPE {
 | 
					        if Self::IS_DENSE {
 | 
				
			||||||
            StorageType::Table => {
 | 
					            Self::set_table(fetch, component_id, table);
 | 
				
			||||||
                fetch.entity_table_rows = Some(archetype.entity_table_rows().into());
 | 
					 | 
				
			||||||
                let column = tables[archetype.table_id()]
 | 
					 | 
				
			||||||
                    .get_column(component_id)
 | 
					 | 
				
			||||||
                    .unwrap();
 | 
					 | 
				
			||||||
                fetch.table_components = Some(column.get_data_slice().into());
 | 
					 | 
				
			||||||
                fetch.table_ticks = Some(column.get_ticks_slice().into());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            StorageType::SparseSet => fetch.entities = Some(archetype.entities().into()),
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -818,23 +751,26 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
 | 
				
			|||||||
        &component_id: &ComponentId,
 | 
					        &component_id: &ComponentId,
 | 
				
			||||||
        table: &'w Table,
 | 
					        table: &'w Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        let column = table.get_column(component_id).unwrap();
 | 
					        let column = table
 | 
				
			||||||
        fetch.table_components = Some(column.get_data_slice().into());
 | 
					            .get_column(component_id)
 | 
				
			||||||
        fetch.table_ticks = Some(column.get_ticks_slice().into());
 | 
					            .unwrap_or_else(|| debug_checked_unreachable());
 | 
				
			||||||
 | 
					        fetch.table_data = Some((
 | 
				
			||||||
 | 
					            column.get_data_slice().into(),
 | 
				
			||||||
 | 
					            column.get_ticks_slice().into(),
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
        archetype_index: usize,
 | 
					        entity: Entity,
 | 
				
			||||||
 | 
					        table_row: usize,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
        match T::Storage::STORAGE_TYPE {
 | 
					        match T::Storage::STORAGE_TYPE {
 | 
				
			||||||
            StorageType::Table => {
 | 
					            StorageType::Table => {
 | 
				
			||||||
                let (entity_table_rows, (table_components, table_ticks)) = fetch
 | 
					                let (table_components, table_ticks) = fetch
 | 
				
			||||||
                    .entity_table_rows
 | 
					                    .table_data
 | 
				
			||||||
                    .zip(fetch.table_components.zip(fetch.table_ticks))
 | 
					 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
					                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
				
			||||||
                let table_row = *entity_table_rows.get(archetype_index);
 | 
					 | 
				
			||||||
                Mut {
 | 
					                Mut {
 | 
				
			||||||
                    value: table_components.get(table_row).deref_mut(),
 | 
					                    value: table_components.get(table_row).deref_mut(),
 | 
				
			||||||
                    ticks: Ticks {
 | 
					                    ticks: Ticks {
 | 
				
			||||||
@ -845,12 +781,9 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            StorageType::SparseSet => {
 | 
					            StorageType::SparseSet => {
 | 
				
			||||||
                let (entities, sparse_set) = fetch
 | 
					                let (component, component_ticks) = fetch
 | 
				
			||||||
                    .entities
 | 
					                    .sparse_set
 | 
				
			||||||
                    .zip(fetch.sparse_set)
 | 
					                    .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
                let entity = *entities.get(archetype_index);
 | 
					 | 
				
			||||||
                let (component, component_ticks) = sparse_set
 | 
					 | 
				
			||||||
                    .get_with_ticks(entity)
 | 
					                    .get_with_ticks(entity)
 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
					                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
				
			||||||
                Mut {
 | 
					                Mut {
 | 
				
			||||||
@ -865,25 +798,6 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					 | 
				
			||||||
        table_row: usize,
 | 
					 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					 | 
				
			||||||
        let (table_components, table_ticks) = fetch
 | 
					 | 
				
			||||||
            .table_components
 | 
					 | 
				
			||||||
            .zip(fetch.table_ticks)
 | 
					 | 
				
			||||||
            .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
        Mut {
 | 
					 | 
				
			||||||
            value: table_components.get(table_row).deref_mut(),
 | 
					 | 
				
			||||||
            ticks: Ticks {
 | 
					 | 
				
			||||||
                component_ticks: table_ticks.get(table_row).deref_mut(),
 | 
					 | 
				
			||||||
                change_tick: fetch.change_tick,
 | 
					 | 
				
			||||||
                last_change_tick: fetch.last_change_tick,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn update_component_access(
 | 
					    fn update_component_access(
 | 
				
			||||||
        &component_id: &ComponentId,
 | 
					        &component_id: &ComponentId,
 | 
				
			||||||
        access: &mut FilteredAccess<ComponentId>,
 | 
					        access: &mut FilteredAccess<ComponentId>,
 | 
				
			||||||
@ -968,11 +882,11 @@ unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
 | 
				
			|||||||
        fetch: &mut OptionFetch<'w, T>,
 | 
					        fetch: &mut OptionFetch<'w, T>,
 | 
				
			||||||
        state: &T::State,
 | 
					        state: &T::State,
 | 
				
			||||||
        archetype: &'w Archetype,
 | 
					        archetype: &'w Archetype,
 | 
				
			||||||
        tables: &'w Tables,
 | 
					        table: &'w Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        fetch.matches = T::matches_component_set(state, &|id| archetype.contains(id));
 | 
					        fetch.matches = T::matches_component_set(state, &|id| archetype.contains(id));
 | 
				
			||||||
        if fetch.matches {
 | 
					        if fetch.matches {
 | 
				
			||||||
            T::set_archetype(&mut fetch.fetch, state, archetype, tables);
 | 
					            T::set_archetype(&mut fetch.fetch, state, archetype, table);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -984,28 +898,15 @@ unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					 | 
				
			||||||
        archetype_index: usize,
 | 
					 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					 | 
				
			||||||
        if fetch.matches {
 | 
					 | 
				
			||||||
            Some(T::archetype_fetch(&mut fetch.fetch, archetype_index))
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            None
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					        entity: Entity,
 | 
				
			||||||
        table_row: usize,
 | 
					        table_row: usize,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
        if fetch.matches {
 | 
					        fetch
 | 
				
			||||||
            Some(T::table_fetch(&mut fetch.fetch, table_row))
 | 
					            .matches
 | 
				
			||||||
        } else {
 | 
					            .then(|| T::fetch(&mut fetch.fetch, entity, table_row))
 | 
				
			||||||
            None
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn update_component_access(state: &T::State, access: &mut FilteredAccess<ComponentId>) {
 | 
					    fn update_component_access(state: &T::State, access: &mut FilteredAccess<ComponentId>) {
 | 
				
			||||||
@ -1127,9 +1028,7 @@ impl<T: Component> ChangeTrackers<T> {
 | 
				
			|||||||
pub struct ChangeTrackersFetch<'w, T> {
 | 
					pub struct ChangeTrackersFetch<'w, T> {
 | 
				
			||||||
    // T::Storage = TableStorage
 | 
					    // T::Storage = TableStorage
 | 
				
			||||||
    table_ticks: Option<ThinSlicePtr<'w, UnsafeCell<ComponentTicks>>>,
 | 
					    table_ticks: Option<ThinSlicePtr<'w, UnsafeCell<ComponentTicks>>>,
 | 
				
			||||||
    entity_table_rows: Option<ThinSlicePtr<'w, usize>>,
 | 
					 | 
				
			||||||
    // T::Storage = SparseStorage
 | 
					    // T::Storage = SparseStorage
 | 
				
			||||||
    entities: Option<ThinSlicePtr<'w, Entity>>,
 | 
					 | 
				
			||||||
    sparse_set: Option<&'w ComponentSparseSet>,
 | 
					    sparse_set: Option<&'w ComponentSparseSet>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    marker: PhantomData<T>,
 | 
					    marker: PhantomData<T>,
 | 
				
			||||||
@ -1157,16 +1056,19 @@ unsafe impl<T: Component> WorldQuery for ChangeTrackers<T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    unsafe fn init_fetch<'w>(
 | 
					    unsafe fn init_fetch<'w>(
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
        &id: &ComponentId,
 | 
					        &component_id: &ComponentId,
 | 
				
			||||||
        last_change_tick: u32,
 | 
					        last_change_tick: u32,
 | 
				
			||||||
        change_tick: u32,
 | 
					        change_tick: u32,
 | 
				
			||||||
    ) -> ChangeTrackersFetch<'w, T> {
 | 
					    ) -> ChangeTrackersFetch<'w, T> {
 | 
				
			||||||
        ChangeTrackersFetch {
 | 
					        ChangeTrackersFetch {
 | 
				
			||||||
            table_ticks: None,
 | 
					            table_ticks: None,
 | 
				
			||||||
            entities: None,
 | 
					            sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
 | 
				
			||||||
            entity_table_rows: None,
 | 
					                world
 | 
				
			||||||
            sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet)
 | 
					                    .storages()
 | 
				
			||||||
                .then(|| world.storages().sparse_sets.get(id).unwrap()),
 | 
					                    .sparse_sets
 | 
				
			||||||
 | 
					                    .get(component_id)
 | 
				
			||||||
 | 
					                    .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
            marker: PhantomData,
 | 
					            marker: PhantomData,
 | 
				
			||||||
            last_change_tick,
 | 
					            last_change_tick,
 | 
				
			||||||
            change_tick,
 | 
					            change_tick,
 | 
				
			||||||
@ -1178,8 +1080,6 @@ unsafe impl<T: Component> WorldQuery for ChangeTrackers<T> {
 | 
				
			|||||||
    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
				
			||||||
        ChangeTrackersFetch {
 | 
					        ChangeTrackersFetch {
 | 
				
			||||||
            table_ticks: fetch.table_ticks,
 | 
					            table_ticks: fetch.table_ticks,
 | 
				
			||||||
            entity_table_rows: fetch.entity_table_rows,
 | 
					 | 
				
			||||||
            entities: fetch.entities,
 | 
					 | 
				
			||||||
            sparse_set: fetch.sparse_set,
 | 
					            sparse_set: fetch.sparse_set,
 | 
				
			||||||
            marker: fetch.marker,
 | 
					            marker: fetch.marker,
 | 
				
			||||||
            last_change_tick: fetch.last_change_tick,
 | 
					            last_change_tick: fetch.last_change_tick,
 | 
				
			||||||
@ -1190,17 +1090,12 @@ unsafe impl<T: Component> WorldQuery for ChangeTrackers<T> {
 | 
				
			|||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn set_archetype<'w>(
 | 
					    unsafe fn set_archetype<'w>(
 | 
				
			||||||
        fetch: &mut ChangeTrackersFetch<'w, T>,
 | 
					        fetch: &mut ChangeTrackersFetch<'w, T>,
 | 
				
			||||||
        &id: &ComponentId,
 | 
					        component_id: &ComponentId,
 | 
				
			||||||
        archetype: &'w Archetype,
 | 
					        _archetype: &'w Archetype,
 | 
				
			||||||
        tables: &'w Tables,
 | 
					        table: &'w Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        match T::Storage::STORAGE_TYPE {
 | 
					        if Self::IS_DENSE {
 | 
				
			||||||
            StorageType::Table => {
 | 
					            Self::set_table(fetch, component_id, table);
 | 
				
			||||||
                fetch.entity_table_rows = Some(archetype.entity_table_rows().into());
 | 
					 | 
				
			||||||
                let column = tables[archetype.table_id()].get_column(id).unwrap();
 | 
					 | 
				
			||||||
                fetch.table_ticks = Some(column.get_ticks_slice().into());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            StorageType::SparseSet => fetch.entities = Some(archetype.entities().into()),
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1210,68 +1105,44 @@ unsafe impl<T: Component> WorldQuery for ChangeTrackers<T> {
 | 
				
			|||||||
        &id: &ComponentId,
 | 
					        &id: &ComponentId,
 | 
				
			||||||
        table: &'w Table,
 | 
					        table: &'w Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        fetch.table_ticks = Some(table.get_column(id).unwrap().get_ticks_slice().into());
 | 
					        fetch.table_ticks = Some(
 | 
				
			||||||
 | 
					            table
 | 
				
			||||||
 | 
					                .get_column(id)
 | 
				
			||||||
 | 
					                .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                .get_ticks_slice()
 | 
				
			||||||
 | 
					                .into(),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					 | 
				
			||||||
        archetype_index: usize,
 | 
					 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					 | 
				
			||||||
        match T::Storage::STORAGE_TYPE {
 | 
					 | 
				
			||||||
            StorageType::Table => {
 | 
					 | 
				
			||||||
                let entity_table_rows = fetch
 | 
					 | 
				
			||||||
                    .entity_table_rows
 | 
					 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
                let table_row = *entity_table_rows.get(archetype_index);
 | 
					 | 
				
			||||||
                ChangeTrackers {
 | 
					 | 
				
			||||||
                    component_ticks: {
 | 
					 | 
				
			||||||
                        let table_ticks = fetch
 | 
					 | 
				
			||||||
                            .table_ticks
 | 
					 | 
				
			||||||
                            .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
                        table_ticks.get(table_row).read()
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    marker: PhantomData,
 | 
					 | 
				
			||||||
                    last_change_tick: fetch.last_change_tick,
 | 
					 | 
				
			||||||
                    change_tick: fetch.change_tick,
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            StorageType::SparseSet => {
 | 
					 | 
				
			||||||
                let entities = fetch
 | 
					 | 
				
			||||||
                    .entities
 | 
					 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
					 | 
				
			||||||
                let entity = *entities.get(archetype_index);
 | 
					 | 
				
			||||||
                ChangeTrackers {
 | 
					 | 
				
			||||||
                    component_ticks: fetch
 | 
					 | 
				
			||||||
                        .sparse_set
 | 
					 | 
				
			||||||
                        .unwrap_or_else(|| debug_checked_unreachable())
 | 
					 | 
				
			||||||
                        .get_ticks(entity)
 | 
					 | 
				
			||||||
                        .map(|ticks| &*ticks.get())
 | 
					 | 
				
			||||||
                        .cloned()
 | 
					 | 
				
			||||||
                        .unwrap_or_else(|| debug_checked_unreachable()),
 | 
					 | 
				
			||||||
                    marker: PhantomData,
 | 
					 | 
				
			||||||
                    last_change_tick: fetch.last_change_tick,
 | 
					 | 
				
			||||||
                    change_tick: fetch.change_tick,
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					 | 
				
			||||||
        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					        entity: Entity,
 | 
				
			||||||
        table_row: usize,
 | 
					        table_row: usize,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
        ChangeTrackers {
 | 
					        match T::Storage::STORAGE_TYPE {
 | 
				
			||||||
            component_ticks: {
 | 
					            StorageType::Table => ChangeTrackers {
 | 
				
			||||||
                let table_ticks = fetch
 | 
					                component_ticks: {
 | 
				
			||||||
                    .table_ticks
 | 
					                    let table_ticks = fetch
 | 
				
			||||||
                    .unwrap_or_else(|| debug_checked_unreachable());
 | 
					                        .table_ticks
 | 
				
			||||||
                table_ticks.get(table_row).read()
 | 
					                        .unwrap_or_else(|| debug_checked_unreachable());
 | 
				
			||||||
 | 
					                    table_ticks.get(table_row).read()
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                marker: PhantomData,
 | 
				
			||||||
 | 
					                last_change_tick: fetch.last_change_tick,
 | 
				
			||||||
 | 
					                change_tick: fetch.change_tick,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            StorageType::SparseSet => ChangeTrackers {
 | 
				
			||||||
 | 
					                component_ticks: *fetch
 | 
				
			||||||
 | 
					                    .sparse_set
 | 
				
			||||||
 | 
					                    .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                    .get_ticks(entity)
 | 
				
			||||||
 | 
					                    .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                    .get(),
 | 
				
			||||||
 | 
					                marker: PhantomData,
 | 
				
			||||||
 | 
					                last_change_tick: fetch.last_change_tick,
 | 
				
			||||||
 | 
					                change_tick: fetch.change_tick,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            marker: PhantomData,
 | 
					 | 
				
			||||||
            last_change_tick: fetch.last_change_tick,
 | 
					 | 
				
			||||||
            change_tick: fetch.change_tick,
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1355,10 +1226,15 @@ macro_rules! impl_tuple_fetch {
 | 
				
			|||||||
            const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
 | 
					            const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline]
 | 
				
			||||||
            unsafe fn set_archetype<'w>(_fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, _state: &Self::State, _archetype: &'w Archetype, _tables: &'w Tables) {
 | 
					            unsafe fn set_archetype<'w>(
 | 
				
			||||||
 | 
					                _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                _state: &Self::State,
 | 
				
			||||||
 | 
					                _archetype: &'w Archetype,
 | 
				
			||||||
 | 
					                _table: &'w Table
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
                let ($($name,)*) = _fetch;
 | 
					                let ($($name,)*) = _fetch;
 | 
				
			||||||
                let ($($state,)*) = _state;
 | 
					                let ($($state,)*) = _state;
 | 
				
			||||||
                $($name::set_archetype($name, $state, _archetype, _tables);)*
 | 
					                $($name::set_archetype($name, $state, _archetype, _table);)*
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline]
 | 
				
			||||||
@ -1368,32 +1244,25 @@ macro_rules! impl_tuple_fetch {
 | 
				
			|||||||
                $($name::set_table($name, $state, _table);)*
 | 
					                $($name::set_table($name, $state, _table);)*
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline(always)]
 | 
				
			||||||
            #[allow(clippy::unused_unit)]
 | 
					            #[allow(clippy::unused_unit)]
 | 
				
			||||||
            unsafe fn table_fetch<'w>(_fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, _table_row: usize) -> QueryItem<'w, Self> {
 | 
					            unsafe fn fetch<'w>(
 | 
				
			||||||
 | 
					                _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                _entity: Entity,
 | 
				
			||||||
 | 
					                _table_row: usize
 | 
				
			||||||
 | 
					            ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
                let ($($name,)*) = _fetch;
 | 
					                let ($($name,)*) = _fetch;
 | 
				
			||||||
                ($($name::table_fetch($name, _table_row),)*)
 | 
					                ($($name::fetch($name, _entity, _table_row),)*)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline(always)]
 | 
				
			||||||
            #[allow(clippy::unused_unit)]
 | 
					            unsafe fn filter_fetch<'w>(
 | 
				
			||||||
            unsafe fn archetype_fetch<'w>(_fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, _archetype_index: usize) -> QueryItem<'w, Self> {
 | 
					                _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                _entity: Entity,
 | 
				
			||||||
 | 
					                _table_row: usize
 | 
				
			||||||
 | 
					            ) -> bool {
 | 
				
			||||||
                let ($($name,)*) = _fetch;
 | 
					                let ($($name,)*) = _fetch;
 | 
				
			||||||
                ($($name::archetype_fetch($name, _archetype_index),)*)
 | 
					                true $(&& $name::filter_fetch($name, _entity, _table_row))*
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            #[allow(unused_variables)]
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            unsafe fn table_filter_fetch(_fetch: &mut QueryFetch<'_, Self>, table_row: usize) -> bool {
 | 
					 | 
				
			||||||
                let ($($name,)*) = _fetch;
 | 
					 | 
				
			||||||
                true $(&& $name::table_filter_fetch($name, table_row))*
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            #[allow(unused_variables)]
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            unsafe fn archetype_filter_fetch(_fetch: &mut QueryFetch<'_, Self>, archetype_index: usize) -> bool {
 | 
					 | 
				
			||||||
                let ($($name,)*) = _fetch;
 | 
					 | 
				
			||||||
                true $(&& $name::archetype_filter_fetch($name, archetype_index))*
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fn update_component_access(state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {
 | 
					            fn update_component_access(state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {
 | 
				
			||||||
@ -1471,13 +1340,18 @@ macro_rules! impl_anytuple_fetch {
 | 
				
			|||||||
            const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
 | 
					            const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline]
 | 
				
			||||||
            unsafe fn set_archetype<'w>(_fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, _state: &Self::State, _archetype: &'w Archetype, _tables: &'w Tables) {
 | 
					            unsafe fn set_archetype<'w>(
 | 
				
			||||||
 | 
					                _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                _state: &Self::State,
 | 
				
			||||||
 | 
					                _archetype: &'w Archetype,
 | 
				
			||||||
 | 
					                _table: &'w Table
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
                let ($($name,)*) = _fetch;
 | 
					                let ($($name,)*) = _fetch;
 | 
				
			||||||
                let ($($state,)*) = _state;
 | 
					                let ($($state,)*) = _state;
 | 
				
			||||||
                $(
 | 
					                $(
 | 
				
			||||||
                    $name.1 = $name::matches_component_set($state, &|id| _archetype.contains(id));
 | 
					                    $name.1 = $name::matches_component_set($state, &|id| _archetype.contains(id));
 | 
				
			||||||
                    if $name.1 {
 | 
					                    if $name.1 {
 | 
				
			||||||
                        $name::set_archetype(&mut $name.0, $state, _archetype, _tables);
 | 
					                        $name::set_archetype(&mut $name.0, $state, _archetype, _table);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                )*
 | 
					                )*
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -1494,21 +1368,16 @@ macro_rules! impl_anytuple_fetch {
 | 
				
			|||||||
                )*
 | 
					                )*
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline(always)]
 | 
				
			||||||
            #[allow(clippy::unused_unit)]
 | 
					            #[allow(clippy::unused_unit)]
 | 
				
			||||||
            unsafe fn table_fetch<'w>(_fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, _table_row: usize) -> QueryItem<'w, Self> {
 | 
					            unsafe fn fetch<'w>(
 | 
				
			||||||
 | 
					                _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                _entity: Entity,
 | 
				
			||||||
 | 
					                _table_row: usize
 | 
				
			||||||
 | 
					            ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
                let ($($name,)*) = _fetch;
 | 
					                let ($($name,)*) = _fetch;
 | 
				
			||||||
                ($(
 | 
					                ($(
 | 
				
			||||||
                    $name.1.then(|| $name::table_fetch(&mut $name.0, _table_row)),
 | 
					                    $name.1.then(|| $name::fetch(&mut $name.0, _entity, _table_row)),
 | 
				
			||||||
                )*)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            #[allow(clippy::unused_unit)]
 | 
					 | 
				
			||||||
            unsafe fn archetype_fetch<'w>(_fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, _archetype_index: usize) -> QueryItem<'w, Self> {
 | 
					 | 
				
			||||||
                let ($($name,)*) = _fetch;
 | 
					 | 
				
			||||||
                ($(
 | 
					 | 
				
			||||||
                    $name.1.then(|| $name::archetype_fetch(&mut $name.0, _archetype_index)),
 | 
					 | 
				
			||||||
                )*)
 | 
					                )*)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1608,7 +1477,7 @@ unsafe impl<Q: WorldQuery> WorldQuery for NopWorldQuery<Q> {
 | 
				
			|||||||
        _fetch: &mut (),
 | 
					        _fetch: &mut (),
 | 
				
			||||||
        _state: &Q::State,
 | 
					        _state: &Q::State,
 | 
				
			||||||
        _archetype: &Archetype,
 | 
					        _archetype: &Archetype,
 | 
				
			||||||
        _tables: &Tables,
 | 
					        _tables: &Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1616,15 +1485,9 @@ unsafe impl<Q: WorldQuery> WorldQuery for NopWorldQuery<Q> {
 | 
				
			|||||||
    unsafe fn set_table<'w>(_fetch: &mut (), _state: &Q::State, _table: &Table) {}
 | 
					    unsafe fn set_table<'w>(_fetch: &mut (), _state: &Q::State, _table: &Table) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline(always)]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
        _archetype_index: usize,
 | 
					        _entity: Entity,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					 | 
				
			||||||
        _fetch: &mut (),
 | 
					 | 
				
			||||||
        _table_row: usize,
 | 
					        _table_row: usize,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ use crate::{
 | 
				
			|||||||
    query::{
 | 
					    query::{
 | 
				
			||||||
        debug_checked_unreachable, Access, FilteredAccess, QueryFetch, WorldQuery, WorldQueryGats,
 | 
					        debug_checked_unreachable, Access, FilteredAccess, QueryFetch, WorldQuery, WorldQueryGats,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    storage::{ComponentSparseSet, Table, Tables},
 | 
					    storage::{ComponentSparseSet, Table},
 | 
				
			||||||
    world::World,
 | 
					    world::World,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_ecs_macros::all_tuples;
 | 
					use bevy_ecs_macros::all_tuples;
 | 
				
			||||||
@ -88,20 +88,14 @@ unsafe impl<T: Component> WorldQuery for With<T> {
 | 
				
			|||||||
        _fetch: &mut (),
 | 
					        _fetch: &mut (),
 | 
				
			||||||
        _state: &ComponentId,
 | 
					        _state: &ComponentId,
 | 
				
			||||||
        _archetype: &Archetype,
 | 
					        _archetype: &Archetype,
 | 
				
			||||||
        _tables: &Tables,
 | 
					        _table: &Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					 | 
				
			||||||
        _archetype_index: usize,
 | 
					 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					 | 
				
			||||||
        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					        _entity: Entity,
 | 
				
			||||||
        _table_row: usize,
 | 
					        _table_row: usize,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -200,20 +194,14 @@ unsafe impl<T: Component> WorldQuery for Without<T> {
 | 
				
			|||||||
        _fetch: &mut (),
 | 
					        _fetch: &mut (),
 | 
				
			||||||
        _state: &ComponentId,
 | 
					        _state: &ComponentId,
 | 
				
			||||||
        _archetype: &Archetype,
 | 
					        _archetype: &Archetype,
 | 
				
			||||||
        _tables: &Tables,
 | 
					        _table: &Table,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn archetype_fetch<'w>(
 | 
					    unsafe fn fetch<'w>(
 | 
				
			||||||
        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					 | 
				
			||||||
        _archetype_index: usize,
 | 
					 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn table_fetch<'w>(
 | 
					 | 
				
			||||||
        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
					        _fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					        _entity: Entity,
 | 
				
			||||||
        _table_row: usize,
 | 
					        _table_row: usize,
 | 
				
			||||||
    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					    ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -348,37 +336,39 @@ macro_rules! impl_query_filter_tuple {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline]
 | 
				
			||||||
            unsafe fn set_archetype<'w>(fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, state: &Self::State, archetype: &'w Archetype, tables: &'w Tables) {
 | 
					            unsafe fn set_archetype<'w>(
 | 
				
			||||||
 | 
					                fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                state: & Self::State,
 | 
				
			||||||
 | 
					                archetype: &'w Archetype,
 | 
				
			||||||
 | 
					                table: &'w Table
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
                let ($($filter,)*) = fetch;
 | 
					                let ($($filter,)*) = fetch;
 | 
				
			||||||
                let ($($state,)*) = state;
 | 
					                let ($($state,)*) = &state;
 | 
				
			||||||
                $(
 | 
					                $(
 | 
				
			||||||
                    $filter.matches = $filter::matches_component_set($state, &|id| archetype.contains(id));
 | 
					                    $filter.matches = $filter::matches_component_set($state, &|id| archetype.contains(id));
 | 
				
			||||||
                    if $filter.matches {
 | 
					                    if $filter.matches {
 | 
				
			||||||
                        $filter::set_archetype(&mut $filter.fetch, $state, archetype, tables);
 | 
					                        $filter::set_archetype(&mut $filter.fetch, $state, archetype, table);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                )*
 | 
					                )*
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline(always)]
 | 
				
			||||||
            unsafe fn table_fetch<'w>(fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, table_row: usize) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					            unsafe fn fetch<'w>(
 | 
				
			||||||
 | 
					                fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                _entity: Entity,
 | 
				
			||||||
 | 
					                _table_row: usize
 | 
				
			||||||
 | 
					            ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
                let ($($filter,)*) = fetch;
 | 
					                let ($($filter,)*) = fetch;
 | 
				
			||||||
                false $(|| ($filter.matches && $filter::table_filter_fetch(&mut $filter.fetch, table_row)))*
 | 
					                false $(|| ($filter.matches && $filter::filter_fetch(&mut $filter.fetch, _entity, _table_row)))*
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline(always)]
 | 
				
			||||||
            unsafe fn archetype_fetch<'w>(fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, archetype_index: usize) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					            unsafe fn filter_fetch<'w>(
 | 
				
			||||||
                let ($($filter,)*) = fetch;
 | 
					                fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
                false $(|| ($filter.matches && $filter::archetype_filter_fetch(&mut $filter.fetch, archetype_index)))*
 | 
					                entity: Entity,
 | 
				
			||||||
            }
 | 
					                table_row: usize
 | 
				
			||||||
 | 
					            ) -> bool {
 | 
				
			||||||
            #[inline]
 | 
					                Self::fetch(fetch, entity, table_row)
 | 
				
			||||||
            unsafe fn table_filter_fetch(fetch: &mut QueryFetch<'_, Self>, table_row: usize) -> bool {
 | 
					 | 
				
			||||||
                Self::table_fetch(fetch, table_row)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            unsafe fn archetype_filter_fetch(fetch: &mut QueryFetch<'_, Self>, archetype_index: usize) -> bool {
 | 
					 | 
				
			||||||
                Self::archetype_fetch(fetch, archetype_index)
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
 | 
					            fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
 | 
				
			||||||
@ -450,9 +440,7 @@ macro_rules! impl_tick_filter {
 | 
				
			|||||||
        $(#[$fetch_meta])*
 | 
					        $(#[$fetch_meta])*
 | 
				
			||||||
        pub struct $fetch_name<'w, T> {
 | 
					        pub struct $fetch_name<'w, T> {
 | 
				
			||||||
            table_ticks: Option<ThinSlicePtr<'w, UnsafeCell<ComponentTicks>>>,
 | 
					            table_ticks: Option<ThinSlicePtr<'w, UnsafeCell<ComponentTicks>>>,
 | 
				
			||||||
            entity_table_rows: Option<ThinSlicePtr<'w, usize>>,
 | 
					 | 
				
			||||||
            marker: PhantomData<T>,
 | 
					            marker: PhantomData<T>,
 | 
				
			||||||
            entities: Option<ThinSlicePtr<'w, Entity>>,
 | 
					 | 
				
			||||||
            sparse_set: Option<&'w ComponentSparseSet>,
 | 
					            sparse_set: Option<&'w ComponentSparseSet>,
 | 
				
			||||||
            last_change_tick: u32,
 | 
					            last_change_tick: u32,
 | 
				
			||||||
            change_tick: u32,
 | 
					            change_tick: u32,
 | 
				
			||||||
@ -470,10 +458,13 @@ macro_rules! impl_tick_filter {
 | 
				
			|||||||
            unsafe fn init_fetch<'w>(world: &'w World, &id: &ComponentId, last_change_tick: u32, change_tick: u32) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
					            unsafe fn init_fetch<'w>(world: &'w World, &id: &ComponentId, last_change_tick: u32, change_tick: u32) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
				
			||||||
                QueryFetch::<'w, Self> {
 | 
					                QueryFetch::<'w, Self> {
 | 
				
			||||||
                    table_ticks: None,
 | 
					                    table_ticks: None,
 | 
				
			||||||
                    entities: None,
 | 
					 | 
				
			||||||
                    entity_table_rows: None,
 | 
					 | 
				
			||||||
                    sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet)
 | 
					                    sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet)
 | 
				
			||||||
                        .then(|| world.storages().sparse_sets.get(id).unwrap()),
 | 
					                        .then(|| {
 | 
				
			||||||
 | 
					                            world.storages()
 | 
				
			||||||
 | 
					                                 .sparse_sets
 | 
				
			||||||
 | 
					                                 .get(id)
 | 
				
			||||||
 | 
					                                 .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                        }),
 | 
				
			||||||
                    marker: PhantomData,
 | 
					                    marker: PhantomData,
 | 
				
			||||||
                    last_change_tick,
 | 
					                    last_change_tick,
 | 
				
			||||||
                    change_tick,
 | 
					                    change_tick,
 | 
				
			||||||
@ -485,8 +476,6 @@ macro_rules! impl_tick_filter {
 | 
				
			|||||||
            ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
					            ) -> <Self as WorldQueryGats<'w>>::Fetch {
 | 
				
			||||||
                $fetch_name {
 | 
					                $fetch_name {
 | 
				
			||||||
                    table_ticks: fetch.table_ticks,
 | 
					                    table_ticks: fetch.table_ticks,
 | 
				
			||||||
                    entity_table_rows: fetch.entity_table_rows,
 | 
					 | 
				
			||||||
                    entities: fetch.entities,
 | 
					 | 
				
			||||||
                    sparse_set: fetch.sparse_set,
 | 
					                    sparse_set: fetch.sparse_set,
 | 
				
			||||||
                    last_change_tick: fetch.last_change_tick,
 | 
					                    last_change_tick: fetch.last_change_tick,
 | 
				
			||||||
                    change_tick: fetch.change_tick,
 | 
					                    change_tick: fetch.change_tick,
 | 
				
			||||||
@ -503,53 +492,68 @@ macro_rules! impl_tick_filter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            const IS_ARCHETYPAL:  bool = false;
 | 
					            const IS_ARCHETYPAL:  bool = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            unsafe fn set_table<'w>(fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, &id: &ComponentId, table: &'w Table) {
 | 
					            #[inline]
 | 
				
			||||||
                fetch.table_ticks = Some(table.get_column(id).unwrap().get_ticks_slice().into());
 | 
					            unsafe fn set_table<'w>(
 | 
				
			||||||
 | 
					                fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                &component_id: &ComponentId,
 | 
				
			||||||
 | 
					                table: &'w Table
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
 | 
					                fetch.table_ticks = Some(
 | 
				
			||||||
 | 
					                    table.get_column(component_id)
 | 
				
			||||||
 | 
					                         .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                         .get_ticks_slice()
 | 
				
			||||||
 | 
					                         .into()
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            unsafe fn set_archetype<'w>(fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, &id: &ComponentId, archetype: &'w Archetype, tables: &'w Tables) {
 | 
					            #[inline]
 | 
				
			||||||
                match T::Storage::STORAGE_TYPE {
 | 
					            unsafe fn set_archetype<'w>(
 | 
				
			||||||
                    StorageType::Table => {
 | 
					                fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
                        fetch.entity_table_rows = Some(archetype.entity_table_rows().into());
 | 
					                component_id: &ComponentId,
 | 
				
			||||||
                        let table = &tables[archetype.table_id()];
 | 
					                _archetype: &'w Archetype,
 | 
				
			||||||
                        fetch.table_ticks = Some(table.get_column(id).unwrap().get_ticks_slice().into());
 | 
					                table: &'w Table
 | 
				
			||||||
                    }
 | 
					            ) {
 | 
				
			||||||
                    StorageType::SparseSet => fetch.entities = Some(archetype.entities().into()),
 | 
					                if Self::IS_DENSE {
 | 
				
			||||||
 | 
					                    Self::set_table(fetch, component_id, table);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            unsafe fn table_fetch<'w>(fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, table_row: usize) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					            #[inline(always)]
 | 
				
			||||||
                $is_detected(&*(fetch.table_ticks.unwrap_or_else(|| debug_checked_unreachable()).get(table_row)).deref(), fetch.last_change_tick, fetch.change_tick)
 | 
					            unsafe fn fetch<'w>(
 | 
				
			||||||
            }
 | 
					                fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
 | 
				
			||||||
 | 
					                entity: Entity,
 | 
				
			||||||
            unsafe fn archetype_fetch<'w>(fetch: &mut <Self as WorldQueryGats<'w>>::Fetch, archetype_index: usize) -> <Self as WorldQueryGats<'w>>::Item {
 | 
					                table_row: usize
 | 
				
			||||||
 | 
					            ) -> <Self as WorldQueryGats<'w>>::Item {
 | 
				
			||||||
                match T::Storage::STORAGE_TYPE {
 | 
					                match T::Storage::STORAGE_TYPE {
 | 
				
			||||||
                    StorageType::Table => {
 | 
					                    StorageType::Table => {
 | 
				
			||||||
                        let table_row = *fetch.entity_table_rows.unwrap_or_else(|| debug_checked_unreachable()).get(archetype_index);
 | 
					                        $is_detected(&*(
 | 
				
			||||||
                        $is_detected(&*(fetch.table_ticks.unwrap_or_else(|| debug_checked_unreachable()).get(table_row)).deref(), fetch.last_change_tick, fetch.change_tick)
 | 
					                            fetch.table_ticks
 | 
				
			||||||
 | 
					                                 .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
 | 
					                                 .get(table_row))
 | 
				
			||||||
 | 
					                                 .deref(),
 | 
				
			||||||
 | 
					                            fetch.last_change_tick,
 | 
				
			||||||
 | 
					                            fetch.change_tick
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    StorageType::SparseSet => {
 | 
					                    StorageType::SparseSet => {
 | 
				
			||||||
                        let entity = *fetch.entities.unwrap_or_else(|| debug_checked_unreachable()).get(archetype_index);
 | 
					                        let ticks = &*fetch
 | 
				
			||||||
                        let ticks = fetch
 | 
					 | 
				
			||||||
                            .sparse_set
 | 
					                            .sparse_set
 | 
				
			||||||
                            .unwrap_or_else(|| debug_checked_unreachable())
 | 
					                            .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
                            .get_ticks(entity)
 | 
					                            .get_ticks(entity)
 | 
				
			||||||
                            .map(|ticks| &*ticks.get())
 | 
					                            .unwrap_or_else(|| debug_checked_unreachable())
 | 
				
			||||||
                            .cloned()
 | 
					                            .get();
 | 
				
			||||||
                            .unwrap();
 | 
					                        $is_detected(ticks, fetch.last_change_tick, fetch.change_tick)
 | 
				
			||||||
                        $is_detected(&ticks, fetch.last_change_tick, fetch.change_tick)
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline(always)]
 | 
				
			||||||
            unsafe fn table_filter_fetch(fetch: &mut QueryFetch<'_, Self>, table_row: usize) -> bool {
 | 
					            unsafe fn filter_fetch<'w>(
 | 
				
			||||||
                Self::table_fetch(fetch, table_row)
 | 
					                fetch: &mut QueryFetch<'w, Self>,
 | 
				
			||||||
            }
 | 
					                entity: Entity,
 | 
				
			||||||
 | 
					                table_row: usize
 | 
				
			||||||
            #[inline]
 | 
					            ) -> bool {
 | 
				
			||||||
            unsafe fn archetype_filter_fetch(fetch: &mut QueryFetch<'_, Self>, archetype_index: usize) -> bool {
 | 
					                Self::fetch(fetch, entity, table_row)
 | 
				
			||||||
                Self::archetype_fetch(fetch, archetype_index)
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[inline]
 | 
					            #[inline]
 | 
				
			||||||
@ -625,7 +629,7 @@ impl_tick_filter!(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl_tick_filter!(
 | 
					impl_tick_filter!(
 | 
				
			||||||
    /// A filter on a component that only retains results added or mutably dereferenced after the system last ran.
 | 
					    /// A filter on a component that only retains results added or mutably dereferenced after the system last ran.
 | 
				
			||||||
    ///  
 | 
					    ///
 | 
				
			||||||
    /// A common use for this filter is avoiding redundant work when values have not changed.
 | 
					    /// A common use for this filter is avoiding redundant work when values have not changed.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// **Note** that simply *mutably dereferencing* a component is considered a change ([`DerefMut`](std::ops::DerefMut)).
 | 
					    /// **Note** that simply *mutably dereferencing* a component is considered a change ([`DerefMut`](std::ops::DerefMut)).
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    archetype::{ArchetypeId, Archetypes},
 | 
					    archetype::{ArchetypeEntity, ArchetypeId, Archetypes},
 | 
				
			||||||
    entity::{Entities, Entity},
 | 
					    entity::{Entities, Entity},
 | 
				
			||||||
    prelude::World,
 | 
					    prelude::World,
 | 
				
			||||||
    query::{ArchetypeFilter, QueryState, WorldQuery},
 | 
					    query::{ArchetypeFilter, QueryState, WorldQuery},
 | 
				
			||||||
@ -139,7 +139,8 @@ where
 | 
				
			|||||||
    #[inline(always)]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<QueryItem<'w, Q>> {
 | 
					    unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<QueryItem<'w, Q>> {
 | 
				
			||||||
        for entity in self.entity_iter.by_ref() {
 | 
					        for entity in self.entity_iter.by_ref() {
 | 
				
			||||||
            let location = match self.entities.get(*entity.borrow()) {
 | 
					            let entity = *entity.borrow();
 | 
				
			||||||
 | 
					            let location = match self.entities.get(entity) {
 | 
				
			||||||
                Some(location) => location,
 | 
					                Some(location) => location,
 | 
				
			||||||
                None => continue,
 | 
					                None => continue,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@ -153,6 +154,7 @@ where
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let archetype = &self.archetypes[location.archetype_id];
 | 
					            let archetype = &self.archetypes[location.archetype_id];
 | 
				
			||||||
 | 
					            let table = &self.tables[archetype.table_id()];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // SAFETY: `archetype` is from the world that `fetch/filter` were created for,
 | 
					            // SAFETY: `archetype` is from the world that `fetch/filter` were created for,
 | 
				
			||||||
            // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
 | 
					            // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
 | 
				
			||||||
@ -160,7 +162,7 @@ where
 | 
				
			|||||||
                &mut self.fetch,
 | 
					                &mut self.fetch,
 | 
				
			||||||
                &self.query_state.fetch_state,
 | 
					                &self.query_state.fetch_state,
 | 
				
			||||||
                archetype,
 | 
					                archetype,
 | 
				
			||||||
                self.tables,
 | 
					                table,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            // SAFETY: `table` is from the world that `fetch/filter` were created for,
 | 
					            // SAFETY: `table` is from the world that `fetch/filter` were created for,
 | 
				
			||||||
            // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
 | 
					            // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
 | 
				
			||||||
@ -168,13 +170,15 @@ where
 | 
				
			|||||||
                &mut self.filter,
 | 
					                &mut self.filter,
 | 
				
			||||||
                &self.query_state.filter_state,
 | 
					                &self.query_state.filter_state,
 | 
				
			||||||
                archetype,
 | 
					                archetype,
 | 
				
			||||||
                self.tables,
 | 
					                table,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let table_row = archetype.entity_table_row(location.index);
 | 
				
			||||||
            // SAFETY: set_archetype was called prior.
 | 
					            // SAFETY: set_archetype was called prior.
 | 
				
			||||||
            // `location.index` is an archetype index row in range of the current archetype, because if it was not, the match above would have `continue`d
 | 
					            // `location.index` is an archetype index row in range of the current archetype, because if it was not, the match above would have `continue`d
 | 
				
			||||||
            if F::archetype_filter_fetch(&mut self.filter, location.index) {
 | 
					            if F::filter_fetch(&mut self.filter, entity, table_row) {
 | 
				
			||||||
                // SAFETY: set_archetype was called prior, `location.index` is an archetype index in range of the current archetype
 | 
					                // SAFETY: set_archetype was called prior, `location.index` is an archetype index in range of the current archetype
 | 
				
			||||||
                return Some(Q::archetype_fetch(&mut self.fetch, location.index));
 | 
					                return Some(Q::fetch(&mut self.fetch, entity, table_row));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        None
 | 
					        None
 | 
				
			||||||
@ -462,6 +466,8 @@ impl<'w, 's, Q: ReadOnlyWorldQuery, F: ReadOnlyWorldQuery, const K: usize> Fused
 | 
				
			|||||||
struct QueryIterationCursor<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> {
 | 
					struct QueryIterationCursor<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> {
 | 
				
			||||||
    table_id_iter: std::slice::Iter<'s, TableId>,
 | 
					    table_id_iter: std::slice::Iter<'s, TableId>,
 | 
				
			||||||
    archetype_id_iter: std::slice::Iter<'s, ArchetypeId>,
 | 
					    archetype_id_iter: std::slice::Iter<'s, ArchetypeId>,
 | 
				
			||||||
 | 
					    table_entities: &'w [Entity],
 | 
				
			||||||
 | 
					    archetype_entities: &'w [ArchetypeEntity],
 | 
				
			||||||
    fetch: QueryFetch<'w, Q>,
 | 
					    fetch: QueryFetch<'w, Q>,
 | 
				
			||||||
    filter: QueryFetch<'w, F>,
 | 
					    filter: QueryFetch<'w, F>,
 | 
				
			||||||
    // length of the table table or length of the archetype, depending on whether both `Q`'s and `F`'s fetches are dense
 | 
					    // length of the table table or length of the archetype, depending on whether both `Q`'s and `F`'s fetches are dense
 | 
				
			||||||
@ -482,6 +488,8 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
 | 
				
			|||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            table_id_iter: self.table_id_iter.clone(),
 | 
					            table_id_iter: self.table_id_iter.clone(),
 | 
				
			||||||
            archetype_id_iter: self.archetype_id_iter.clone(),
 | 
					            archetype_id_iter: self.archetype_id_iter.clone(),
 | 
				
			||||||
 | 
					            table_entities: self.table_entities,
 | 
				
			||||||
 | 
					            archetype_entities: self.archetype_entities,
 | 
				
			||||||
            // SAFETY: upheld by caller invariants
 | 
					            // SAFETY: upheld by caller invariants
 | 
				
			||||||
            fetch: Q::clone_fetch(&self.fetch),
 | 
					            fetch: Q::clone_fetch(&self.fetch),
 | 
				
			||||||
            filter: F::clone_fetch(&self.filter),
 | 
					            filter: F::clone_fetch(&self.filter),
 | 
				
			||||||
@ -529,6 +537,8 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
 | 
				
			|||||||
        QueryIterationCursor {
 | 
					        QueryIterationCursor {
 | 
				
			||||||
            fetch,
 | 
					            fetch,
 | 
				
			||||||
            filter,
 | 
					            filter,
 | 
				
			||||||
 | 
					            table_entities: &[],
 | 
				
			||||||
 | 
					            archetype_entities: &[],
 | 
				
			||||||
            table_id_iter: query_state.matched_table_ids.iter(),
 | 
					            table_id_iter: query_state.matched_table_ids.iter(),
 | 
				
			||||||
            archetype_id_iter: query_state.matched_archetype_ids.iter(),
 | 
					            archetype_id_iter: query_state.matched_archetype_ids.iter(),
 | 
				
			||||||
            current_len: 0,
 | 
					            current_len: 0,
 | 
				
			||||||
@ -541,10 +551,17 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
 | 
				
			|||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn peek_last(&mut self) -> Option<QueryItem<'w, Q>> {
 | 
					    unsafe fn peek_last(&mut self) -> Option<QueryItem<'w, Q>> {
 | 
				
			||||||
        if self.current_index > 0 {
 | 
					        if self.current_index > 0 {
 | 
				
			||||||
 | 
					            let index = self.current_index - 1;
 | 
				
			||||||
            if Self::IS_DENSE {
 | 
					            if Self::IS_DENSE {
 | 
				
			||||||
                Some(Q::table_fetch(&mut self.fetch, self.current_index - 1))
 | 
					                let entity = self.table_entities.get_unchecked(index);
 | 
				
			||||||
 | 
					                Some(Q::fetch(&mut self.fetch, *entity, index))
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                Some(Q::archetype_fetch(&mut self.fetch, self.current_index - 1))
 | 
					                let archetype_entity = self.archetype_entities.get_unchecked(index);
 | 
				
			||||||
 | 
					                Some(Q::fetch(
 | 
				
			||||||
 | 
					                    &mut self.fetch,
 | 
				
			||||||
 | 
					                    archetype_entity.entity,
 | 
				
			||||||
 | 
					                    archetype_entity.table_row,
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            None
 | 
					            None
 | 
				
			||||||
@ -574,6 +591,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
 | 
				
			|||||||
                    // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
 | 
					                    // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
 | 
				
			||||||
                    Q::set_table(&mut self.fetch, &query_state.fetch_state, table);
 | 
					                    Q::set_table(&mut self.fetch, &query_state.fetch_state, table);
 | 
				
			||||||
                    F::set_table(&mut self.filter, &query_state.filter_state, table);
 | 
					                    F::set_table(&mut self.filter, &query_state.filter_state, table);
 | 
				
			||||||
 | 
					                    self.table_entities = table.entities();
 | 
				
			||||||
                    self.current_len = table.entity_count();
 | 
					                    self.current_len = table.entity_count();
 | 
				
			||||||
                    self.current_index = 0;
 | 
					                    self.current_index = 0;
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
@ -581,14 +599,15 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                // SAFETY: set_table was called prior.
 | 
					                // SAFETY: set_table was called prior.
 | 
				
			||||||
                // `current_index` is a table row in range of the current table, because if it was not, then the if above would have been executed.
 | 
					                // `current_index` is a table row in range of the current table, because if it was not, then the if above would have been executed.
 | 
				
			||||||
                if !F::table_filter_fetch(&mut self.filter, self.current_index) {
 | 
					                let entity = self.table_entities.get_unchecked(self.current_index);
 | 
				
			||||||
 | 
					                if !F::filter_fetch(&mut self.filter, *entity, self.current_index) {
 | 
				
			||||||
                    self.current_index += 1;
 | 
					                    self.current_index += 1;
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // SAFETY: set_table was called prior.
 | 
					                // SAFETY: set_table was called prior.
 | 
				
			||||||
                // `current_index` is a table row in range of the current table, because if it was not, then the if above would have been executed.
 | 
					                // `current_index` is a table row in range of the current table, because if it was not, then the if above would have been executed.
 | 
				
			||||||
                let item = Q::table_fetch(&mut self.fetch, self.current_index);
 | 
					                let item = Q::fetch(&mut self.fetch, *entity, self.current_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                self.current_index += 1;
 | 
					                self.current_index += 1;
 | 
				
			||||||
                return Some(item);
 | 
					                return Some(item);
 | 
				
			||||||
@ -600,13 +619,15 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
 | 
				
			|||||||
                    let archetype = &archetypes[*archetype_id];
 | 
					                    let archetype = &archetypes[*archetype_id];
 | 
				
			||||||
                    // SAFETY: `archetype` and `tables` are from the world that `fetch/filter` were created for,
 | 
					                    // SAFETY: `archetype` and `tables` are from the world that `fetch/filter` were created for,
 | 
				
			||||||
                    // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
 | 
					                    // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
 | 
				
			||||||
                    Q::set_archetype(&mut self.fetch, &query_state.fetch_state, archetype, tables);
 | 
					                    let table = &tables[archetype.table_id()];
 | 
				
			||||||
 | 
					                    Q::set_archetype(&mut self.fetch, &query_state.fetch_state, archetype, table);
 | 
				
			||||||
                    F::set_archetype(
 | 
					                    F::set_archetype(
 | 
				
			||||||
                        &mut self.filter,
 | 
					                        &mut self.filter,
 | 
				
			||||||
                        &query_state.filter_state,
 | 
					                        &query_state.filter_state,
 | 
				
			||||||
                        archetype,
 | 
					                        archetype,
 | 
				
			||||||
                        tables,
 | 
					                        table,
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
 | 
					                    self.archetype_entities = archetype.entities();
 | 
				
			||||||
                    self.current_len = archetype.len();
 | 
					                    self.current_len = archetype.len();
 | 
				
			||||||
                    self.current_index = 0;
 | 
					                    self.current_index = 0;
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
@ -614,14 +635,23 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                // SAFETY: set_archetype was called prior.
 | 
					                // SAFETY: set_archetype was called prior.
 | 
				
			||||||
                // `current_index` is an archetype index row in range of the current archetype, because if it was not, then the if above would have been executed.
 | 
					                // `current_index` is an archetype index row in range of the current archetype, because if it was not, then the if above would have been executed.
 | 
				
			||||||
                if !F::archetype_filter_fetch(&mut self.filter, self.current_index) {
 | 
					                let archetype_entity = self.archetype_entities.get_unchecked(self.current_index);
 | 
				
			||||||
 | 
					                if !F::filter_fetch(
 | 
				
			||||||
 | 
					                    &mut self.filter,
 | 
				
			||||||
 | 
					                    archetype_entity.entity,
 | 
				
			||||||
 | 
					                    archetype_entity.table_row,
 | 
				
			||||||
 | 
					                ) {
 | 
				
			||||||
                    self.current_index += 1;
 | 
					                    self.current_index += 1;
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // SAFETY: set_archetype was called prior, `current_index` is an archetype index in range of the current archetype
 | 
					                // SAFETY: set_archetype was called prior, `current_index` is an archetype index in range of the current archetype
 | 
				
			||||||
                // `current_index` is an archetype index row in range of the current archetype, because if it was not, then the if above would have been executed.
 | 
					                // `current_index` is an archetype index row in range of the current archetype, because if it was not, then the if above would have been executed.
 | 
				
			||||||
                let item = Q::archetype_fetch(&mut self.fetch, self.current_index);
 | 
					                let item = Q::fetch(
 | 
				
			||||||
 | 
					                    &mut self.fetch,
 | 
				
			||||||
 | 
					                    archetype_entity.entity,
 | 
				
			||||||
 | 
					                    archetype_entity.table_row,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
                self.current_index += 1;
 | 
					                self.current_index += 1;
 | 
				
			||||||
                return Some(item);
 | 
					                return Some(item);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -413,20 +413,12 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        let mut fetch = Q::init_fetch(world, &self.fetch_state, last_change_tick, change_tick);
 | 
					        let mut fetch = Q::init_fetch(world, &self.fetch_state, last_change_tick, change_tick);
 | 
				
			||||||
        let mut filter = F::init_fetch(world, &self.filter_state, last_change_tick, change_tick);
 | 
					        let mut filter = F::init_fetch(world, &self.filter_state, last_change_tick, change_tick);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Q::set_archetype(
 | 
					        let table = &world.storages().tables[archetype.table_id()];
 | 
				
			||||||
            &mut fetch,
 | 
					        Q::set_archetype(&mut fetch, &self.fetch_state, archetype, table);
 | 
				
			||||||
            &self.fetch_state,
 | 
					        F::set_archetype(&mut filter, &self.filter_state, archetype, table);
 | 
				
			||||||
            archetype,
 | 
					
 | 
				
			||||||
            &world.storages().tables,
 | 
					        if F::filter_fetch(&mut filter, entity, location.index) {
 | 
				
			||||||
        );
 | 
					            Ok(Q::fetch(&mut fetch, entity, location.index))
 | 
				
			||||||
        F::set_archetype(
 | 
					 | 
				
			||||||
            &mut filter,
 | 
					 | 
				
			||||||
            &self.filter_state,
 | 
					 | 
				
			||||||
            archetype,
 | 
					 | 
				
			||||||
            &world.storages().tables,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        if F::archetype_filter_fetch(&mut filter, location.index) {
 | 
					 | 
				
			||||||
            Ok(Q::archetype_fetch(&mut fetch, location.index))
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            Err(QueryEntityError::QueryDoesNotMatch(entity))
 | 
					            Err(QueryEntityError::QueryDoesNotMatch(entity))
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -945,34 +937,45 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        let mut fetch = Q::init_fetch(world, &self.fetch_state, last_change_tick, change_tick);
 | 
					        let mut fetch = Q::init_fetch(world, &self.fetch_state, last_change_tick, change_tick);
 | 
				
			||||||
        let mut filter = F::init_fetch(world, &self.filter_state, last_change_tick, change_tick);
 | 
					        let mut filter = F::init_fetch(world, &self.filter_state, last_change_tick, change_tick);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let tables = &world.storages().tables;
 | 
				
			||||||
        if Q::IS_DENSE && F::IS_DENSE {
 | 
					        if Q::IS_DENSE && F::IS_DENSE {
 | 
				
			||||||
            let tables = &world.storages().tables;
 | 
					 | 
				
			||||||
            for table_id in &self.matched_table_ids {
 | 
					            for table_id in &self.matched_table_ids {
 | 
				
			||||||
                let table = &tables[*table_id];
 | 
					                let table = &tables[*table_id];
 | 
				
			||||||
                Q::set_table(&mut fetch, &self.fetch_state, table);
 | 
					                Q::set_table(&mut fetch, &self.fetch_state, table);
 | 
				
			||||||
                F::set_table(&mut filter, &self.filter_state, table);
 | 
					                F::set_table(&mut filter, &self.filter_state, table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for table_index in 0..table.entity_count() {
 | 
					                let entities = table.entities();
 | 
				
			||||||
                    if !F::table_filter_fetch(&mut filter, table_index) {
 | 
					                for row in 0..table.entity_count() {
 | 
				
			||||||
 | 
					                    let entity = entities.get_unchecked(row);
 | 
				
			||||||
 | 
					                    if !F::filter_fetch(&mut filter, *entity, row) {
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    let item = Q::table_fetch(&mut fetch, table_index);
 | 
					                    func(Q::fetch(&mut fetch, *entity, row));
 | 
				
			||||||
                    func(item);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            let archetypes = &world.archetypes;
 | 
					            let archetypes = &world.archetypes;
 | 
				
			||||||
            let tables = &world.storages().tables;
 | 
					 | 
				
			||||||
            for archetype_id in &self.matched_archetype_ids {
 | 
					            for archetype_id in &self.matched_archetype_ids {
 | 
				
			||||||
                let archetype = &archetypes[*archetype_id];
 | 
					                let archetype = &archetypes[*archetype_id];
 | 
				
			||||||
                Q::set_archetype(&mut fetch, &self.fetch_state, archetype, tables);
 | 
					                let table = &tables[archetype.table_id()];
 | 
				
			||||||
                F::set_archetype(&mut filter, &self.filter_state, archetype, tables);
 | 
					                Q::set_archetype(&mut fetch, &self.fetch_state, archetype, table);
 | 
				
			||||||
 | 
					                F::set_archetype(&mut filter, &self.filter_state, archetype, table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for archetype_index in 0..archetype.len() {
 | 
					                let entities = archetype.entities();
 | 
				
			||||||
                    if !F::archetype_filter_fetch(&mut filter, archetype_index) {
 | 
					                for idx in 0..archetype.len() {
 | 
				
			||||||
 | 
					                    let archetype_entity = entities.get_unchecked(idx);
 | 
				
			||||||
 | 
					                    if !F::filter_fetch(
 | 
				
			||||||
 | 
					                        &mut filter,
 | 
				
			||||||
 | 
					                        archetype_entity.entity,
 | 
				
			||||||
 | 
					                        archetype_entity.table_row,
 | 
				
			||||||
 | 
					                    ) {
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    func(Q::archetype_fetch(&mut fetch, archetype_index));
 | 
					                    func(Q::fetch(
 | 
				
			||||||
 | 
					                        &mut fetch,
 | 
				
			||||||
 | 
					                        archetype_entity.entity,
 | 
				
			||||||
 | 
					                        archetype_entity.table_row,
 | 
				
			||||||
 | 
					                    ));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -1033,14 +1036,15 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
                            );
 | 
					                            );
 | 
				
			||||||
                            let tables = &world.storages().tables;
 | 
					                            let tables = &world.storages().tables;
 | 
				
			||||||
                            let table = &tables[*table_id];
 | 
					                            let table = &tables[*table_id];
 | 
				
			||||||
 | 
					                            let entities = table.entities();
 | 
				
			||||||
                            Q::set_table(&mut fetch, &self.fetch_state, table);
 | 
					                            Q::set_table(&mut fetch, &self.fetch_state, table);
 | 
				
			||||||
                            F::set_table(&mut filter, &self.filter_state, table);
 | 
					                            F::set_table(&mut filter, &self.filter_state, table);
 | 
				
			||||||
                            for table_index in offset..offset + len {
 | 
					                            for row in offset..offset + len {
 | 
				
			||||||
                                if !F::table_filter_fetch(&mut filter, table_index) {
 | 
					                                let entity = entities.get_unchecked(row);
 | 
				
			||||||
 | 
					                                if !F::filter_fetch(&mut filter, *entity, row) {
 | 
				
			||||||
                                    continue;
 | 
					                                    continue;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                                let item = Q::table_fetch(&mut fetch, table_index);
 | 
					                                func(Q::fetch(&mut fetch, *entity, row));
 | 
				
			||||||
                                func(item);
 | 
					 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        };
 | 
					                        };
 | 
				
			||||||
                        #[cfg(feature = "trace")]
 | 
					                        #[cfg(feature = "trace")]
 | 
				
			||||||
@ -1083,14 +1087,25 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
                            );
 | 
					                            );
 | 
				
			||||||
                            let tables = &world.storages().tables;
 | 
					                            let tables = &world.storages().tables;
 | 
				
			||||||
                            let archetype = &world.archetypes[*archetype_id];
 | 
					                            let archetype = &world.archetypes[*archetype_id];
 | 
				
			||||||
                            Q::set_archetype(&mut fetch, &self.fetch_state, archetype, tables);
 | 
					                            let table = &tables[archetype.table_id()];
 | 
				
			||||||
                            F::set_archetype(&mut filter, &self.filter_state, archetype, tables);
 | 
					                            Q::set_archetype(&mut fetch, &self.fetch_state, archetype, table);
 | 
				
			||||||
 | 
					                            F::set_archetype(&mut filter, &self.filter_state, archetype, table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            let entities = archetype.entities();
 | 
				
			||||||
                            for archetype_index in offset..offset + len {
 | 
					                            for archetype_index in offset..offset + len {
 | 
				
			||||||
                                if !F::archetype_filter_fetch(&mut filter, archetype_index) {
 | 
					                                let archetype_entity = entities.get_unchecked(archetype_index);
 | 
				
			||||||
 | 
					                                if !F::filter_fetch(
 | 
				
			||||||
 | 
					                                    &mut filter,
 | 
				
			||||||
 | 
					                                    archetype_entity.entity,
 | 
				
			||||||
 | 
					                                    archetype_entity.table_row,
 | 
				
			||||||
 | 
					                                ) {
 | 
				
			||||||
                                    continue;
 | 
					                                    continue;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                                func(Q::archetype_fetch(&mut fetch, archetype_index));
 | 
					                                func(Q::fetch(
 | 
				
			||||||
 | 
					                                    &mut fetch,
 | 
				
			||||||
 | 
					                                    archetype_entity.entity,
 | 
				
			||||||
 | 
					                                    archetype_entity.table_row,
 | 
				
			||||||
 | 
					                                ));
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        };
 | 
					                        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -327,7 +327,8 @@ impl World {
 | 
				
			|||||||
    pub fn iter_entities(&self) -> impl Iterator<Item = Entity> + '_ {
 | 
					    pub fn iter_entities(&self) -> impl Iterator<Item = Entity> + '_ {
 | 
				
			||||||
        self.archetypes
 | 
					        self.archetypes
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .flat_map(|archetype| archetype.entities().iter().copied())
 | 
					            .flat_map(|archetype| archetype.entities().iter())
 | 
				
			||||||
 | 
					            .map(|archetype_entity| archetype_entity.entity)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Retrieves an [`EntityMut`] that exposes read and write operations for the given `entity`.
 | 
					    /// Retrieves an [`EntityMut`] that exposes read and write operations for the given `entity`.
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ impl Scene {
 | 
				
			|||||||
            for scene_entity in archetype.entities() {
 | 
					            for scene_entity in archetype.entities() {
 | 
				
			||||||
                let entity = *instance_info
 | 
					                let entity = *instance_info
 | 
				
			||||||
                    .entity_map
 | 
					                    .entity_map
 | 
				
			||||||
                    .entry(*scene_entity)
 | 
					                    .entry(scene_entity.entity())
 | 
				
			||||||
                    .or_insert_with(|| world.spawn_empty().id());
 | 
					                    .or_insert_with(|| world.spawn_empty().id());
 | 
				
			||||||
                for component_id in archetype.components() {
 | 
					                for component_id in archetype.components() {
 | 
				
			||||||
                    let component_info = self
 | 
					                    let component_info = self
 | 
				
			||||||
@ -86,7 +86,7 @@ impl Scene {
 | 
				
			|||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            })
 | 
					                            })
 | 
				
			||||||
                        })?;
 | 
					                        })?;
 | 
				
			||||||
                    reflect_component.copy(&self.world, world, *scene_entity, entity);
 | 
					                    reflect_component.copy(&self.world, world, scene_entity.entity(), entity);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user