mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
Reflect::first_field_ref/mut_of_type
This commit is contained in:
@@ -482,11 +482,11 @@ fn gen_impl(
|
||||
Ok(Box::new(this))
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, reflect_argument_index: usize) -> Option<FieldRef> {
|
||||
fn field_direct_ref(&self, reflect_argument_index: usize) -> Option<FieldRef> {
|
||||
#getter_ref
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, reflect_argument_index: usize) -> Option<FieldMut> {
|
||||
fn field_direct_mut(&mut self, reflect_argument_index: usize) -> Option<FieldMut> {
|
||||
#getter_mut
|
||||
}
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ impl Reflect for DynTypeWrapper {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
if index == 0 {
|
||||
Some(FieldRef {
|
||||
metadata: &CONTENT_METADATA,
|
||||
@@ -254,7 +254,7 @@ impl Reflect for DynTypeWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
if index == 0 {
|
||||
Some(FieldMut {
|
||||
metadata: &CONTENT_METADATA,
|
||||
|
||||
@@ -213,7 +213,7 @@ impl<T: Reflect> Reflect for Handle<T> {
|
||||
func(Some(self))
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
if index == 0 {
|
||||
Some(FieldRef {
|
||||
metadata: &INDEX_METADATA,
|
||||
@@ -229,7 +229,7 @@ impl<T: Reflect> Reflect for Handle<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
if index == 0 {
|
||||
Some(FieldMut {
|
||||
metadata: &INDEX_METADATA,
|
||||
|
||||
@@ -226,11 +226,11 @@ where
|
||||
env!("CARGO_PKG_NAME")
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, _index: usize) -> Option<FieldRef> {
|
||||
fn field_direct_ref(&self, _index: usize) -> Option<FieldRef> {
|
||||
None
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, _index: usize) -> Option<FieldMut> {
|
||||
fn field_direct_mut(&mut self, _index: usize) -> Option<FieldMut> {
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
@@ -210,13 +210,13 @@ macro_rules! impl_reflect_inner_mutability {
|
||||
guard.set(value)
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
warn!("Cannot get a direct field ref {index}, because it is \
|
||||
not supported for types with interior mutability.");
|
||||
None
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
warn!("Cannot get a direct field ref {index}, because it is \
|
||||
not supported for types with interior mutability.");
|
||||
None
|
||||
|
||||
@@ -200,12 +200,12 @@ macro_rules! delegate_reflect {
|
||||
self.deref_mut().as_reflect_mut(func)
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.deref().get_field_direct_ref(index)
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.deref().field_direct_ref(index)
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.deref_mut().get_field_direct_mut(index)
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.deref_mut().field_direct_mut(index)
|
||||
}
|
||||
|
||||
fn set(
|
||||
@@ -374,11 +374,11 @@ macro_rules! blank_reflect {
|
||||
func(if name == "self" { Some(self) } else { None })
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, _index: usize) -> Option<$crate::reflect::FieldRef> {
|
||||
fn field_direct_ref(&self, _index: usize) -> Option<$crate::reflect::FieldRef> {
|
||||
None
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, _index: usize) -> Option<$crate::reflect::FieldMut> {
|
||||
fn field_direct_mut(&mut self, _index: usize) -> Option<$crate::reflect::FieldMut> {
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ pub trait Reflect: Any + Debug {
|
||||
/// but returning a lock guard would require boxing which in most cases would ruin performance.
|
||||
/// If you need to get a field reference for types with interior mutability, then use
|
||||
/// [`Reflect::fields_ref`] instead.
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef>;
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef>;
|
||||
|
||||
/// Tries to get a mutable reference to a field at the specified index. Returns [`None`] in two cases:
|
||||
/// 1) The type does not have such field
|
||||
@@ -175,7 +175,7 @@ pub trait Reflect: Any + Debug {
|
||||
/// but returning a lock guard would require boxing which in most cases would ruin performance.
|
||||
/// If you need to get a field reference for types with interior mutability, then use
|
||||
/// [`Reflect::fields_ref`] instead.
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut>;
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut>;
|
||||
|
||||
/// Returns the total number of fields.
|
||||
fn fields_count(&self) -> usize {
|
||||
@@ -307,6 +307,46 @@ impl dyn Reflect {
|
||||
self.as_any_mut(&mut |any| func(any.downcast_mut::<T>()))
|
||||
}
|
||||
|
||||
/// Tries to find the first field of the given type. This method internally uses
|
||||
/// [`Reflect::field_direct_ref`] with all of its limitations.
|
||||
#[inline]
|
||||
pub fn first_field_ref_of_type<T: Reflect>(&self) -> Option<&T> {
|
||||
let count = self.fields_count();
|
||||
|
||||
for i in 0..count {
|
||||
if let Some(field) = self.field_direct_ref(i) {
|
||||
if let Some(typed_field) = (field.value as &dyn Any).downcast_ref::<T>() {
|
||||
return Some(typed_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Tries to find the first field of the given type. This method internally uses
|
||||
/// [`Reflect::field_direct_ref`] with all of its limitations.
|
||||
#[inline]
|
||||
pub fn first_field_mut_of_type<T: Reflect>(&mut self) -> Option<&mut T> {
|
||||
let count = self.fields_count();
|
||||
|
||||
for i in 0..count {
|
||||
// SAFETY: Current implementation of borrow checker is just dumb. When a reborrow of self
|
||||
// happens in every iteration of the loop, it assigns a new lifetime to the new reference.
|
||||
// This way the returned reference has a different lifetime than in the method definition.
|
||||
// The following unsafe block reborrows self with the correct lifetime, while the initial
|
||||
// reference is not used so this is absolutely safe.
|
||||
let this = unsafe { &mut *(self as *mut Self) };
|
||||
if let Some(field) = this.field_direct_mut(i) {
|
||||
if let Some(typed_field) = (field.value as &mut dyn Any).downcast_mut::<T>() {
|
||||
return Some(typed_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Sets a field by its path in the given entity. This method always uses [`Reflect::set_field`] which means,
|
||||
/// that it will always call custom property setters.
|
||||
#[inline]
|
||||
@@ -983,10 +1023,12 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn enumerate_fields_recursively() {
|
||||
let baz = 123.321;
|
||||
|
||||
let foo = Foo {
|
||||
enum_field: Enum::Stuff { field: 123 }.into(),
|
||||
bar: Default::default(),
|
||||
baz: 0.0,
|
||||
baz,
|
||||
collection: vec![Item::default()],
|
||||
hash_map: [("Foobar".to_string(), Item::default())].into(),
|
||||
};
|
||||
@@ -1020,6 +1062,13 @@ mod test {
|
||||
assert_eq!(names[11], "hash_map[Foobar].payload");
|
||||
|
||||
assert_eq!(foo.fields_count(), 5);
|
||||
|
||||
assert_eq!(
|
||||
(&foo as &dyn Reflect)
|
||||
.first_field_ref_of_type::<f32>()
|
||||
.unwrap(),
|
||||
&baz
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
|
||||
@@ -543,12 +543,12 @@ where
|
||||
func(Some(self))
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.value.get_field_direct_ref(index)
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.value.field_direct_ref(index)
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.value.get_field_direct_mut(index)
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.value.field_direct_mut(index)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1815,12 +1815,12 @@ mod test {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef<'_, '_>> {
|
||||
self.0.deref().get_field_direct_ref(index)
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef<'_, '_>> {
|
||||
self.0.deref().field_direct_ref(index)
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut<'_, '_>> {
|
||||
self.0.deref_mut().get_field_direct_mut(index)
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut<'_, '_>> {
|
||||
self.0.deref_mut().field_direct_mut(index)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -662,12 +662,12 @@ impl Reflect for Node {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.0.deref().get_field_direct_ref(index)
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.0.deref().field_direct_ref(index)
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.0.deref_mut().get_field_direct_mut(index)
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.0.deref_mut().field_direct_mut(index)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -812,12 +812,12 @@ impl Reflect for Script {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.instance.deref().get_field_direct_ref(index)
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.instance.deref().field_direct_ref(index)
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.instance.deref_mut().get_field_direct_mut(index)
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.instance.deref_mut().field_direct_mut(index)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,12 +161,12 @@ impl Reflect for ResourceDataWrapper {
|
||||
env!("CARGO_PKG_NAME")
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef<'_, '_>> {
|
||||
self.deref().get_field_direct_ref(index)
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef<'_, '_>> {
|
||||
self.deref().field_direct_ref(index)
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut<'_, '_>> {
|
||||
self.deref_mut().get_field_direct_mut(index)
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut<'_, '_>> {
|
||||
self.deref_mut().field_direct_mut(index)
|
||||
}
|
||||
|
||||
fn set_field(
|
||||
|
||||
@@ -345,12 +345,12 @@ impl Reflect for UiNode {
|
||||
env!("CARGO_PKG_NAME")
|
||||
}
|
||||
|
||||
fn get_field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.0.deref().get_field_direct_ref(index)
|
||||
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
|
||||
self.0.deref().field_direct_ref(index)
|
||||
}
|
||||
|
||||
fn get_field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.0.deref_mut().get_field_direct_mut(index)
|
||||
fn field_direct_mut(&mut self, index: usize) -> Option<FieldMut> {
|
||||
self.0.deref_mut().field_direct_mut(index)
|
||||
}
|
||||
|
||||
fn set_field(
|
||||
|
||||
Reference in New Issue
Block a user