Reflect::try_compare draft

This commit is contained in:
Dmitry Stepanov
2026-06-05 23:06:29 +03:00
parent 6ffc26b274
commit 0965df060c
8 changed files with 47 additions and 4 deletions
+14
View File
@@ -443,6 +443,18 @@ fn gen_impl(
}
};
let try_compare = if ty_args.non_comparable {
quote! {
fn try_compare(&self, _other: &dyn Reflect) -> Option<bool> { None }
}
} else {
quote! {
fn try_compare(&self, other: &dyn Reflect) -> Option<bool> {
(other as &dyn Any).downcast_ref::<Self>().map(|other| other == self)
}
}
};
let type_uuid_str = ty_args.type_uuid.as_str();
let type_uuid = if ty_args.generics.params.is_empty() {
quote! { uuid!(#type_uuid_str) }
@@ -494,6 +506,8 @@ fn gen_impl(
#try_clone_box
#try_compare
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
#metadata_ref
}
+3
View File
@@ -63,6 +63,9 @@ pub struct TypeArgs {
#[darling(default)]
pub non_cloneable: bool,
#[darling(default)]
pub non_comparable: bool,
#[darling(default)]
pub clone_fn: Option<Path>,
+1 -1
View File
@@ -37,7 +37,7 @@ use fyrox_core_derive::{impl_reflect, impl_visit};
impl_reflect!(
#[reflect(type_uuid = "64ef33b7-d05a-4d8d-b0c7-99bcc919271f")]
pub struct Rect<T: Reflect + Copy> {}
pub struct Rect<T: Reflect + Copy + PartialEq> {}
);
impl<T> Visit for Rect<T>
+6
View File
@@ -207,6 +207,12 @@ impl<T: Reflect> Reflect for Handle<T> {
None
}
}
fn try_compare(&self, other: &dyn Reflect) -> Option<bool> {
(other as &dyn std::any::Any)
.downcast_ref::<Self>()
.map(|other| other == self)
}
}
impl<T> Copy for Handle<T> {}
+6
View File
@@ -170,6 +170,12 @@ where
Some(Box::new(self.clone()))
}
fn try_compare(&self, other: &dyn Reflect) -> Option<bool> {
(other as &dyn std::any::Any)
.downcast_ref::<Self>()
.map(|other| other == self)
}
#[inline]
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
func(&[])
+2
View File
@@ -334,6 +334,8 @@ macro_rules! impl_reflect_inner_mutability {
Some(Box::new($clone))
}
fn fields_ref(&$self, func: &mut dyn FnMut(&[FieldRef])) {
let guard = $acquire_lock_guard;
func(&[{
+6
View File
@@ -158,6 +158,12 @@ macro_rules! blank_reflect {
Some(Box::new(self.clone()))
}
fn try_compare(&self, other: &dyn Reflect) -> Option<bool> {
(other as &dyn std::any::Any)
.downcast_ref::<Self>()
.map(|other| other == self)
}
fn fields_ref(&self, func: &mut dyn FnMut(&[$crate::reflect::FieldRef])) {
func(&[])
}
+9 -3
View File
@@ -53,6 +53,7 @@ pub mod prelude {
TypeInfo,
};
pub use crate::uuid::{uuid, Uuid};
pub use std::any::Any;
}
#[inline]
@@ -175,6 +176,11 @@ pub trait Reflect: Any + Debug {
/// [`None`] for non-cloneable objects.
fn try_clone_box(&self) -> Option<Box<dyn Reflect>>;
/// Tries to compare this object with some other. The result is `Some(bool)` if the underlying
/// type implements [`PartialEq`] trait, `None` - otherwise or if the type is marked with
/// `#[reflect(non_comparable)]` attribute.
fn try_compare(&self, other: &dyn Reflect) -> Option<bool>;
/// Calls the given closure with the reference to a slice that contains description for all
/// fields in the object.
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef]));
@@ -1021,7 +1027,7 @@ mod test {
},
}
#[derive(Reflect, Clone, Default, Debug)]
#[derive(Reflect, Clone, Default, Debug, PartialEq)]
#[reflect(type_uuid = "97718a85-3901-407e-9347-b684c0047743")]
struct Foo {
enum_field: InheritableVariable<Enum>,
@@ -1031,13 +1037,13 @@ mod test {
hash_map: HashMap<String, Item>,
}
#[derive(Reflect, Clone, Default, Debug)]
#[derive(Reflect, Clone, Default, Debug, PartialEq)]
#[reflect(type_uuid = "9465ea72-dd27-43f3-8ccf-b634e4b2887f")]
struct Item {
payload: u32,
}
#[derive(Reflect, Clone, Default, Debug)]
#[derive(Reflect, Clone, Default, Debug, PartialEq)]
#[reflect(type_uuid = "8fb478ac-e4c4-4762-a43a-451147e6e509")]
struct Bar {
stuff: String,