mirror of
https://github.com/bevyengine/bevy
synced 2024-11-13 00:17:27 +00:00
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>
This commit is contained in:
parent
f69e923c27
commit
dfdc9f8369
1 changed files with 49 additions and 0 deletions
|
@ -381,6 +381,15 @@ macro_rules! impl_methods {
|
||||||
ticks: self.ticks,
|
ticks: self.ticks,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allows you access to the dereferenced value of this pointer without immediately
|
||||||
|
/// triggering change detection.
|
||||||
|
pub fn as_deref_mut(&mut self) -> Mut<'_, <$target as Deref>::Target>
|
||||||
|
where $target: DerefMut
|
||||||
|
{
|
||||||
|
self.reborrow().map_unchanged(|v| v.deref_mut())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -907,6 +916,7 @@ mod tests {
|
||||||
use bevy_ecs_macros::Resource;
|
use bevy_ecs_macros::Resource;
|
||||||
use bevy_ptr::PtrMut;
|
use bevy_ptr::PtrMut;
|
||||||
use bevy_reflect::{FromType, ReflectFromPtr};
|
use bevy_reflect::{FromType, ReflectFromPtr};
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
self as bevy_ecs,
|
self as bevy_ecs,
|
||||||
|
@ -929,6 +939,19 @@ mod tests {
|
||||||
#[derive(Resource, PartialEq)]
|
#[derive(Resource, PartialEq)]
|
||||||
struct R2(u8);
|
struct R2(u8);
|
||||||
|
|
||||||
|
impl Deref for R2 {
|
||||||
|
type Target = u8;
|
||||||
|
fn deref(&self) -> &u8 {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for R2 {
|
||||||
|
fn deref_mut(&mut self) -> &mut u8 {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn change_expiration() {
|
fn change_expiration() {
|
||||||
fn change_detected(query: Query<Ref<C>>) -> bool {
|
fn change_detected(query: Query<Ref<C>>) -> bool {
|
||||||
|
@ -1143,6 +1166,32 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn as_deref_mut() {
|
||||||
|
let mut world = World::new();
|
||||||
|
|
||||||
|
world.insert_resource(R2(0));
|
||||||
|
// Resources are Changed when first added
|
||||||
|
world.increment_change_tick();
|
||||||
|
// This is required to update world::last_change_tick
|
||||||
|
world.clear_trackers();
|
||||||
|
|
||||||
|
let mut r = world.resource_mut::<R2>();
|
||||||
|
assert!(!r.is_changed(), "Resource must begin unchanged.");
|
||||||
|
|
||||||
|
let mut r = r.as_deref_mut();
|
||||||
|
assert!(
|
||||||
|
!r.is_changed(),
|
||||||
|
"Dereferencing should not mark the item as changed yet"
|
||||||
|
);
|
||||||
|
|
||||||
|
r.set_if_neq(3);
|
||||||
|
assert!(
|
||||||
|
r.is_changed(),
|
||||||
|
"Resource must be changed after setting to a different value."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mut_untyped_to_reflect() {
|
fn mut_untyped_to_reflect() {
|
||||||
let last_run = Tick::new(2);
|
let last_run = Tick::new(2);
|
||||||
|
|
Loading…
Reference in a new issue