diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 63788b9dfc..ca956c271e 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -276,15 +276,9 @@ impl QueryState { entity: Entity, ) -> Result, QueryEntityError> { self.update_archetypes(world); + let change_tick = world.change_tick(); // SAFETY: query has unique world access - unsafe { - self.get_unchecked_manual( - world, - entity, - world.last_change_tick(), - world.read_change_tick(), - ) - } + unsafe { self.get_unchecked_manual(world, entity, world.last_change_tick(), change_tick) } } /// Returns the query results for the given array of [`Entity`]. @@ -333,15 +327,11 @@ impl QueryState { ) -> Result<[Q::Item<'w>; N], QueryEntityError> { self.update_archetypes(world); + let change_tick = world.change_tick(); // SAFETY: method requires exclusive world access // and world has been validated via update_archetypes unsafe { - self.get_many_unchecked_manual( - world, - entities, - world.last_change_tick(), - world.read_change_tick(), - ) + self.get_many_unchecked_manual(world, entities, world.last_change_tick(), change_tick) } } @@ -525,10 +515,11 @@ impl QueryState { /// Returns an [`Iterator`] over the query results for the given [`World`]. #[inline] pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, Q, F> { + let change_tick = world.change_tick(); // SAFETY: query has unique world access unsafe { self.update_archetypes(world); - self.iter_unchecked_manual(world, world.last_change_tick(), world.read_change_tick()) + self.iter_unchecked_manual(world, world.last_change_tick(), change_tick) } } @@ -611,14 +602,11 @@ impl QueryState { &'s mut self, world: &'w mut World, ) -> QueryCombinationIter<'w, 's, Q, F, K> { + let change_tick = world.change_tick(); // SAFETY: query has unique world access unsafe { self.update_archetypes(world); - self.iter_combinations_unchecked_manual( - world, - world.last_change_tick(), - world.read_change_tick(), - ) + self.iter_combinations_unchecked_manual(world, world.last_change_tick(), change_tick) } } @@ -665,14 +653,10 @@ impl QueryState { EntityList::Item: Borrow, { self.update_archetypes(world); + let change_tick = world.change_tick(); // SAFETY: Query has unique world access. unsafe { - self.iter_many_unchecked_manual( - entities, - world, - world.last_change_tick(), - world.read_change_tick(), - ) + self.iter_many_unchecked_manual(entities, world, world.last_change_tick(), change_tick) } } @@ -797,15 +781,11 @@ impl QueryState { /// `iter_mut()` method, but cannot be chained like a normal [`Iterator`]. #[inline] pub fn for_each_mut<'w, FN: FnMut(Q::Item<'w>)>(&mut self, world: &'w mut World, func: FN) { + let change_tick = world.change_tick(); // SAFETY: query has unique world access unsafe { self.update_archetypes(world); - self.for_each_unchecked_manual( - world, - func, - world.last_change_tick(), - world.read_change_tick(), - ); + self.for_each_unchecked_manual(world, func, world.last_change_tick(), change_tick); } } @@ -873,6 +853,7 @@ impl QueryState { batch_size: usize, func: FN, ) { + let change_tick = world.change_tick(); // SAFETY: query has unique world access unsafe { self.update_archetypes(world); @@ -881,7 +862,7 @@ impl QueryState { batch_size, func, world.last_change_tick(), - world.read_change_tick(), + change_tick, ); } } @@ -1195,14 +1176,9 @@ impl QueryState { ) -> Result, QuerySingleError> { self.update_archetypes(world); + let change_tick = world.change_tick(); // SAFETY: query has unique world access - unsafe { - self.get_single_unchecked_manual( - world, - world.last_change_tick(), - world.read_change_tick(), - ) - } + unsafe { self.get_single_unchecked_manual(world, world.last_change_tick(), change_tick) } } /// Returns a query result when there is exactly one entity matching the query. @@ -1293,7 +1269,7 @@ mod tests { // These don't matter for the test let last_change_tick = world.last_change_tick(); - let change_tick = world.read_change_tick(); + let change_tick = world.change_tick(); // It's best to test get_many_unchecked_manual directly, // as it is shared and unsafe diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index f0da529196..e305033991 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -930,15 +930,12 @@ pub(crate) unsafe fn get_mut_by_id( location: EntityLocation, component_id: ComponentId, ) -> Option { + let change_tick = world.change_tick(); // SAFETY: world access is unique, entity location and component_id required to be valid get_component_and_ticks(world, component_id, entity, location).map(|(value, ticks)| { MutUntyped { value: value.assert_unique(), - ticks: Ticks::from_tick_cells( - ticks, - world.last_change_tick(), - world.read_change_tick(), - ), + ticks: Ticks::from_tick_cells(ticks, world.last_change_tick(), change_tick), } }) } diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index a3218f8ff0..b60fdb5ff2 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -1457,14 +1457,14 @@ impl World { self.validate_non_send_access_untyped(info.name()); } + let change_tick = self.change_tick(); + let (ptr, ticks) = self.get_resource_with_ticks(component_id)?; // SAFETY: This function has exclusive access to the world so nothing aliases `ticks`. // - index is in-bounds because the column is initialized and non-empty // - no other reference to the ticks of the same row can exist at the same time - let ticks = unsafe { - Ticks::from_tick_cells(ticks, self.last_change_tick(), self.read_change_tick()) - }; + let ticks = unsafe { Ticks::from_tick_cells(ticks, self.last_change_tick(), change_tick) }; Some(MutUntyped { // SAFETY: This function has exclusive access to the world so nothing aliases `ptr`.