Skip to content

Commit dfdc9f8

Browse files
Testarealice-i-cecilejoseph-gio
authored
as_deref_mut() method for Mut-like types (#9912)
# Objective Add a new method so you can do `set_if_neq` with dereferencing components: `as_deref_mut()`! ## Solution Added an as_deref_mut method so that we can use `set_if_neq()` without having to wrap up types for derefencable components --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Joseph <21144246+JoJoJet@users.noreply.github.com>
1 parent f69e923 commit dfdc9f8

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

crates/bevy_ecs/src/change_detection.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,15 @@ macro_rules! impl_methods {
381381
ticks: self.ticks,
382382
}
383383
}
384+
385+
/// Allows you access to the dereferenced value of this pointer without immediately
386+
/// triggering change detection.
387+
pub fn as_deref_mut(&mut self) -> Mut<'_, <$target as Deref>::Target>
388+
where $target: DerefMut
389+
{
390+
self.reborrow().map_unchanged(|v| v.deref_mut())
391+
}
392+
384393
}
385394
};
386395
}
@@ -907,6 +916,7 @@ mod tests {
907916
use bevy_ecs_macros::Resource;
908917
use bevy_ptr::PtrMut;
909918
use bevy_reflect::{FromType, ReflectFromPtr};
919+
use std::ops::{Deref, DerefMut};
910920

911921
use crate::{
912922
self as bevy_ecs,
@@ -929,6 +939,19 @@ mod tests {
929939
#[derive(Resource, PartialEq)]
930940
struct R2(u8);
931941

942+
impl Deref for R2 {
943+
type Target = u8;
944+
fn deref(&self) -> &u8 {
945+
&self.0
946+
}
947+
}
948+
949+
impl DerefMut for R2 {
950+
fn deref_mut(&mut self) -> &mut u8 {
951+
&mut self.0
952+
}
953+
}
954+
932955
#[test]
933956
fn change_expiration() {
934957
fn change_detected(query: Query<Ref<C>>) -> bool {
@@ -1143,6 +1166,32 @@ mod tests {
11431166
);
11441167
}
11451168

1169+
#[test]
1170+
fn as_deref_mut() {
1171+
let mut world = World::new();
1172+
1173+
world.insert_resource(R2(0));
1174+
// Resources are Changed when first added
1175+
world.increment_change_tick();
1176+
// This is required to update world::last_change_tick
1177+
world.clear_trackers();
1178+
1179+
let mut r = world.resource_mut::<R2>();
1180+
assert!(!r.is_changed(), "Resource must begin unchanged.");
1181+
1182+
let mut r = r.as_deref_mut();
1183+
assert!(
1184+
!r.is_changed(),
1185+
"Dereferencing should not mark the item as changed yet"
1186+
);
1187+
1188+
r.set_if_neq(3);
1189+
assert!(
1190+
r.is_changed(),
1191+
"Resource must be changed after setting to a different value."
1192+
);
1193+
}
1194+
11461195
#[test]
11471196
fn mut_untyped_to_reflect() {
11481197
let last_run = Tick::new(2);

0 commit comments

Comments
 (0)