Use a default implementation for set_if_neq (#7660)
# Objective While porting my crate `bevy_trait_query` to bevy 0.10, I ran into an issue with the `DetectChangesMut` trait. Due to the way that the `set_if_neq` method (added in #6853) is implemented, you are forced to write a nonsense implementation of it for dynamically sized types. This edge case shows up when implementing trait queries, since `DetectChangesMut` is implemented for `Mut<dyn Trait>`. ## Solution Simplify the generics for `set_if_neq` and add the `where Self::Target: Sized` trait bound to it. Add a default implementation so implementers don't need to implement a method with nonsensical trait bounds.
This commit is contained in:
parent
4f57f380c7
commit
670c4c1852
@ -125,10 +125,17 @@ pub trait DetectChangesMut: DetectChanges {
|
||||
///
|
||||
/// This is useful to ensure change detection is only triggered when the underlying value
|
||||
/// changes, instead of every time [`DerefMut`] is used.
|
||||
fn set_if_neq<Target>(&mut self, value: Target)
|
||||
#[inline]
|
||||
fn set_if_neq(&mut self, value: Self::Inner)
|
||||
where
|
||||
Self: Deref<Target = Target> + DerefMut<Target = Target>,
|
||||
Target: PartialEq;
|
||||
Self::Inner: Sized + PartialEq,
|
||||
{
|
||||
let old = self.bypass_change_detection();
|
||||
if *old != value {
|
||||
*old = value;
|
||||
self.set_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! change_detection_impl {
|
||||
@ -195,19 +202,6 @@ macro_rules! change_detection_mut_impl {
|
||||
fn bypass_change_detection(&mut self) -> &mut Self::Inner {
|
||||
self.value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_if_neq<Target>(&mut self, value: Target)
|
||||
where
|
||||
Self: Deref<Target = Target> + DerefMut<Target = Target>,
|
||||
Target: PartialEq,
|
||||
{
|
||||
// This dereference is immutable, so does not trigger change detection
|
||||
if *<Self as Deref>::deref(self) != value {
|
||||
// `DerefMut` usage triggers change detection
|
||||
*<Self as DerefMut>::deref_mut(self) = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<$($generics),* : ?Sized $(+ $traits)?> DerefMut for $name<$($generics),*> {
|
||||
@ -685,19 +679,6 @@ impl<'a> DetectChangesMut for MutUntyped<'a> {
|
||||
fn bypass_change_detection(&mut self) -> &mut Self::Inner {
|
||||
&mut self.value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_if_neq<Target>(&mut self, value: Target)
|
||||
where
|
||||
Self: Deref<Target = Target> + DerefMut<Target = Target>,
|
||||
Target: PartialEq,
|
||||
{
|
||||
// This dereference is immutable, so does not trigger change detection
|
||||
if *<Self as Deref>::deref(self) != value {
|
||||
// `DerefMut` usage triggers change detection
|
||||
*<Self as DerefMut>::deref_mut(self) = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for MutUntyped<'_> {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user