mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 22:20:20 +00:00
Remove ChangeTrackers (#7902)
This commit is contained in:
parent
3ec764ea24
commit
7d9cb1c4ab
3 changed files with 3 additions and 272 deletions
|
@ -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();
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
Loading…
Reference in a new issue