refactored Reflect::as_xxx methods to return value itself

- there's no reason anymore to use closures there because proxy structures now supports reflection in normal way
This commit is contained in:
Dmitry Stepanov
2026-05-21 18:22:39 +03:00
parent 1799856ea3
commit 480559e07a
16 changed files with 386 additions and 478 deletions
+34 -42
View File
@@ -544,38 +544,34 @@ impl<F: EntityGetter> CommandTrait for AddCollectionItemCommand<F> {
fn execute(&mut self, ctx: &mut dyn CommandContext) {
let entity = some_or_return!((self.entity_getter)(ctx));
try_modify_property(entity, &self.path, |field| {
field.as_list_mut(&mut |result| {
if let Some(list) = result {
if let Err(item) = list.reflect_push(self.item.take().unwrap()) {
err!(
"Failed to push item to {} collection. Type mismatch {} and {}!",
self.path,
item.type_info_ref().type_name,
list.type_info_ref().type_name
);
self.item = Some(item);
}
} else {
err!("Property {} is not a collection!", self.path)
if let Some(list) = field.as_list_mut() {
if let Err(item) = list.reflect_push(self.item.take().unwrap()) {
err!(
"Failed to push item to {} collection. Type mismatch {} and {}!",
self.path,
item.type_info_ref().type_name,
list.type_info_ref().type_name
);
self.item = Some(item);
}
});
} else {
err!("Property {} is not a collection!", self.path)
}
})
}
fn revert(&mut self, ctx: &mut dyn CommandContext) {
let entity = some_or_return!((self.entity_getter)(ctx));
try_modify_property(entity, &self.path, |field| {
field.as_list_mut(&mut |result| {
if let Some(list) = result {
if let Some(item) = list.reflect_pop() {
self.item = Some(item);
} else {
err!("Failed to pop item from {} collection!", self.path)
}
if let Some(list) = field.as_list_mut() {
if let Some(item) = list.reflect_pop() {
self.item = Some(item);
} else {
err!("Property {} is not a collection!", self.path)
err!("Failed to pop item from {} collection!", self.path)
}
});
} else {
err!("Property {} is not a collection!", self.path)
}
})
}
}
@@ -612,32 +608,28 @@ impl<F: EntityGetter> CommandTrait for RemoveCollectionItemCommand<F> {
fn execute(&mut self, ctx: &mut dyn CommandContext) {
let entity = some_or_return!((self.entity_getter)(ctx));
try_modify_property(entity, &self.path, |field| {
field.as_list_mut(&mut |result| {
if let Some(list) = result {
self.value = list.reflect_remove(self.index);
} else {
err!("Property {} is not a collection!", self.path)
}
})
if let Some(list) = field.as_list_mut() {
self.value = list.reflect_remove(self.index);
} else {
err!("Property {} is not a collection!", self.path)
}
})
}
fn revert(&mut self, ctx: &mut dyn CommandContext) {
let entity = some_or_return!((self.entity_getter)(ctx));
try_modify_property(entity, &self.path, |field| {
field.as_list_mut(&mut |result| {
if let Some(list) = result {
if let Err(item) = list.reflect_insert(self.index, self.value.take().unwrap()) {
self.value = Some(item);
err!(
"Failed to insert item to {} collection. Type mismatch!",
self.path
)
}
} else {
err!("Property {} is not a collection!", self.path)
if let Some(list) = field.as_list_mut() {
if let Err(item) = list.reflect_insert(self.index, self.value.take().unwrap()) {
self.value = Some(item);
err!(
"Failed to insert item to {} collection. Type mismatch!",
self.path
)
}
});
} else {
err!("Property {} is not a collection!", self.path)
}
})
}
}
+4 -4
View File
@@ -186,7 +186,7 @@ where
let mut processed = true;
field_ref.as_array(&mut |array| match array {
match field_ref.as_array() {
Some(array) => {
let mut descriptor = PropertyDescriptor {
path: path.clone(),
@@ -218,10 +218,10 @@ where
None => {
processed = false;
}
});
}
if !processed {
field_ref.as_hash_map(&mut |result| match result {
match field_ref.as_hash_map() {
Some(hash_map) => {
let mut descriptor = PropertyDescriptor {
path: path.clone(),
@@ -271,7 +271,7 @@ where
None => {
processed = false;
}
})
}
}
if !processed {
+8 -10
View File
@@ -461,16 +461,14 @@ impl SceneNodeContextMenu {
if let Ok(node) = scene.graph.try_get_node(*node_handle) {
(node as &dyn Reflect).enumerate_fields_recursively(
&mut |path, _, val| {
val.as_inheritable_variable(&mut |inheritable| {
if inheritable.is_some() {
commands.push(Command::new(
RevertSceneNodePropertyCommand::new(
path.to_string(),
*node_handle,
),
));
}
});
if val.as_inheritable_variable().is_some() {
commands.push(Command::new(
RevertSceneNodePropertyCommand::new(
path.to_string(),
*node_handle,
),
));
}
},
&[TypeId::of::<UntypedResource>()],
)
+3 -5
View File
@@ -409,11 +409,9 @@ impl BoundValue {
Ok(property) => {
let applied = self.value.apply_to_any(property, value_type);
if applied {
property.as_inheritable_variable_mut(&mut |var| {
if let Some(var) = var {
var.mark_modified();
}
});
if let Some(var) = property.as_inheritable_variable_mut() {
var.mark_modified();
}
}
}
Err(err) => {
+8 -8
View File
@@ -104,12 +104,12 @@ impl TypeArgs {
}
quote! {
fn as_list(&self, func: &mut dyn FnMut(Option<&dyn ReflectList>)) {
func(Some(self))
fn as_list(&self) -> Option<&dyn ReflectList> {
Some(self)
}
fn as_list_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
func(Some(self))
fn as_list_mut(&mut self) -> Option<&mut dyn ReflectList> {
Some(self)
}
}
}
@@ -120,12 +120,12 @@ impl TypeArgs {
}
quote! {
fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
func(Some(self))
fn as_array(&self) -> Option<&dyn ReflectArray> {
Some(self)
}
fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
func(Some(self))
fn as_array_mut(&mut self) -> Option<&mut dyn ReflectArray> {
Some(self)
}
}
}
+13 -16
View File
@@ -207,14 +207,12 @@ fn reflect_list() {
let mut data = vec![10usize, 11usize];
let data = &mut data as &mut dyn Reflect;
data.as_list_mut(&mut |data| {
let data = data.unwrap();
data.get_reflect_index(0, &mut |result| assert_eq!(result, Some(&10usize)));
data.get_reflect_index::<usize>(2, &mut |result| assert_eq!(result, None));
let data = data.as_list_mut().unwrap();
data.get_reflect_index(0, &mut |result| assert_eq!(result, Some(&10usize)));
data.get_reflect_index::<usize>(2, &mut |result| assert_eq!(result, None));
data.reflect_push(Box::new(12usize)).unwrap();
data.get_reflect_index(2, &mut |result| assert_eq!(result, Some(&12usize)));
});
data.reflect_push(Box::new(12usize)).unwrap();
data.get_reflect_index(2, &mut |result| assert_eq!(result, Some(&12usize)));
}
#[test]
@@ -654,21 +652,20 @@ fn test_hash_map() {
},
);
hash_map.as_hash_map(&mut |result| {
let hash_map = result.unwrap();
{
let hash_map = hash_map.as_hash_map().unwrap();
assert_eq!(hash_map.reflect_len(), 2);
hash_map.reflect_get(&foo_key, &mut |result| {
assert_eq!(result.unwrap().downcast_ref::<Struct>().unwrap().field, 123)
})
});
});
}
hash_map.as_hash_map_mut(&mut |result| {
let hash_map = result.unwrap();
{
let hash_map = hash_map.as_hash_map_mut().unwrap();
hash_map.reflect_get_mut(&bar_key, &mut |result| {
result.unwrap().downcast_mut::<Struct>().unwrap().field = 555
})
});
});
}
// Check path resolution.
#[derive(Reflect, Clone, Debug)]
+4 -4
View File
@@ -168,12 +168,12 @@ impl<T: Reflect> Reflect for Handle<T> {
Ok(Box::new(this))
}
fn as_handle(&self, func: &mut dyn FnMut(Option<&dyn ReflectHandle>)) {
func(Some(self))
fn as_handle(&self) -> Option<&dyn ReflectHandle> {
Some(self)
}
fn as_handle_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHandle>)) {
func(Some(self))
fn as_handle_mut(&mut self) -> Option<&mut dyn ReflectHandle> {
Some(self)
}
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
+4 -4
View File
@@ -191,13 +191,13 @@ where
}
#[inline]
fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
func(Some(self))
fn as_array(&self) -> Option<&dyn ReflectArray> {
Some(self)
}
#[inline]
fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
func(Some(self))
fn as_array_mut(&mut self) -> Option<&mut dyn ReflectArray> {
Some(self)
}
}
+4 -4
View File
@@ -67,12 +67,12 @@ impl<const N: usize, T: Reflect + Clone> ReflectArray for [T; N] {
impl<const N: usize, T: Reflect + Clone> Reflect for [T; N] {
blank_reflect!();
fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
func(Some(self))
fn as_array(&self) -> Option<&dyn ReflectArray> {
Some(self)
}
fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
func(Some(self))
fn as_array_mut(&mut self) -> Option<&mut dyn ReflectArray> {
Some(self)
}
}
+4 -4
View File
@@ -51,12 +51,12 @@ where
{
blank_reflect!();
fn as_hash_map(&self, func: &mut dyn FnMut(Option<&dyn ReflectHashMap>)) {
func(Some(self))
fn as_hash_map(&self) -> Option<&dyn ReflectHashMap> {
Some(self)
}
fn as_hash_map_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHashMap>)) {
func(Some(self))
fn as_hash_map_mut(&mut self) -> Option<&mut dyn ReflectHashMap> {
Some(self)
}
}
+125 -153
View File
@@ -247,50 +247,44 @@ pub trait Reflect: Any + Debug {
});
}
fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
func(None)
fn as_array(&self) -> Option<&dyn ReflectArray> {
None
}
fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
func(None)
fn as_array_mut(&mut self) -> Option<&mut dyn ReflectArray> {
None
}
fn as_list(&self, func: &mut dyn FnMut(Option<&dyn ReflectList>)) {
func(None)
fn as_list(&self) -> Option<&dyn ReflectList> {
None
}
fn as_list_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
func(None)
fn as_list_mut(&mut self) -> Option<&mut dyn ReflectList> {
None
}
fn as_inheritable_variable(
&self,
func: &mut dyn FnMut(Option<&dyn ReflectInheritableVariable>),
) {
func(None)
fn as_inheritable_variable(&self) -> Option<&dyn ReflectInheritableVariable> {
None
}
fn as_inheritable_variable_mut(
&mut self,
func: &mut dyn FnMut(Option<&mut dyn ReflectInheritableVariable>),
) {
func(None)
fn as_inheritable_variable_mut(&mut self) -> Option<&mut dyn ReflectInheritableVariable> {
None
}
fn as_hash_map(&self, func: &mut dyn FnMut(Option<&dyn ReflectHashMap>)) {
func(None)
fn as_hash_map(&self) -> Option<&dyn ReflectHashMap> {
None
}
fn as_hash_map_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHashMap>)) {
func(None)
fn as_hash_map_mut(&mut self) -> Option<&mut dyn ReflectHashMap> {
None
}
fn as_handle(&self, func: &mut dyn FnMut(Option<&dyn ReflectHandle>)) {
func(None)
fn as_handle(&self) -> Option<&dyn ReflectHandle> {
None
}
fn as_handle_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHandle>)) {
func(None)
fn as_handle_mut(&mut self) -> Option<&mut dyn ReflectHandle> {
None
}
}
@@ -443,16 +437,14 @@ impl dyn Reflect {
let mut done = false;
self.as_inheritable_variable(&mut |variable| {
if let Some(variable) = variable {
// Inner variable might also contain inheritable variables, so continue iterating.
variable
.inner_value_ref()
.enumerate_fields_recursively_internal(path, field_info, func, ignored_types);
if let Some(variable) = self.as_inheritable_variable() {
// Inner variable might also contain inheritable variables, so continue iterating.
variable
.inner_value_ref()
.enumerate_fields_recursively_internal(path, field_info, func, ignored_types);
done = true;
}
});
done = true;
}
if done {
return;
@@ -460,62 +452,58 @@ impl dyn Reflect {
func(path, field_info, self);
self.as_array(&mut |array| {
if let Some(array) = array {
for i in 0..array.reflect_len() {
if let Some(item) = array.reflect_index(i) {
let item_path = format!("{path}[{i}]");
if let Some(array) = self.as_array() {
for i in 0..array.reflect_len() {
if let Some(item) = array.reflect_index(i) {
let item_path = format!("{path}[{i}]");
item.enumerate_fields_recursively_internal(
&item_path,
field_info,
func,
ignored_types,
);
}
item.enumerate_fields_recursively_internal(
&item_path,
field_info,
func,
ignored_types,
);
}
done = true;
}
});
done = true;
}
if done {
return;
}
self.as_hash_map(&mut |hash_map| {
if let Some(hash_map) = hash_map {
for i in 0..hash_map.reflect_len() {
if let Some((key, value)) = hash_map.reflect_get_at(i) {
// TODO: Here we just using `Debug` impl to obtain string representation for keys. This is
// fine for most cases in the engine.
let mut key_str = format!("{key:?}");
if let Some(hash_map) = self.as_hash_map() {
for i in 0..hash_map.reflect_len() {
if let Some((key, value)) = hash_map.reflect_get_at(i) {
// TODO: Here we just using `Debug` impl to obtain string representation for keys. This is
// fine for most cases in the engine.
let mut key_str = format!("{key:?}");
let is_key_string = key.downcast_ref::<String>().is_some()
|| key.downcast_ref::<ImmutableString>().is_some();
let is_key_string = key.downcast_ref::<String>().is_some()
|| key.downcast_ref::<ImmutableString>().is_some();
if is_key_string {
// Strip quotes at the beginning and the end, because Debug impl for String adds
// quotes at the beginning and the end, but we want raw value.
// TODO: This is unreliable mechanism.
key_str.remove(0);
key_str.pop();
}
let item_path = format!("{path}[{key_str}]");
value.enumerate_fields_recursively_internal(
&item_path,
field_info,
func,
ignored_types,
);
if is_key_string {
// Strip quotes at the beginning and the end, because Debug impl for String adds
// quotes at the beginning and the end, but we want raw value.
// TODO: This is unreliable mechanism.
key_str.remove(0);
key_str.pop();
}
}
done = true;
let item_path = format!("{path}[{key_str}]");
value.enumerate_fields_recursively_internal(
&item_path,
field_info,
func,
ignored_types,
);
}
}
});
done = true;
}
if done {
return;
@@ -553,48 +541,42 @@ impl dyn Reflect {
let mut done = false;
self.as_inheritable_variable(&mut |variable| {
if let Some(variable) = variable {
// Inner variable might also contain inheritable variables, so continue iterating.
variable
.inner_value_ref()
.apply_recursively(func, ignored_types);
if let Some(variable) = self.as_inheritable_variable() {
// Inner variable might also contain inheritable variables, so continue iterating.
variable
.inner_value_ref()
.apply_recursively(func, ignored_types);
done = true;
}
});
done = true;
}
if done {
return;
}
self.as_array(&mut |array| {
if let Some(array) = array {
for i in 0..array.reflect_len() {
if let Some(item) = array.reflect_index(i) {
item.apply_recursively(func, ignored_types);
}
if let Some(array) = self.as_array() {
for i in 0..array.reflect_len() {
if let Some(item) = array.reflect_index(i) {
item.apply_recursively(func, ignored_types);
}
done = true;
}
});
done = true;
}
if done {
return;
}
self.as_hash_map(&mut |hash_map| {
if let Some(hash_map) = hash_map {
for i in 0..hash_map.reflect_len() {
if let Some(item) = hash_map.reflect_get_nth_value_ref(i) {
item.apply_recursively(func, ignored_types);
}
if let Some(hash_map) = self.as_hash_map() {
for i in 0..hash_map.reflect_len() {
if let Some(item) = hash_map.reflect_get_nth_value_ref(i) {
item.apply_recursively(func, ignored_types);
}
done = true;
}
});
done = true;
}
if done {
return;
@@ -619,48 +601,42 @@ impl dyn Reflect {
let mut done = false;
self.as_inheritable_variable_mut(&mut |variable| {
if let Some(variable) = variable {
// Inner variable might also contain inheritable variables, so continue iterating.
variable
.inner_value_mut()
.apply_recursively_mut(func, ignored_types);
if let Some(variable) = self.as_inheritable_variable_mut() {
// Inner variable might also contain inheritable variables, so continue iterating.
variable
.inner_value_mut()
.apply_recursively_mut(func, ignored_types);
done = true;
}
});
done = true;
}
if done {
return;
}
self.as_array_mut(&mut |array| {
if let Some(array) = array {
for i in 0..array.reflect_len() {
if let Some(item) = array.reflect_index_mut(i) {
item.apply_recursively_mut(func, ignored_types);
}
if let Some(array) = self.as_array_mut() {
for i in 0..array.reflect_len() {
if let Some(item) = array.reflect_index_mut(i) {
item.apply_recursively_mut(func, ignored_types);
}
done = true;
}
});
done = true;
}
if done {
return;
}
self.as_hash_map_mut(&mut |hash_map| {
if let Some(hash_map) = hash_map {
for i in 0..hash_map.reflect_len() {
if let Some(item) = hash_map.reflect_get_nth_value_mut(i) {
item.apply_recursively_mut(func, ignored_types);
}
if let Some(hash_map) = self.as_hash_map_mut() {
for i in 0..hash_map.reflect_len() {
if let Some(item) = hash_map.reflect_get_nth_value_mut(i) {
item.apply_recursively_mut(func, ignored_types);
}
done = true;
}
});
done = true;
}
if done {
return;
@@ -884,25 +860,21 @@ impl<'p> Component<'p> {
Self::Field(path) => reflect.find_field(path, &mut |field| {
func(field.ok_or(ReflectPathError::UnknownField { s: path }))
}),
Self::Index(path) => {
reflect.as_array(&mut |result| match result {
Some(array) => match path.parse::<usize>() {
Ok(index) => match array.reflect_index(index) {
None => func(Err(ReflectPathError::NoItemForIndex { s: path })),
Some(value) => func(Ok(value)),
},
Err(_) => func(Err(ReflectPathError::InvalidIndexSyntax { s: path })),
Self::Index(path) => match reflect.as_array() {
Some(array) => match path.parse::<usize>() {
Ok(index) => match array.reflect_index(index) {
None => func(Err(ReflectPathError::NoItemForIndex { s: path })),
Some(value) => func(Ok(value)),
},
None => reflect.as_hash_map(&mut |result| match result {
Some(hash_map) => {
try_fetch_by_str_path_ref(hash_map, path, &mut |result| {
func(result.ok_or(ReflectPathError::NoItemForIndex { s: path }))
})
}
None => func(Err(ReflectPathError::NotAnArray)),
Err(_) => func(Err(ReflectPathError::InvalidIndexSyntax { s: path })),
},
None => match reflect.as_hash_map() {
Some(hash_map) => try_fetch_by_str_path_ref(hash_map, path, &mut |result| {
func(result.ok_or(ReflectPathError::NoItemForIndex { s: path }))
}),
});
}
None => func(Err(ReflectPathError::NotAnArray)),
},
},
}
}
@@ -917,7 +889,7 @@ impl<'p> Component<'p> {
}),
Self::Index(path) => {
let mut succeeded = true;
reflect.as_array_mut(&mut |array| match array {
match reflect.as_array_mut() {
Some(list) => match path.parse::<usize>() {
Ok(index) => match list.reflect_index_mut(index) {
None => func(Err(ReflectPathError::NoItemForIndex { s: path })),
@@ -926,17 +898,17 @@ impl<'p> Component<'p> {
Err(_) => func(Err(ReflectPathError::InvalidIndexSyntax { s: path })),
},
None => succeeded = false,
});
}
if !succeeded {
reflect.as_hash_map_mut(&mut |result| match result {
match reflect.as_hash_map_mut() {
Some(hash_map) => {
try_fetch_by_str_path_mut(hash_map, path, &mut |result| {
func(result.ok_or(ReflectPathError::NoItemForIndex { s: path }))
})
}
None => func(Err(ReflectPathError::NotAnArray)),
})
}
}
}
}
+36 -55
View File
@@ -482,19 +482,13 @@ where
}
#[inline]
fn as_inheritable_variable(
&self,
func: &mut dyn FnMut(Option<&dyn ReflectInheritableVariable>),
) {
func(Some(self))
fn as_inheritable_variable(&self) -> Option<&dyn ReflectInheritableVariable> {
Some(self)
}
#[inline]
fn as_inheritable_variable_mut(
&mut self,
func: &mut dyn FnMut(Option<&mut dyn ReflectInheritableVariable>),
) {
func(Some(self))
fn as_inheritable_variable_mut(&mut self) -> Option<&mut dyn ReflectInheritableVariable> {
Some(self)
}
}
@@ -638,55 +632,44 @@ pub fn try_inherit_properties(
let mut result = None;
child.as_inheritable_variable_mut(&mut |inheritable_child| {
if let Some(inheritable_child) = inheritable_child {
parent.as_inheritable_variable(&mut |inheritable_parent| {
if let Some(inheritable_parent) = inheritable_parent {
if let Err(e) = inheritable_child.try_inherit(inheritable_parent, ignored_types)
{
result = Some(Err(e));
}
if let Some(inheritable_child) = child.as_inheritable_variable_mut() {
if let Some(inheritable_parent) = parent.as_inheritable_variable() {
if let Err(e) = inheritable_child.try_inherit(inheritable_parent, ignored_types) {
result = Some(Err(e));
}
if !matches!(result, Some(Err(_))) {
result = Some(try_inherit_properties(
inheritable_child.inner_value_mut(),
inheritable_parent.inner_value_ref(),
ignored_types,
));
}
}
})
if !matches!(result, Some(Err(_))) {
result = Some(try_inherit_properties(
inheritable_child.inner_value_mut(),
inheritable_parent.inner_value_ref(),
ignored_types,
));
}
}
});
}
if result.is_none() {
child.as_array_mut(&mut |child_collection| {
if let Some(child_collection) = child_collection {
parent.as_array(&mut |parent_collection| {
if let Some(parent_collection) = parent_collection {
if child_collection.reflect_len() == parent_collection.reflect_len() {
for i in 0..child_collection.reflect_len() {
// Sparse arrays (like Pool) could have empty entries.
if let (Some(child_item), Some(parent_item)) = (
child_collection.reflect_index_mut(i),
parent_collection.reflect_index(i),
) {
if let Err(e) = try_inherit_properties(
child_item,
parent_item,
ignored_types,
) {
result = Some(Err(e));
if let Some(child_collection) = child.as_array_mut() {
if let Some(parent_collection) = parent.as_array() {
if child_collection.reflect_len() == parent_collection.reflect_len() {
for i in 0..child_collection.reflect_len() {
// Sparse arrays (like Pool) could have empty entries.
if let (Some(child_item), Some(parent_item)) = (
child_collection.reflect_index_mut(i),
parent_collection.reflect_index(i),
) {
if let Err(e) =
try_inherit_properties(child_item, parent_item, ignored_types)
{
result = Some(Err(e));
break;
}
}
break;
}
}
}
})
}
}
})
}
}
if result.is_none() {
@@ -721,11 +704,9 @@ pub fn do_with_inheritable_variables<F>(
{
root.apply_recursively_mut(
&mut |object| {
object.as_inheritable_variable_mut(&mut |variable| {
if let Some(variable) = variable {
func(variable);
}
});
if let Some(variable) = object.as_inheritable_variable_mut() {
func(variable);
}
},
ignored_types,
)
+101 -120
View File
@@ -232,70 +232,62 @@ where
}
// Handle derived entities handles.
entity.as_handle_mut(&mut |handle| {
if let Some(handle) = handle {
if handle
.type_info_ref()
.derived_types
.contains(&TypeId::of::<N>())
&& handle.reflect_is_some()
&& !self.try_map_reflect(handle)
{
Log::warn(format!(
"Failed to remap handle {}:{} of node {}!",
handle.reflect_index(),
handle.reflect_generation(),
node_name
));
}
mapped = true;
if let Some(handle) = entity.as_handle_mut() {
if handle
.type_info_ref()
.derived_types
.contains(&TypeId::of::<N>())
&& handle.reflect_is_some()
&& !self.try_map_reflect(handle)
{
Log::warn(format!(
"Failed to remap handle {}:{} of node {}!",
handle.reflect_index(),
handle.reflect_generation(),
node_name
));
}
});
mapped = true;
}
if mapped {
return;
}
entity.as_inheritable_variable_mut(&mut |inheritable| {
if let Some(inheritable) = inheritable {
// In case of inheritable variable we must take inner value and do not mark variables as modified.
self.remap_handles_any(inheritable.inner_value_mut(), node_name, ignored_types);
if let Some(inheritable) = entity.as_inheritable_variable_mut() {
// In case of inheritable variable we must take inner value and do not mark variables as modified.
self.remap_handles_any(inheritable.inner_value_mut(), node_name, ignored_types);
mapped = true;
}
});
mapped = true;
}
if mapped {
return;
}
entity.as_array_mut(&mut |array| {
if let Some(array) = array {
// Look in every array item.
for i in 0..array.reflect_len() {
// Sparse arrays (like Pool) could have empty entries.
if let Some(item) = array.reflect_index_mut(i) {
self.remap_handles_any(item, node_name, ignored_types);
}
if let Some(array) = entity.as_array_mut() {
// Look in every array item.
for i in 0..array.reflect_len() {
// Sparse arrays (like Pool) could have empty entries.
if let Some(item) = array.reflect_index_mut(i) {
self.remap_handles_any(item, node_name, ignored_types);
}
mapped = true;
}
});
mapped = true;
}
if mapped {
return;
}
entity.as_hash_map_mut(&mut |hash_map| {
if let Some(hash_map) = hash_map {
for i in 0..hash_map.reflect_len() {
if let Some(item) = hash_map.reflect_get_nth_value_mut(i) {
self.remap_handles_any(item, node_name, ignored_types);
}
if let Some(hash_map) = entity.as_hash_map_mut() {
for i in 0..hash_map.reflect_len() {
if let Some(item) = hash_map.reflect_get_nth_value_mut(i) {
self.remap_handles_any(item, node_name, ignored_types);
}
mapped = true;
}
});
mapped = true;
}
if mapped {
return;
@@ -328,22 +320,20 @@ where
let mut mapped = false;
entity.as_inheritable_variable_mut(&mut |result| {
if let Some(inheritable) = result {
// In case of inheritable variable we must take inner value and do not mark variables as modified.
if !inheritable.is_modified() {
self.remap_inheritable_handles_internal(
inheritable.inner_value_mut(),
node_name,
// Raise mapping flag, any handle in inner value will be mapped. The flag is propagated
// to unlimited depth.
true,
ignored_types,
);
}
mapped = true;
if let Some(inheritable) = entity.as_inheritable_variable_mut() {
// In case of inheritable variable we must take inner value and do not mark variables as modified.
if !inheritable.is_modified() {
self.remap_inheritable_handles_internal(
inheritable.inner_value_mut(),
node_name,
// Raise mapping flag, any handle in inner value will be mapped. The flag is propagated
// to unlimited depth.
true,
ignored_types,
);
}
});
mapped = true;
}
if mapped {
return;
@@ -364,72 +354,66 @@ where
}
// Handle derived entities handles.
entity.as_handle_mut(&mut |handle| {
if let Some(handle) = handle {
if do_map
&& handle
.type_info_ref()
.derived_types
.contains(&TypeId::of::<N>())
&& handle.reflect_is_some()
&& !self.try_map_reflect(handle)
{
Log::warn(format!(
"Failed to remap handle {}:{} of node {}!",
handle.reflect_index(),
handle.reflect_generation(),
node_name
));
}
mapped = true;
if let Some(handle) = entity.as_handle_mut() {
if do_map
&& handle
.type_info_ref()
.derived_types
.contains(&TypeId::of::<N>())
&& handle.reflect_is_some()
&& !self.try_map_reflect(handle)
{
Log::warn(format!(
"Failed to remap handle {}:{} of node {}!",
handle.reflect_index(),
handle.reflect_generation(),
node_name
));
}
});
mapped = true;
}
if mapped {
return;
}
entity.as_array_mut(&mut |result| {
if let Some(array) = result {
// Look in every array item.
for i in 0..array.reflect_len() {
// Sparse arrays (like Pool) could have empty entries.
if let Some(item) = array.reflect_index_mut(i) {
self.remap_inheritable_handles_internal(
item,
node_name,
// Propagate mapping flag - it means that we're inside inheritable variable. In this
// case we will map handles.
do_map,
ignored_types,
);
}
if let Some(array) = entity.as_array_mut() {
// Look in every array item.
for i in 0..array.reflect_len() {
// Sparse arrays (like Pool) could have empty entries.
if let Some(item) = array.reflect_index_mut(i) {
self.remap_inheritable_handles_internal(
item,
node_name,
// Propagate mapping flag - it means that we're inside inheritable variable. In this
// case we will map handles.
do_map,
ignored_types,
);
}
mapped = true;
}
});
mapped = true;
}
if mapped {
return;
}
entity.as_hash_map_mut(&mut |result| {
if let Some(hash_map) = result {
for i in 0..hash_map.reflect_len() {
if let Some(item) = hash_map.reflect_get_nth_value_mut(i) {
self.remap_inheritable_handles_internal(
item,
node_name,
// Propagate mapping flag - it means that we're inside inheritable variable. In this
// case we will map handles.
do_map,
ignored_types,
);
}
if let Some(hash_map) = entity.as_hash_map_mut() {
for i in 0..hash_map.reflect_len() {
if let Some(item) = hash_map.reflect_get_nth_value_mut(i) {
self.remap_inheritable_handles_internal(
item,
node_name,
// Propagate mapping flag - it means that we're inside inheritable variable. In this
// case we will map handles.
do_map,
ignored_types,
);
}
mapped = true;
}
});
mapped = true;
}
if mapped {
return;
@@ -558,11 +542,11 @@ pub trait SceneGraphNode: Reflect + NameProvider + Clone {
parent
.inner_ref()
.resolve_path(path, &mut |result| match result {
Ok(parent_field) => parent_field.as_inheritable_variable(&mut |parent_field| {
if let Some(parent_inheritable) = parent_field {
Ok(parent_field) => {
if let Some(parent_inheritable) = parent_field.as_inheritable_variable() {
parent_value = Some(parent_inheritable.clone_value_box());
}
}),
}
Err(e) => Log::err(format!(
"Failed to resolve parent path {path}. Reason: {e:?}"
)),
@@ -574,13 +558,11 @@ pub trait SceneGraphNode: Reflect + NameProvider + Clone {
self.inner_mut()
.resolve_path_mut(path, &mut |result| match result {
Ok(child_field) => {
child_field.as_inheritable_variable_mut(&mut |child_inheritable| {
if let Some(child_inheritable) = child_inheritable {
need_revert = child_inheritable.is_modified();
} else {
Log::err(format!("Property {path} is not inheritable!"))
}
})
if let Some(child_inheritable) = child_field.as_inheritable_variable_mut() {
need_revert = child_inheritable.is_modified();
} else {
Log::err(format!("Property {path} is not inheritable!"))
}
}
Err(e) => Log::err(format!(
"Failed to resolve child path {path}. Reason: {e:?}"
@@ -1608,7 +1590,6 @@ mod test {
NameProvider,
};
use fyrox_resource::{untyped::UntypedResource, Resource, ResourceData};
use std::any::type_name;
use std::marker::PhantomData;
use std::{
any::{Any, TypeId},
+4 -5
View File
@@ -397,11 +397,10 @@ impl<'a, 'b> PluginContext<'a, 'b> {
&mut |object| {
let type_id = (*object).type_id();
if type_id != TypeId::of::<NodePool>() {
object.as_inheritable_variable_mut(&mut |variable| {
if let Some(variable) = variable {
variable.reset_modified_flag();
}
});
if let Some(variable) = object.as_inheritable_variable_mut()
{
variable.reset_modified_flag();
}
}
},
&[
+19 -25
View File
@@ -637,46 +637,40 @@ pub fn collect_used_resources(
return;
}
entity.as_array(&mut |array| {
if let Some(array) = array {
for i in 0..array.reflect_len() {
if let Some(item) = array.reflect_index(i) {
collect_used_resources(item, resources_collection)
}
if let Some(array) = entity.as_array() {
for i in 0..array.reflect_len() {
if let Some(item) = array.reflect_index(i) {
collect_used_resources(item, resources_collection)
}
finished = true;
}
});
finished = true;
}
if finished {
return;
}
entity.as_inheritable_variable(&mut |inheritable| {
if let Some(inheritable) = inheritable {
collect_used_resources(inheritable.inner_value_ref(), resources_collection);
if let Some(inheritable) = entity.as_inheritable_variable() {
collect_used_resources(inheritable.inner_value_ref(), resources_collection);
finished = true;
}
});
finished = true;
}
if finished {
return;
}
entity.as_hash_map(&mut |hash_map| {
if let Some(hash_map) = hash_map {
for i in 0..hash_map.reflect_len() {
if let Some((key, value)) = hash_map.reflect_get_at(i) {
collect_used_resources(key, resources_collection);
collect_used_resources(value, resources_collection);
}
if let Some(hash_map) = entity.as_hash_map() {
for i in 0..hash_map.reflect_len() {
if let Some((key, value)) = hash_map.reflect_get_at(i) {
collect_used_resources(key, resources_collection);
collect_used_resources(value, resources_collection);
}
finished = true;
}
});
finished = true;
}
if finished {
return;
+15 -19
View File
@@ -199,19 +199,17 @@ impl PropertyAction {
let mut value = Some(value);
target.resolve_path_mut(path, &mut |result| {
if let Ok(field) = result {
field.as_list_mut(&mut |result| {
if let Some(list) = result {
if let Err(value) = list.reflect_push(value.take().unwrap()) {
result_callback(Err(Self::AddItem { value }))
} else {
result_callback(Ok(None))
}
if let Some(list) = field.as_list_mut() {
if let Err(value) = list.reflect_push(value.take().unwrap()) {
result_callback(Err(Self::AddItem { value }))
} else {
result_callback(Err(Self::AddItem {
value: value.take().unwrap(),
}))
result_callback(Ok(None))
}
})
} else {
result_callback(Err(Self::AddItem {
value: value.take().unwrap(),
}))
}
} else {
result_callback(Err(Self::AddItem {
value: value.take().unwrap(),
@@ -221,17 +219,15 @@ impl PropertyAction {
}
PropertyAction::RemoveItem { index } => target.resolve_path_mut(path, &mut |result| {
if let Ok(field) = result {
field.as_list_mut(&mut |result| {
if let Some(list) = result {
if let Some(value) = list.reflect_remove(index) {
result_callback(Ok(Some(value)))
} else {
result_callback(Err(Self::RemoveItem { index }))
}
if let Some(list) = field.as_list_mut() {
if let Some(value) = list.reflect_remove(index) {
result_callback(Ok(Some(value)))
} else {
result_callback(Err(Self::RemoveItem { index }))
}
})
} else {
result_callback(Err(Self::RemoveItem { index }))
}
} else {
result_callback(Err(Self::RemoveItem { index }))
}