mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Deprecate ChangeTrackers<T>
in favor of Ref<T>
(#7306)
# Objective `ChangeTrackers<>` is a `WorldQuery` type that lets you access the change ticks for a component. #7097 has added `Ref<>`, which gives access to a component's value in addition to its change ticks. Since bevy's access model does not separate a component's value from its change ticks, there is no benefit to using `ChangeTrackers<T>` over `Ref<T>`. ## Solution Deprecate `ChangeTrackers<>`. --- ## Changelog * `ChangeTrackers<T>` has been deprecated. It will be removed in Bevy 0.11. ## Migration Guide `ChangeTrackers<T>` has been deprecated, and will be removed in the next release. Any usage should be replaced with `Ref<T>`. ```rust // Before (0.9) fn my_system(q: Query<(&MyComponent, ChangeTrackers<MyComponent>)>) { for (value, trackers) in &q { if trackers.is_changed() { // Do something with `value`. } } } // After (0.10) fn my_system(q: Query<Ref<MyComponent>>) { for value in &q { if value.is_changed() { // Do something with `value`. } } } ```
This commit is contained in:
parent
0af001edd4
commit
5a5125671b
5 changed files with 40 additions and 33 deletions
|
@ -696,10 +696,9 @@ mod tests {
|
|||
use crate::{
|
||||
self as bevy_ecs,
|
||||
change_detection::{
|
||||
Mut, NonSendMut, ResMut, TicksMut, CHECK_TICK_THRESHOLD, MAX_CHANGE_AGE,
|
||||
Mut, NonSendMut, Ref, ResMut, TicksMut, CHECK_TICK_THRESHOLD, MAX_CHANGE_AGE,
|
||||
},
|
||||
component::{Component, ComponentTicks, Tick},
|
||||
query::ChangeTrackers,
|
||||
system::{IntoSystem, Query, System},
|
||||
world::World,
|
||||
};
|
||||
|
@ -718,11 +717,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn change_expiration() {
|
||||
fn change_detected(query: Query<ChangeTrackers<C>>) -> bool {
|
||||
fn change_detected(query: Query<Ref<C>>) -> bool {
|
||||
query.single().is_changed()
|
||||
}
|
||||
|
||||
fn change_expired(query: Query<ChangeTrackers<C>>) -> bool {
|
||||
fn change_expired(query: Query<Ref<C>>) -> bool {
|
||||
query.single().is_changed()
|
||||
}
|
||||
|
||||
|
@ -753,7 +752,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn change_tick_wraparound() {
|
||||
fn change_detected(query: Query<ChangeTrackers<C>>) -> bool {
|
||||
fn change_detected(query: Query<Ref<C>>) -> bool {
|
||||
query.single().is_changed()
|
||||
}
|
||||
|
||||
|
@ -784,10 +783,10 @@ mod tests {
|
|||
*world.change_tick.get_mut() += MAX_CHANGE_AGE + CHECK_TICK_THRESHOLD;
|
||||
let change_tick = world.change_tick();
|
||||
|
||||
let mut query = world.query::<ChangeTrackers<C>>();
|
||||
let mut query = world.query::<Ref<C>>();
|
||||
for tracker in query.iter(&world) {
|
||||
let ticks_since_insert = change_tick.wrapping_sub(tracker.component_ticks.added.tick);
|
||||
let ticks_since_change = change_tick.wrapping_sub(tracker.component_ticks.changed.tick);
|
||||
let ticks_since_insert = change_tick.wrapping_sub(tracker.ticks.added.tick);
|
||||
let ticks_since_change = change_tick.wrapping_sub(tracker.ticks.changed.tick);
|
||||
assert!(ticks_since_insert > MAX_CHANGE_AGE);
|
||||
assert!(ticks_since_change > MAX_CHANGE_AGE);
|
||||
}
|
||||
|
@ -796,8 +795,8 @@ mod tests {
|
|||
world.check_change_ticks();
|
||||
|
||||
for tracker in query.iter(&world) {
|
||||
let ticks_since_insert = change_tick.wrapping_sub(tracker.component_ticks.added.tick);
|
||||
let ticks_since_change = change_tick.wrapping_sub(tracker.component_ticks.changed.tick);
|
||||
let ticks_since_insert = change_tick.wrapping_sub(tracker.ticks.added.tick);
|
||||
let ticks_since_change = change_tick.wrapping_sub(tracker.ticks.changed.tick);
|
||||
assert!(ticks_since_insert == MAX_CHANGE_AGE);
|
||||
assert!(ticks_since_change == MAX_CHANGE_AGE);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@ 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};
|
||||
|
@ -35,7 +38,7 @@ pub mod prelude {
|
|||
component::Component,
|
||||
entity::Entity,
|
||||
event::{Event, EventReader, EventWriter, Events},
|
||||
query::{Added, AnyOf, ChangeTrackers, Changed, Or, QueryState, With, Without},
|
||||
query::{Added, AnyOf, Changed, Or, QueryState, With, Without},
|
||||
removal_detection::RemovedComponents,
|
||||
schedule::{
|
||||
apply_state_transition, apply_system_buffers, common_conditions::*, IntoSystemConfig,
|
||||
|
@ -63,11 +66,10 @@ mod tests {
|
|||
use crate::prelude::Or;
|
||||
use crate::{
|
||||
bundle::Bundle,
|
||||
change_detection::Ref,
|
||||
component::{Component, ComponentId},
|
||||
entity::Entity,
|
||||
query::{
|
||||
Added, ChangeTrackers, Changed, FilteredAccess, ReadOnlyWorldQuery, With, Without,
|
||||
},
|
||||
query::{Added, Changed, FilteredAccess, ReadOnlyWorldQuery, With, Without},
|
||||
system::Resource,
|
||||
world::{Mut, World},
|
||||
};
|
||||
|
@ -1297,7 +1299,10 @@ mod tests {
|
|||
}
|
||||
|
||||
#[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));
|
||||
|
@ -1541,7 +1546,7 @@ mod tests {
|
|||
assert_eq!(1, query_min_size![&B, (With<A>, With<C>)],);
|
||||
assert_eq!(1, query_min_size![(&A, &B), With<C>],);
|
||||
assert_eq!(4, query_min_size![&A, ()], "Simple Archetypal");
|
||||
assert_eq!(4, query_min_size![ChangeTrackers<A>, ()],);
|
||||
assert_eq!(4, query_min_size![Ref<A>, ()],);
|
||||
// All the following should set minimum size to 0, as it's impossible to predict
|
||||
// how many entities the filters will trim.
|
||||
assert_eq!(0, query_min_size![(), Added<A>], "Simple Added");
|
||||
|
|
|
@ -1115,6 +1115,7 @@ unsafe impl<T: ReadOnlyWorldQuery> ReadOnlyWorldQuery for Option<T> {}
|
|||
/// }
|
||||
/// # 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_change_tick: u32,
|
||||
|
@ -1122,18 +1123,17 @@ pub struct ChangeTrackers<T: Component> {
|
|||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<T: Component> Clone for ChangeTrackers<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
component_ticks: self.component_ticks,
|
||||
last_change_tick: self.last_change_tick,
|
||||
change_tick: self.change_tick,
|
||||
marker: PhantomData,
|
||||
}
|
||||
*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")
|
||||
|
@ -1144,6 +1144,7 @@ impl<T: Component> std::fmt::Debug for ChangeTrackers<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[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 {
|
||||
|
@ -1171,6 +1172,7 @@ pub struct ChangeTrackersFetch<'w, T> {
|
|||
change_tick: u32,
|
||||
}
|
||||
|
||||
#[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>;
|
||||
|
@ -1317,6 +1319,7 @@ unsafe impl<T: Component> WorldQuery for ChangeTrackers<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
/// SAFETY: access is read only
|
||||
unsafe impl<T: Component> ReadOnlyWorldQuery for ChangeTrackers<T> {}
|
||||
|
||||
|
|
|
@ -572,7 +572,7 @@ impl_tick_filter!(
|
|||
/// A common use for this filter is one-time initialization.
|
||||
///
|
||||
/// To retain all results without filtering but still check whether they were added after the
|
||||
/// system last ran, use [`ChangeTrackers<T>`](crate::query::ChangeTrackers).
|
||||
/// system last ran, use [`Ref<T>`](crate::change_detection::Ref).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! This example illustrates how to react to component change.
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy::{ecs::world::Ref, prelude::*};
|
||||
use rand::Rng;
|
||||
|
||||
fn main() {
|
||||
|
@ -43,15 +43,15 @@ fn change_detection(query: Query<(Entity, &MyComponent), Changed<MyComponent>>)
|
|||
}
|
||||
}
|
||||
|
||||
// By looking at trackers, the query is not filtered but the information is available
|
||||
fn tracker_monitoring(
|
||||
query: Query<(
|
||||
Entity,
|
||||
Option<&MyComponent>,
|
||||
Option<ChangeTrackers<MyComponent>>,
|
||||
)>,
|
||||
) {
|
||||
for (entity, component, trackers) in &query {
|
||||
info!("{:?}: {:?} -> {:?}", entity, component, trackers);
|
||||
// By using `Ref`, the query is not filtered but the information is available
|
||||
fn tracker_monitoring(query: Query<(Entity, Ref<MyComponent>)>) {
|
||||
for (entity, component) in &query {
|
||||
info!(
|
||||
"{:?}: {:?} -> {{is_added: {}, is_changed: {}}}",
|
||||
entity,
|
||||
component,
|
||||
component.is_added(),
|
||||
component.is_changed()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue