Remove ChangeTrackers (#7902)

This commit is contained in:
James Liu 2023-03-09 12:02:56 -08:00 committed by GitHub
parent 3ec764ea24
commit 7d9cb1c4ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 3 additions and 272 deletions

View file

@ -25,9 +25,6 @@ pub use bevy_ptr as ptr;
/// Most commonly used re-exported types.
pub mod prelude {
#[doc(hidden)]
#[allow(deprecated)]
pub use crate::query::ChangeTrackers;
#[doc(hidden)]
#[cfg(feature = "bevy_reflect")]
pub use crate::reflect::{ReflectComponent, ReflectResource};
@ -1299,33 +1296,6 @@ mod tests {
.unwrap();
}
#[test]
#[allow(deprecated)]
fn trackers_query() {
use crate::prelude::ChangeTrackers;
let mut world = World::default();
let e1 = world.spawn((A(0), B(0))).id();
world.spawn(B(0));
let mut trackers_query = world.query::<Option<ChangeTrackers<A>>>();
let trackers = trackers_query.iter(&world).collect::<Vec<_>>();
let a_trackers = trackers[0].as_ref().unwrap();
assert!(trackers[1].is_none());
assert!(a_trackers.is_added());
assert!(a_trackers.is_changed());
world.clear_trackers();
let trackers = trackers_query.iter(&world).collect::<Vec<_>>();
let a_trackers = trackers[0].as_ref().unwrap();
assert!(!a_trackers.is_added());
assert!(!a_trackers.is_changed());
*world.get_mut(e1).unwrap() = A(1);
let trackers = trackers_query.iter(&world).collect::<Vec<_>>();
let a_trackers = trackers[0].as_ref().unwrap();
assert!(!a_trackers.is_added());
assert!(a_trackers.is_changed());
}
#[test]
fn exact_size_query() {
let mut world = World::default();

View file

@ -1,7 +1,7 @@
use crate::{
archetype::{Archetype, ArchetypeComponentId},
change_detection::{Ticks, TicksMut},
component::{Component, ComponentId, ComponentStorage, ComponentTicks, StorageType, Tick},
component::{Component, ComponentId, ComponentStorage, StorageType, Tick},
entity::Entity,
query::{Access, DebugCheckedUnwrap, FilteredAccess},
storage::{ComponentSparseSet, Table, TableRow},
@ -37,7 +37,7 @@ use std::{cell::UnsafeCell, marker::PhantomData};
/// Wrapping it into an `Option` will increase the query search space, and it will return `None` if an entity doesn't satisfy the `WorldQuery`.
/// - **[`AnyOf`].**
/// Equivalent to wrapping each world query inside it into an `Option`.
/// - **[`ChangeTrackers`].**
/// - **[`Ref`].**
/// Similar to change detection filters but it is used as a query fetch parameter.
/// It exposes methods to check for changes to the wrapped component.
///
@ -1075,245 +1075,6 @@ unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
/// SAFETY: [`OptionFetch`] is read only because `T` is read only
unsafe impl<T: ReadOnlyWorldQuery> ReadOnlyWorldQuery for Option<T> {}
/// [`WorldQuery`] that tracks changes and additions for component `T`.
///
/// Wraps a [`Component`] to track whether the component changed for the corresponding entities in
/// a query since the last time the system that includes these queries ran.
///
/// If you only care about entities that changed or that got added use the
/// [`Changed`](crate::query::Changed) and [`Added`](crate::query::Added) filters instead.
///
/// # Examples
///
/// ```
/// # use bevy_ecs::component::Component;
/// # use bevy_ecs::query::ChangeTrackers;
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// #
/// # #[derive(Component, Debug)]
/// # struct Name {};
/// # #[derive(Component)]
/// # struct Transform {};
/// #
/// fn print_moving_objects_system(query: Query<(&Name, ChangeTrackers<Transform>)>) {
/// for (name, tracker) in &query {
/// if tracker.is_changed() {
/// println!("Entity moved: {:?}", name);
/// } else {
/// println!("Entity stood still: {:?}", name);
/// }
/// }
/// }
/// # bevy_ecs::system::assert_is_system(print_moving_objects_system);
/// ```
#[deprecated = "`ChangeTrackers<T>` will be removed in bevy 0.11. Use `bevy_ecs::prelude::Ref<T>` instead."]
pub struct ChangeTrackers<T: Component> {
pub(crate) component_ticks: ComponentTicks,
pub(crate) last_run: Tick,
pub(crate) this_run: Tick,
marker: PhantomData<T>,
}
#[allow(deprecated)]
impl<T: Component> Clone for ChangeTrackers<T> {
fn clone(&self) -> Self {
*self
}
}
#[allow(deprecated)]
impl<T: Component> Copy for ChangeTrackers<T> {}
#[allow(deprecated)]
impl<T: Component> std::fmt::Debug for ChangeTrackers<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ChangeTrackers")
.field("component_ticks", &self.component_ticks)
.field("last_run", &self.last_run)
.field("this_run", &self.this_run)
.finish()
}
}
#[allow(deprecated)]
impl<T: Component> ChangeTrackers<T> {
/// Returns true if this component has been added since the last execution of this system.
pub fn is_added(&self) -> bool {
self.component_ticks.is_added(self.last_run, self.this_run)
}
/// Returns true if this component has been changed since the last execution of this system.
pub fn is_changed(&self) -> bool {
self.component_ticks
.is_changed(self.last_run, self.this_run)
}
}
#[doc(hidden)]
pub struct ChangeTrackersFetch<'w, T> {
// T::Storage = TableStorage
table_added: Option<ThinSlicePtr<'w, UnsafeCell<Tick>>>,
table_changed: Option<ThinSlicePtr<'w, UnsafeCell<Tick>>>,
// T::Storage = SparseStorage
sparse_set: Option<&'w ComponentSparseSet>,
marker: PhantomData<T>,
last_run: Tick,
this_run: Tick,
}
#[allow(deprecated)]
// SAFETY: `ROQueryFetch<Self>` is the same as `QueryFetch<Self>`
unsafe impl<T: Component> WorldQuery for ChangeTrackers<T> {
type Fetch<'w> = ChangeTrackersFetch<'w, T>;
type Item<'w> = ChangeTrackers<T>;
type ReadOnly = Self;
type State = ComponentId;
fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
item
}
const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
};
const IS_ARCHETYPAL: bool = true;
unsafe fn init_fetch<'w>(
world: &'w World,
&component_id: &ComponentId,
last_run: Tick,
this_run: Tick,
) -> ChangeTrackersFetch<'w, T> {
ChangeTrackersFetch {
table_added: None,
table_changed: None,
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
world
.storages()
.sparse_sets
.get(component_id)
.debug_checked_unwrap()
}),
marker: PhantomData,
last_run,
this_run,
}
}
unsafe fn clone_fetch<'w>(fetch: &Self::Fetch<'w>) -> Self::Fetch<'w> {
ChangeTrackersFetch {
table_added: fetch.table_added,
table_changed: fetch.table_changed,
sparse_set: fetch.sparse_set,
marker: fetch.marker,
last_run: fetch.last_run,
this_run: fetch.this_run,
}
}
#[inline]
unsafe fn set_archetype<'w>(
fetch: &mut ChangeTrackersFetch<'w, T>,
component_id: &ComponentId,
_archetype: &'w Archetype,
table: &'w Table,
) {
if Self::IS_DENSE {
Self::set_table(fetch, component_id, table);
}
}
#[inline]
unsafe fn set_table<'w>(
fetch: &mut ChangeTrackersFetch<'w, T>,
&id: &ComponentId,
table: &'w Table,
) {
let column = table.get_column(id).debug_checked_unwrap();
fetch.table_added = Some(column.get_added_ticks_slice().into());
fetch.table_changed = Some(column.get_changed_ticks_slice().into());
}
#[inline(always)]
unsafe fn fetch<'w>(
fetch: &mut Self::Fetch<'w>,
entity: Entity,
table_row: TableRow,
) -> Self::Item<'w> {
match T::Storage::STORAGE_TYPE {
StorageType::Table => ChangeTrackers {
component_ticks: {
ComponentTicks {
added: fetch
.table_added
.debug_checked_unwrap()
.get(table_row.index())
.read(),
changed: fetch
.table_changed
.debug_checked_unwrap()
.get(table_row.index())
.read(),
}
},
marker: PhantomData,
last_run: fetch.last_run,
this_run: fetch.this_run,
},
StorageType::SparseSet => ChangeTrackers {
component_ticks: fetch
.sparse_set
.debug_checked_unwrap()
.get_ticks(entity)
.debug_checked_unwrap(),
marker: PhantomData,
last_run: fetch.last_run,
this_run: fetch.this_run,
},
}
}
fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess<ComponentId>) {
assert!(
!access.access().has_write(id),
"ChangeTrackers<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
std::any::type_name::<T>()
);
access.add_read(id);
}
fn update_archetype_component_access(
&id: &ComponentId,
archetype: &Archetype,
access: &mut Access<ArchetypeComponentId>,
) {
if let Some(archetype_component_id) = archetype.get_archetype_component_id(id) {
access.add_read(archetype_component_id);
}
}
fn init_state(world: &mut World) -> ComponentId {
world.init_component::<T>()
}
fn matches_component_set(
&id: &ComponentId,
set_contains_id: &impl Fn(ComponentId) -> bool,
) -> bool {
set_contains_id(id)
}
}
#[allow(deprecated)]
/// SAFETY: access is read only
unsafe impl<T: Component> ReadOnlyWorldQuery for ChangeTrackers<T> {}
macro_rules! impl_tuple_fetch {
($(($name: ident, $state: ident)),*) => {
#[allow(non_snake_case)]

View file

@ -596,7 +596,7 @@ impl_tick_filter!(
/// Bevy does not compare components to their previous values.
///
/// To retain all results without filtering but still check whether they were changed after the
/// system last ran, use [`ChangeTrackers<T>`](crate::query::ChangeTrackers).
/// system last ran, use [`Ref<T>`](crate::change_detection::Ref).
///
/// # Examples
///