fyrox_core/
reflect.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! Runtime reflection
22
23mod external_impls;
24mod std_impls;
25
26pub use fyrox_core_derive::Reflect;
27use std::ops::Deref;
28use std::{
29    any::{Any, TypeId},
30    fmt::{self, Debug, Display, Formatter},
31    mem::ManuallyDrop,
32};
33
34pub mod prelude {
35    pub use super::{
36        FieldMetadata, FieldMut, FieldRef, FieldValue, Reflect, ReflectArray, ReflectHashMap,
37        ReflectInheritableVariable, ReflectList, ResolvePath, SetFieldByPathError, SetFieldError,
38    };
39}
40
41/// A value of a field..
42pub trait FieldValue: Any + 'static {
43    /// Casts `self` to a `&dyn Any`
44    fn field_value_as_any_ref(&self) -> &dyn Any;
45
46    /// Casts `self` to a `&mut dyn Any`
47    fn field_value_as_any_mut(&mut self) -> &mut dyn Any;
48
49    fn field_value_as_reflect(&self) -> &dyn Reflect;
50    fn field_value_as_reflect_mut(&mut self) -> &mut dyn Reflect;
51
52    fn type_name(&self) -> &'static str;
53}
54
55impl<T: Reflect> FieldValue for T {
56    fn field_value_as_any_ref(&self) -> &dyn Any {
57        self
58    }
59
60    fn field_value_as_any_mut(&mut self) -> &mut dyn Any {
61        self
62    }
63
64    fn field_value_as_reflect(&self) -> &dyn Reflect {
65        self
66    }
67
68    fn field_value_as_reflect_mut(&mut self) -> &mut dyn Reflect {
69        self
70    }
71
72    fn type_name(&self) -> &'static str {
73        std::any::type_name::<T>()
74    }
75}
76
77/// An error that can occur during "type casting"
78#[derive(Debug)]
79pub enum CastError {
80    /// Given type does not match expected.
81    TypeMismatch {
82        /// A name of the field.
83        property_name: String,
84
85        /// Expected type identifier.
86        expected_type_id: TypeId,
87
88        /// Actual type identifier.
89        actual_type_id: TypeId,
90    },
91}
92
93#[derive(Debug)]
94pub struct FieldMetadata<'s> {
95    /// A name of the property.
96    pub name: &'s str,
97
98    /// A human-readable name of the property.
99    pub display_name: &'s str,
100
101    /// Tag of the property. Could be used to group properties by a certain criteria or to find a
102    /// specific property by its tag.
103    pub tag: &'s str,
104
105    /// Doc comment content.
106    pub doc: &'s str,
107
108    /// A property is not meant to be edited.
109    pub read_only: bool,
110
111    /// Only for dynamic collections (Vec, etc) - means that its size cannot be changed, however the
112    /// _items_ of the collection can still be changed.
113    pub immutable_collection: bool,
114
115    /// A minimal value of the property. Works only with numeric properties!
116    pub min_value: Option<f64>,
117
118    /// A minimal value of the property. Works only with numeric properties!
119    pub max_value: Option<f64>,
120
121    /// A minimal value of the property. Works only with numeric properties!
122    pub step: Option<f64>,
123
124    /// Maximum amount of decimal places for a numeric property.
125    pub precision: Option<usize>,
126}
127
128pub struct FieldRef<'a, 'b> {
129    /// A reference to field's metadata.
130    pub metadata: &'a FieldMetadata<'b>,
131
132    /// An reference to the actual value of the property. This is "non-mangled" reference, which
133    /// means that while `field/fields/field_mut/fields_mut` might return a reference to other value,
134    /// than the actual field, the `value` is guaranteed to be a reference to the real value.
135    pub value: &'a dyn FieldValue,
136}
137
138impl<'b> Deref for FieldRef<'_, 'b> {
139    type Target = FieldMetadata<'b>;
140
141    fn deref(&self) -> &Self::Target {
142        self.metadata
143    }
144}
145
146impl FieldRef<'_, '_> {
147    /// Tries to cast a value to a given type.
148    pub fn cast_value<T: 'static>(&self) -> Result<&T, CastError> {
149        match self.value.field_value_as_any_ref().downcast_ref::<T>() {
150            Some(value) => Ok(value),
151            None => Err(CastError::TypeMismatch {
152                property_name: self.metadata.name.to_string(),
153                expected_type_id: TypeId::of::<T>(),
154                actual_type_id: self.value.type_id(),
155            }),
156        }
157    }
158}
159
160impl fmt::Debug for FieldRef<'_, '_> {
161    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162        f.debug_struct("FieldInfo")
163            .field("metadata", &self.metadata)
164            .field("value", &format_args!("{:?}", self.value as *const _))
165            .finish()
166    }
167}
168
169impl PartialEq<Self> for FieldRef<'_, '_> {
170    fn eq(&self, other: &Self) -> bool {
171        let value_ptr_a = self.value as *const _ as *const ();
172        let value_ptr_b = other.value as *const _ as *const ();
173
174        std::ptr::eq(value_ptr_a, value_ptr_b)
175    }
176}
177
178pub struct FieldMut<'a, 'b> {
179    /// A reference to field's metadata.
180    pub metadata: &'a FieldMetadata<'b>,
181
182    /// An reference to the actual value of the property. This is "non-mangled" reference, which
183    /// means that while `field/fields/field_mut/fields_mut` might return a reference to other value,
184    /// than the actual field, the `value` is guaranteed to be a reference to the real value.
185    pub value: &'a mut dyn FieldValue,
186}
187
188impl<'b> Deref for FieldMut<'_, 'b> {
189    type Target = FieldMetadata<'b>;
190
191    fn deref(&self) -> &Self::Target {
192        self.metadata
193    }
194}
195
196impl fmt::Debug for FieldMut<'_, '_> {
197    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198        f.debug_struct("FieldInfo")
199            .field("metadata", &self.metadata)
200            .field("value", &format_args!("{:?}", self.value as *const _))
201            .finish()
202    }
203}
204
205impl PartialEq<Self> for FieldMut<'_, '_> {
206    fn eq(&self, other: &Self) -> bool {
207        let value_ptr_a = self.value as *const _ as *const ();
208        let value_ptr_b = other.value as *const _ as *const ();
209
210        std::ptr::eq(value_ptr_a, value_ptr_b)
211    }
212}
213
214pub trait ReflectBase: Any + Debug {
215    fn as_any_raw(&self) -> &dyn Any;
216    fn as_any_raw_mut(&mut self) -> &mut dyn Any;
217}
218
219impl<T> ReflectBase for T
220where
221    T: Reflect,
222{
223    fn as_any_raw(&self) -> &dyn Any {
224        self
225    }
226
227    fn as_any_raw_mut(&mut self) -> &mut dyn Any {
228        self
229    }
230}
231
232/// A trait for runtime reflection.
233///
234/// ## Code Generation
235///
236/// The derive macro is available under `#[reflect(...)]` attribute that can be placed on both
237/// the type and its fields.
238///
239/// ### Type attributes
240///
241/// - `#[reflect(hide_all)]` - hide all fields from reflection.
242/// - `#[reflect(bounds)]` - add type boundary for `Reflect` impl, for example
243/// `#[reflect(bounds = "T: Reflect + Clone")]`
244/// - `#[reflect(non_cloneable)]` - prevent the macro from generating an implementation of
245/// [`Self::try_clone_box`] trait for your type. Could be useful for non-cloneable types.
246/// - `#[reflect(derived_type = "Type")]` - marks the type for which the attribute is added as a
247/// subtype for the `Type`.
248///
249/// ### Field attributes
250///
251/// - `#[reflect(hidden)]` - hides the field from reflection.
252/// - `#[reflect(setter = "foo")]` - set the desired method that will be used by [`Self::set_field`]
253/// default implementation.
254/// - `#[reflect(deref)]` - delegate the field access with `deref` + `deref_mut` calls. Could be
255/// useful for new-type objects.
256/// - `#[reflect(field = "foo")]` - sets the desired method, that will be used to access
257/// the field.
258/// - `#[reflect(field_mut = "foo")]` - sets the desired method, that will be used to access
259/// the field.
260/// - `#[reflect(name = "name")]` - overrides the name of the field.
261/// - `#[reflect(display_name = "name")]` - sets the human-readable name for the field.
262/// - `#[reflect(tag = "tag")]` - sets some arbitrary string tag of the field. It could be used to
263/// group properties by a certain criteria or to find a specific property by its tag.
264/// - `#[reflect(read_only)]` - the field is not meant to be editable. This flag does not prevent
265/// the reflection API from changing the actual value, it is just an instruction for external
266/// users (editors, tools, etc.)
267/// - `[#reflect(immutable_collection)]` - only for dynamic collections (`Vec`, etc.) - means that its
268/// size cannot be changed, however the _items_ of the collection can still be changed.
269/// - `#[reflect(min_value = "0.0")]` - minimal value of the field. Works only for numeric fields!
270/// - `#[reflect(max_value = "1.0")]` - maximal value of the field. Works only for numeric fields!
271/// - `#[reflect(step = "0.1")]` - increment/decrement step of the field. Works only for numeric fields!
272/// - `#[reflect(precision = "3")]` - maximum amount of decimal places for a numeric property.
273///
274/// ### Clone
275///
276/// By default, the proc macro adds an implementation of [`Self::try_clone_box`] with the assumption
277/// that your type implements the [`Clone`] trait. Not all types can implement this trait, in this
278/// case, add `#[reflect(non_cloneable)]` attribute for your type. This will force the implementation
279/// of [`Self::try_clone_box`] to return `None`.
280///
281/// ## Additional Trait Bounds
282///
283/// `Reflect` restricted to types that implement `Debug` trait, this is needed to convert the actual value
284/// to string. `Display` isn't used here, because it can't be derived and it is very tedious to implement it
285/// for every type that should support `Reflect` trait. It is a good compromise between development speed
286/// and the quality of the string output.
287pub trait Reflect: ReflectBase {
288    fn source_path() -> &'static str
289    where
290        Self: Sized;
291
292    fn derived_types() -> &'static [TypeId]
293    where
294        Self: Sized;
295
296    fn try_clone_box(&self) -> Option<Box<dyn Reflect>>;
297
298    fn query_derived_types(&self) -> &'static [TypeId];
299
300    fn type_name(&self) -> &'static str;
301
302    fn doc(&self) -> &'static str;
303
304    fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef]));
305
306    fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut]));
307
308    fn into_any(self: Box<Self>) -> Box<dyn Any>;
309
310    fn as_any(&self, func: &mut dyn FnMut(&dyn Any));
311
312    fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any));
313
314    fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect));
315
316    fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect));
317
318    fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>>;
319
320    /// Returns a parent assembly name of the type that implements this trait. **WARNING:** You should use
321    /// proc-macro (`#[derive(Reflect)]`) to ensure that this method will return correct assembly
322    /// name. In other words - there's no guarantee, that any implementation other than proc-macro
323    /// will return a correct name of the assembly. Alternatively, you can use `env!("CARGO_PKG_NAME")`
324    /// as an implementation.
325    fn assembly_name(&self) -> &'static str;
326
327    /// Returns a parent assembly name of the type that implements this trait. **WARNING:** You should use
328    /// proc-macro (`#[derive(Reflect)]`) to ensure that this method will return correct assembly
329    /// name. In other words - there's no guarantee, that any implementation other than proc-macro
330    /// will return a correct name of the assembly. Alternatively, you can use `env!("CARGO_PKG_NAME")`
331    /// as an implementation.
332    fn type_assembly_name() -> &'static str
333    where
334        Self: Sized;
335
336    /// Calls user method specified with `#[reflect(setter = ..)]` or falls back to
337    /// [`Reflect::field_mut`]
338    #[allow(clippy::type_complexity)]
339    fn set_field(
340        &mut self,
341        field_name: &str,
342        value: Box<dyn Reflect>,
343        func: &mut dyn FnMut(Result<Box<dyn Reflect>, SetFieldError>),
344    ) {
345        let mut opt_value = Some(value);
346        self.field_mut(field_name, &mut move |field| {
347            let value = opt_value.take().unwrap();
348            match field {
349                Some(f) => func(f.set(value).map_err(|value| SetFieldError::InvalidValue {
350                    field_type_name: f.type_name(),
351                    value,
352                })),
353                None => func(Err(SetFieldError::NoSuchField {
354                    name: field_name.to_string(),
355                    value,
356                })),
357            };
358        });
359    }
360
361    fn field(&self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
362        self.fields_ref(&mut |fields| {
363            func(
364                fields
365                    .iter()
366                    .find(|field| field.name == name)
367                    .map(|field| field.value.field_value_as_reflect()),
368            )
369        });
370    }
371
372    fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
373        self.fields_mut(&mut |fields| {
374            func(
375                fields
376                    .iter_mut()
377                    .find(|field| field.name == name)
378                    .map(|field| field.value.field_value_as_reflect_mut()),
379            )
380        });
381    }
382
383    fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
384        func(None)
385    }
386
387    fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
388        func(None)
389    }
390
391    fn as_list(&self, func: &mut dyn FnMut(Option<&dyn ReflectList>)) {
392        func(None)
393    }
394
395    fn as_list_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
396        func(None)
397    }
398
399    fn as_inheritable_variable(
400        &self,
401        func: &mut dyn FnMut(Option<&dyn ReflectInheritableVariable>),
402    ) {
403        func(None)
404    }
405
406    fn as_inheritable_variable_mut(
407        &mut self,
408        func: &mut dyn FnMut(Option<&mut dyn ReflectInheritableVariable>),
409    ) {
410        func(None)
411    }
412
413    fn as_hash_map(&self, func: &mut dyn FnMut(Option<&dyn ReflectHashMap>)) {
414        func(None)
415    }
416
417    fn as_hash_map_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHashMap>)) {
418        func(None)
419    }
420
421    fn as_handle(&self, func: &mut dyn FnMut(Option<&dyn ReflectHandle>)) {
422        func(None)
423    }
424
425    fn as_handle_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHandle>)) {
426        func(None)
427    }
428}
429
430pub trait ReflectHandle: Reflect {
431    fn reflect_inner_type_id(&self) -> TypeId;
432    fn reflect_inner_type_name(&self) -> &'static str;
433    fn reflect_is_some(&self) -> bool;
434    fn reflect_set_index(&mut self, index: u32);
435    fn reflect_index(&self) -> u32;
436    fn reflect_set_generation(&mut self, generation: u32);
437    fn reflect_generation(&self) -> u32;
438    fn reflect_as_erased(&self) -> ErasedHandle;
439}
440
441/// [`Reflect`] sub trait for working with slices.
442pub trait ReflectArray: Reflect {
443    fn reflect_index(&self, index: usize) -> Option<&dyn Reflect>;
444    fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
445    fn reflect_len(&self) -> usize;
446}
447
448/// [`Reflect`] sub trait for working with `Vec`-like types
449pub trait ReflectList: ReflectArray {
450    fn reflect_push(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
451    fn reflect_pop(&mut self) -> Option<Box<dyn Reflect>>;
452    fn reflect_remove(&mut self, index: usize) -> Option<Box<dyn Reflect>>;
453    fn reflect_insert(
454        &mut self,
455        index: usize,
456        value: Box<dyn Reflect>,
457    ) -> Result<(), Box<dyn Reflect>>;
458}
459
460pub trait ReflectHashMap: Reflect {
461    fn reflect_insert(
462        &mut self,
463        key: Box<dyn Reflect>,
464        value: Box<dyn Reflect>,
465    ) -> Option<Box<dyn Reflect>>;
466    fn reflect_len(&self) -> usize;
467    fn reflect_get(&self, key: &dyn Reflect, func: &mut dyn FnMut(Option<&dyn Reflect>));
468    fn reflect_get_mut(
469        &mut self,
470        key: &dyn Reflect,
471        func: &mut dyn FnMut(Option<&mut dyn Reflect>),
472    );
473    fn reflect_get_nth_value_ref(&self, index: usize) -> Option<&dyn Reflect>;
474    fn reflect_get_nth_value_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
475    fn reflect_get_at(&self, index: usize) -> Option<(&dyn Reflect, &dyn Reflect)>;
476    fn reflect_get_at_mut(&mut self, index: usize) -> Option<(&dyn Reflect, &mut dyn Reflect)>;
477    fn reflect_remove(&mut self, key: &dyn Reflect, func: &mut dyn FnMut(Option<Box<dyn Reflect>>));
478}
479
480pub trait ReflectInheritableVariable: Reflect {
481    /// Tries to inherit a value from parent. It will succeed only if the current variable is
482    /// not marked as modified.
483    fn try_inherit(
484        &mut self,
485        parent: &dyn ReflectInheritableVariable,
486        ignored_types: &[TypeId],
487    ) -> Result<Option<Box<dyn Reflect>>, InheritError>;
488
489    /// Resets modified flag from the variable.
490    fn reset_modified_flag(&mut self);
491
492    /// Returns current variable flags.
493    fn flags(&self) -> VariableFlags;
494
495    fn set_flags(&mut self, flags: VariableFlags);
496
497    /// Returns true if value was modified.
498    fn is_modified(&self) -> bool;
499
500    /// Returns true if value equals to other's value.
501    fn value_equals(&self, other: &dyn ReflectInheritableVariable) -> bool;
502
503    /// Clones self value.
504    fn clone_value_box(&self) -> Box<dyn Reflect>;
505
506    /// Marks value as modified, so its value won't be overwritten during property inheritance.
507    fn mark_modified(&mut self);
508
509    /// Returns a mutable reference to wrapped value without marking the variable itself as modified.
510    fn inner_value_mut(&mut self) -> &mut dyn Reflect;
511
512    /// Returns a shared reference to wrapped value without marking the variable itself as modified.
513    fn inner_value_ref(&self) -> &dyn Reflect;
514}
515
516/// An error returned from a failed path string query.
517#[derive(Debug, PartialEq, Eq)]
518pub enum ReflectPathError<'a> {
519    // syntax errors
520    UnclosedBrackets { s: &'a str },
521    InvalidIndexSyntax { s: &'a str },
522
523    // access errors
524    UnknownField { s: &'a str },
525    NoItemForIndex { s: &'a str },
526
527    // type cast errors
528    InvalidDowncast,
529    NotAnArray,
530}
531
532impl Display for ReflectPathError<'_> {
533    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
534        match self {
535            ReflectPathError::UnclosedBrackets { s } => {
536                write!(f, "unclosed brackets: `{s}`")
537            }
538            ReflectPathError::InvalidIndexSyntax { s } => {
539                write!(f, "not index syntax: `{s}`")
540            }
541            ReflectPathError::UnknownField { s } => {
542                write!(f, "given unknown field: `{s}`")
543            }
544            ReflectPathError::NoItemForIndex { s } => {
545                write!(f, "no item for index: `{s}`")
546            }
547            ReflectPathError::InvalidDowncast => {
548                write!(
549                    f,
550                    "failed to downcast to the target type after path resolution"
551                )
552            }
553            ReflectPathError::NotAnArray => {
554                write!(f, "tried to resolve index access, but the reflect type does not implement list API")
555            }
556        }
557    }
558}
559
560pub trait ResolvePath {
561    fn resolve_path<'p>(
562        &self,
563        path: &'p str,
564        func: &mut dyn FnMut(Result<&dyn Reflect, ReflectPathError<'p>>),
565    );
566
567    fn resolve_path_mut<'p>(
568        &mut self,
569        path: &'p str,
570        func: &mut dyn FnMut(Result<&mut dyn Reflect, ReflectPathError<'p>>),
571    );
572
573    fn get_resolve_path<'p, T: Reflect>(
574        &self,
575        path: &'p str,
576        func: &mut dyn FnMut(Result<&T, ReflectPathError<'p>>),
577    ) {
578        self.resolve_path(path, &mut |resolve_result| {
579            match resolve_result {
580                Ok(value) => {
581                    value.downcast_ref(&mut |result| {
582                        match result {
583                            Some(value) => {
584                                func(Ok(value));
585                            }
586                            None => {
587                                func(Err(ReflectPathError::InvalidDowncast));
588                            }
589                        };
590                    });
591                }
592                Err(err) => {
593                    func(Err(err));
594                }
595            };
596        })
597    }
598
599    fn get_resolve_path_mut<'p, T: Reflect>(
600        &mut self,
601        path: &'p str,
602        func: &mut dyn FnMut(Result<&mut T, ReflectPathError<'p>>),
603    ) {
604        self.resolve_path_mut(path, &mut |result| match result {
605            Ok(value) => value.downcast_mut(&mut |result| match result {
606                Some(value) => func(Ok(value)),
607                None => func(Err(ReflectPathError::InvalidDowncast)),
608            }),
609            Err(err) => func(Err(err)),
610        })
611    }
612}
613
614impl<T: Reflect> ResolvePath for T {
615    fn resolve_path<'p>(
616        &self,
617        path: &'p str,
618        func: &mut dyn FnMut(Result<&dyn Reflect, ReflectPathError<'p>>),
619    ) {
620        (self as &dyn Reflect).resolve_path(path, func)
621    }
622
623    fn resolve_path_mut<'p>(
624        &mut self,
625        path: &'p str,
626        func: &mut dyn FnMut(Result<&mut dyn Reflect, ReflectPathError<'p>>),
627    ) {
628        (self as &mut dyn Reflect).resolve_path_mut(path, func)
629    }
630}
631
632/// Splits property path into individual components.
633pub fn path_to_components(path: &str) -> Vec<Component> {
634    let mut components = Vec::new();
635    let mut current_path = path;
636    while let Ok((component, sub_path)) = Component::next(current_path) {
637        if let Component::Field(field) = component {
638            if field.is_empty() {
639                break;
640            }
641        }
642        current_path = sub_path;
643        components.push(component);
644    }
645    components
646}
647
648/// Helper methods over [`Reflect`] types
649pub trait GetField {
650    fn get_field<T: 'static>(&self, name: &str, func: &mut dyn FnMut(Option<&T>));
651
652    fn get_field_mut<T: 'static>(&mut self, _name: &str, func: &mut dyn FnMut(Option<&mut T>));
653}
654
655impl<R: Reflect> GetField for R {
656    fn get_field<T: 'static>(&self, name: &str, func: &mut dyn FnMut(Option<&T>)) {
657        self.field(name, &mut |field| match field {
658            None => func(None),
659            Some(reflect) => reflect.as_any(&mut |any| func(any.downcast_ref())),
660        })
661    }
662
663    fn get_field_mut<T: 'static>(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut T>)) {
664        self.field_mut(name, &mut |field| match field {
665            None => func(None),
666            Some(reflect) => reflect.as_any_mut(&mut |any| func(any.downcast_mut())),
667        })
668    }
669}
670
671// --------------------------------------------------------------------------------
672// impl dyn Trait
673// --------------------------------------------------------------------------------
674
675// SAFETY: String usage is safe in immutable contexts only. Calling `ManuallyDrop::drop`
676// (running strings destructor) on the returned value will cause crash!
677unsafe fn make_fake_string_from_slice(string: &str) -> ManuallyDrop<String> {
678    ManuallyDrop::new(String::from_utf8_unchecked(Vec::from_raw_parts(
679        string.as_bytes().as_ptr() as *mut _,
680        string.len(),
681        string.len(),
682    )))
683}
684
685fn try_fetch_by_str_path_ref(
686    hash_map: &dyn ReflectHashMap,
687    path: &str,
688    func: &mut dyn FnMut(Option<&dyn Reflect>),
689) {
690    // Create fake string here first, this is needed to avoid memory allocations..
691    // SAFETY: We won't drop the fake string or mutate it.
692    let fake_string_key = unsafe { make_fake_string_from_slice(path) };
693
694    hash_map.reflect_get(&*fake_string_key, &mut |result| match result {
695        Some(value) => func(Some(value)),
696        None => hash_map.reflect_get(&ImmutableString::new(path) as &dyn Reflect, func),
697    });
698}
699
700fn try_fetch_by_str_path_mut(
701    hash_map: &mut dyn ReflectHashMap,
702    path: &str,
703    func: &mut dyn FnMut(Option<&mut dyn Reflect>),
704) {
705    // Create fake string here first, this is needed to avoid memory allocations..
706    // SAFETY: We won't drop the fake string or mutate it.
707    let fake_string_key = unsafe { make_fake_string_from_slice(path) };
708
709    let mut succeeded = true;
710
711    hash_map.reflect_get_mut(&*fake_string_key, &mut |result| match result {
712        Some(value) => func(Some(value)),
713        None => succeeded = false,
714    });
715
716    if !succeeded {
717        hash_map.reflect_get_mut(&ImmutableString::new(path) as &dyn Reflect, func)
718    }
719}
720
721/// Simple path parser / reflect path component
722pub enum Component<'p> {
723    Field(&'p str),
724    Index(&'p str),
725}
726
727impl<'p> Component<'p> {
728    fn next(mut path: &'p str) -> Result<(Self, &'p str), ReflectPathError<'p>> {
729        // Discard the first comma:
730        if path.bytes().next() == Some(b'.') {
731            path = &path[1..];
732        }
733
734        let mut bytes = path.bytes().enumerate();
735        while let Some((i, b)) = bytes.next() {
736            if b == b'.' {
737                let (l, r) = path.split_at(i);
738                return Ok((Self::Field(l), &r[1..]));
739            }
740
741            if b == b'[' {
742                if i != 0 {
743                    // delimit the field access
744                    let (l, r) = path.split_at(i);
745                    return Ok((Self::Field(l), r));
746                }
747
748                // find ']'
749                if let Some((end, _)) = bytes.find(|(_, b)| *b == b']') {
750                    let l = &path[1..end];
751                    let r = &path[end + 1..];
752                    return Ok((Self::Index(l), r));
753                } else {
754                    return Err(ReflectPathError::UnclosedBrackets { s: path });
755                }
756            }
757        }
758
759        // NOTE: the `path` can be empty
760        Ok((Self::Field(path), ""))
761    }
762
763    fn resolve(
764        &self,
765        reflect: &dyn Reflect,
766        func: &mut dyn FnMut(Result<&dyn Reflect, ReflectPathError<'p>>),
767    ) {
768        match self {
769            Self::Field(path) => reflect.field(path, &mut |field| {
770                func(field.ok_or(ReflectPathError::UnknownField { s: path }))
771            }),
772            Self::Index(path) => {
773                reflect.as_array(&mut |result| match result {
774                    Some(array) => match path.parse::<usize>() {
775                        Ok(index) => match array.reflect_index(index) {
776                            None => func(Err(ReflectPathError::NoItemForIndex { s: path })),
777                            Some(value) => func(Ok(value)),
778                        },
779                        Err(_) => func(Err(ReflectPathError::InvalidIndexSyntax { s: path })),
780                    },
781                    None => reflect.as_hash_map(&mut |result| match result {
782                        Some(hash_map) => {
783                            try_fetch_by_str_path_ref(hash_map, path, &mut |result| {
784                                func(result.ok_or(ReflectPathError::NoItemForIndex { s: path }))
785                            })
786                        }
787                        None => func(Err(ReflectPathError::NotAnArray)),
788                    }),
789                });
790            }
791        }
792    }
793
794    fn resolve_mut(
795        &self,
796        reflect: &mut dyn Reflect,
797        func: &mut dyn FnMut(Result<&mut dyn Reflect, ReflectPathError<'p>>),
798    ) {
799        match self {
800            Self::Field(path) => reflect.field_mut(path, &mut |field| {
801                func(field.ok_or(ReflectPathError::UnknownField { s: path }))
802            }),
803            Self::Index(path) => {
804                let mut succeeded = true;
805                reflect.as_array_mut(&mut |array| match array {
806                    Some(list) => match path.parse::<usize>() {
807                        Ok(index) => match list.reflect_index_mut(index) {
808                            None => func(Err(ReflectPathError::NoItemForIndex { s: path })),
809                            Some(value) => func(Ok(value)),
810                        },
811                        Err(_) => func(Err(ReflectPathError::InvalidIndexSyntax { s: path })),
812                    },
813                    None => succeeded = false,
814                });
815
816                if !succeeded {
817                    reflect.as_hash_map_mut(&mut |result| match result {
818                        Some(hash_map) => {
819                            try_fetch_by_str_path_mut(hash_map, path, &mut |result| {
820                                func(result.ok_or(ReflectPathError::NoItemForIndex { s: path }))
821                            })
822                        }
823                        None => func(Err(ReflectPathError::NotAnArray)),
824                    })
825                }
826            }
827        }
828    }
829}
830
831impl ResolvePath for dyn Reflect {
832    fn resolve_path<'p>(
833        &self,
834        path: &'p str,
835        func: &mut dyn FnMut(Result<&dyn Reflect, ReflectPathError<'p>>),
836    ) {
837        match Component::next(path) {
838            Ok((component, r)) => component.resolve(self, &mut |result| match result {
839                Ok(child) => {
840                    if r.is_empty() {
841                        func(Ok(child))
842                    } else {
843                        child.resolve_path(r, func)
844                    }
845                }
846                Err(err) => func(Err(err)),
847            }),
848            Err(err) => func(Err(err)),
849        }
850    }
851
852    fn resolve_path_mut<'p>(
853        &mut self,
854        path: &'p str,
855        func: &mut dyn FnMut(Result<&mut dyn Reflect, ReflectPathError<'p>>),
856    ) {
857        match Component::next(path) {
858            Ok((component, r)) => component.resolve_mut(self, &mut |result| match result {
859                Ok(child) => {
860                    if r.is_empty() {
861                        func(Ok(child))
862                    } else {
863                        child.resolve_path_mut(r, func)
864                    }
865                }
866                Err(err) => func(Err(err)),
867            }),
868            Err(err) => func(Err(err)),
869        }
870    }
871}
872
873pub enum SetFieldError {
874    NoSuchField {
875        name: String,
876        value: Box<dyn Reflect>,
877    },
878    InvalidValue {
879        field_type_name: &'static str,
880        value: Box<dyn Reflect>,
881    },
882}
883
884pub enum SetFieldByPathError<'p> {
885    InvalidPath {
886        value: Box<dyn Reflect>,
887        reason: ReflectPathError<'p>,
888    },
889    InvalidValue {
890        field_type_name: &'static str,
891        value: Box<dyn Reflect>,
892    },
893    SetFieldError(SetFieldError),
894}
895
896/// Type-erased API
897impl dyn Reflect {
898    pub fn downcast<T: Reflect>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>> {
899        if self.is::<T>() {
900            Ok(self.into_any().downcast().unwrap())
901        } else {
902            Err(self)
903        }
904    }
905
906    pub fn take<T: Reflect>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>> {
907        self.downcast::<T>().map(|value| *value)
908    }
909
910    #[inline]
911    pub fn is<T: Reflect>(&self) -> bool {
912        self.type_id() == TypeId::of::<T>()
913    }
914
915    #[inline]
916    pub fn downcast_ref<T: Reflect>(&self, func: &mut dyn FnMut(Option<&T>)) {
917        self.as_any(&mut |any| func(any.downcast_ref::<T>()))
918    }
919
920    #[inline]
921    pub fn downcast_mut<T: Reflect>(&mut self, func: &mut dyn FnMut(Option<&mut T>)) {
922        self.as_any_mut(&mut |any| func(any.downcast_mut::<T>()))
923    }
924
925    /// Sets a field by its path in the given entity. This method always uses [`Reflect::set_field`] which means,
926    /// that it will always call custom property setters.
927    #[inline]
928    pub fn set_field_by_path<'p>(
929        &mut self,
930        path: &'p str,
931        value: Box<dyn Reflect>,
932        func: &mut dyn FnMut(Result<Box<dyn Reflect>, SetFieldByPathError<'p>>),
933    ) {
934        if let Some(separator_position) = path.rfind('.') {
935            let mut opt_value = Some(value);
936            let parent_path = &path[..separator_position];
937            let field = &path[(separator_position + 1)..];
938            self.resolve_path_mut(parent_path, &mut |result| match result {
939                Err(reason) => {
940                    func(Err(SetFieldByPathError::InvalidPath {
941                        reason,
942                        value: opt_value.take().unwrap(),
943                    }));
944                }
945                Ok(property) => {
946                    property.set_field(field, opt_value.take().unwrap(), &mut |result| match result
947                    {
948                        Ok(value) => func(Ok(value)),
949                        Err(err) => func(Err(SetFieldByPathError::SetFieldError(err))),
950                    })
951                }
952            });
953        } else {
954            self.set_field(path, value, &mut |result| match result {
955                Ok(value) => func(Ok(value)),
956                Err(err) => func(Err(SetFieldByPathError::SetFieldError(err))),
957            });
958        }
959    }
960
961    pub fn enumerate_fields_recursively<F>(&self, func: &mut F, ignored_types: &[TypeId])
962    where
963        F: FnMut(&str, Option<&FieldRef>, &dyn Reflect),
964    {
965        self.enumerate_fields_recursively_internal("", None, func, ignored_types)
966    }
967
968    fn enumerate_fields_recursively_internal<F>(
969        &self,
970        path: &str,
971        field_info: Option<&FieldRef>,
972        func: &mut F,
973        ignored_types: &[TypeId],
974    ) where
975        F: FnMut(&str, Option<&FieldRef>, &dyn Reflect),
976    {
977        if ignored_types.contains(&self.type_id()) {
978            return;
979        }
980
981        func(path, field_info, self);
982
983        let mut done = false;
984
985        self.as_inheritable_variable(&mut |variable| {
986            if let Some(variable) = variable {
987                // Inner variable might also contain inheritable variables, so continue iterating.
988                variable
989                    .inner_value_ref()
990                    .enumerate_fields_recursively_internal(path, field_info, func, ignored_types);
991
992                done = true;
993            }
994        });
995
996        if done {
997            return;
998        }
999
1000        self.as_array(&mut |array| {
1001            if let Some(array) = array {
1002                for i in 0..array.reflect_len() {
1003                    if let Some(item) = array.reflect_index(i) {
1004                        let item_path = format!("{path}[{i}]");
1005
1006                        item.enumerate_fields_recursively_internal(
1007                            &item_path,
1008                            field_info,
1009                            func,
1010                            ignored_types,
1011                        );
1012                    }
1013                }
1014
1015                done = true;
1016            }
1017        });
1018
1019        if done {
1020            return;
1021        }
1022
1023        self.as_hash_map(&mut |hash_map| {
1024            if let Some(hash_map) = hash_map {
1025                for i in 0..hash_map.reflect_len() {
1026                    if let Some((key, value)) = hash_map.reflect_get_at(i) {
1027                        // TODO: Here we just using `Debug` impl to obtain string representation for keys. This is
1028                        // fine for most cases in the engine.
1029                        let mut key_str = format!("{key:?}");
1030
1031                        let mut is_key_string = false;
1032                        key.downcast_ref::<String>(&mut |string| is_key_string |= string.is_some());
1033                        key.downcast_ref::<ImmutableString>(&mut |string| {
1034                            is_key_string |= string.is_some()
1035                        });
1036
1037                        if is_key_string {
1038                            // Strip quotes at the beginning and the end, because Debug impl for String adds
1039                            // quotes at the beginning and the end, but we want raw value.
1040                            // TODO: This is unreliable mechanism.
1041                            key_str.remove(0);
1042                            key_str.pop();
1043                        }
1044
1045                        let item_path = format!("{path}[{key_str}]");
1046
1047                        value.enumerate_fields_recursively_internal(
1048                            &item_path,
1049                            field_info,
1050                            func,
1051                            ignored_types,
1052                        );
1053                    }
1054                }
1055
1056                done = true;
1057            }
1058        });
1059
1060        if done {
1061            return;
1062        }
1063
1064        self.fields_ref(&mut |fields| {
1065            for field in fields {
1066                let compound_path;
1067                let field_path = if path.is_empty() {
1068                    field.metadata.name
1069                } else {
1070                    compound_path = format!("{}.{}", path, field.metadata.name);
1071                    &compound_path
1072                };
1073
1074                field
1075                    .value
1076                    .field_value_as_reflect()
1077                    .enumerate_fields_recursively_internal(
1078                        field_path,
1079                        Some(field),
1080                        func,
1081                        ignored_types,
1082                    );
1083            }
1084        })
1085    }
1086
1087    pub fn apply_recursively<F>(&self, func: &mut F, ignored_types: &[TypeId])
1088    where
1089        F: FnMut(&dyn Reflect),
1090    {
1091        if ignored_types.contains(&(*self).type_id()) {
1092            return;
1093        }
1094
1095        func(self);
1096
1097        let mut done = false;
1098
1099        self.as_inheritable_variable(&mut |variable| {
1100            if let Some(variable) = variable {
1101                // Inner variable might also contain inheritable variables, so continue iterating.
1102                variable
1103                    .inner_value_ref()
1104                    .apply_recursively(func, ignored_types);
1105
1106                done = true;
1107            }
1108        });
1109
1110        if done {
1111            return;
1112        }
1113
1114        self.as_array(&mut |array| {
1115            if let Some(array) = array {
1116                for i in 0..array.reflect_len() {
1117                    if let Some(item) = array.reflect_index(i) {
1118                        item.apply_recursively(func, ignored_types);
1119                    }
1120                }
1121
1122                done = true;
1123            }
1124        });
1125
1126        if done {
1127            return;
1128        }
1129
1130        self.as_hash_map(&mut |hash_map| {
1131            if let Some(hash_map) = hash_map {
1132                for i in 0..hash_map.reflect_len() {
1133                    if let Some(item) = hash_map.reflect_get_nth_value_ref(i) {
1134                        item.apply_recursively(func, ignored_types);
1135                    }
1136                }
1137
1138                done = true;
1139            }
1140        });
1141
1142        if done {
1143            return;
1144        }
1145
1146        self.fields_ref(&mut |fields| {
1147            for field_info_ref in fields {
1148                field_info_ref
1149                    .value
1150                    .field_value_as_reflect()
1151                    .apply_recursively(func, ignored_types);
1152            }
1153        })
1154    }
1155
1156    pub fn apply_recursively_mut<F>(&mut self, func: &mut F, ignored_types: &[TypeId])
1157    where
1158        F: FnMut(&mut dyn Reflect),
1159    {
1160        if ignored_types.contains(&(*self).type_id()) {
1161            return;
1162        }
1163
1164        func(self);
1165
1166        let mut done = false;
1167
1168        self.as_inheritable_variable_mut(&mut |variable| {
1169            if let Some(variable) = variable {
1170                // Inner variable might also contain inheritable variables, so continue iterating.
1171                variable
1172                    .inner_value_mut()
1173                    .apply_recursively_mut(func, ignored_types);
1174
1175                done = true;
1176            }
1177        });
1178
1179        if done {
1180            return;
1181        }
1182
1183        self.as_array_mut(&mut |array| {
1184            if let Some(array) = array {
1185                for i in 0..array.reflect_len() {
1186                    if let Some(item) = array.reflect_index_mut(i) {
1187                        item.apply_recursively_mut(func, ignored_types);
1188                    }
1189                }
1190
1191                done = true;
1192            }
1193        });
1194
1195        if done {
1196            return;
1197        }
1198
1199        self.as_hash_map_mut(&mut |hash_map| {
1200            if let Some(hash_map) = hash_map {
1201                for i in 0..hash_map.reflect_len() {
1202                    if let Some(item) = hash_map.reflect_get_nth_value_mut(i) {
1203                        item.apply_recursively_mut(func, ignored_types);
1204                    }
1205                }
1206
1207                done = true;
1208            }
1209        });
1210
1211        if done {
1212            return;
1213        }
1214
1215        self.fields_mut(&mut |fields| {
1216            for field_info_mut in fields {
1217                (*field_info_mut.value.field_value_as_reflect_mut())
1218                    .apply_recursively_mut(func, ignored_types);
1219            }
1220        })
1221    }
1222}
1223
1224pub fn is_path_to_array_element(path: &str) -> bool {
1225    path.ends_with(']')
1226}
1227
1228// Make it a trait?
1229impl dyn ReflectList {
1230    pub fn get_reflect_index<T: Reflect>(&self, index: usize, func: &mut dyn FnMut(Option<&T>)) {
1231        if let Some(reflect) = self.reflect_index(index) {
1232            reflect.downcast_ref(func)
1233        } else {
1234            func(None)
1235        }
1236    }
1237
1238    pub fn get_reflect_index_mut<T: Reflect>(
1239        &mut self,
1240        index: usize,
1241        func: &mut dyn FnMut(Option<&mut T>),
1242    ) {
1243        if let Some(reflect) = self.reflect_index_mut(index) {
1244            reflect.downcast_mut(func)
1245        } else {
1246            func(None)
1247        }
1248    }
1249}
1250
1251#[macro_export]
1252macro_rules! blank_reflect {
1253    () => {
1254        fn source_path() -> &'static str {
1255            file!()
1256        }
1257
1258        fn derived_types() -> &'static [std::any::TypeId]
1259        where
1260            Self: Sized,
1261        {
1262            &[]
1263        }
1264
1265        fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
1266            Some(Box::new(self.clone()))
1267        }
1268
1269        fn query_derived_types(&self) -> &'static [std::any::TypeId] {
1270            Self::derived_types()
1271        }
1272
1273        fn type_name(&self) -> &'static str {
1274            std::any::type_name::<Self>()
1275        }
1276
1277        fn doc(&self) -> &'static str {
1278            ""
1279        }
1280
1281        fn assembly_name(&self) -> &'static str {
1282            env!("CARGO_PKG_NAME")
1283        }
1284
1285        fn type_assembly_name() -> &'static str {
1286            env!("CARGO_PKG_NAME")
1287        }
1288
1289        fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
1290            func(&[])
1291        }
1292
1293        #[inline]
1294        fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut])) {
1295            func(&mut [])
1296        }
1297
1298        fn into_any(self: Box<Self>) -> Box<dyn Any> {
1299            self
1300        }
1301
1302        fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
1303            func(self)
1304        }
1305
1306        fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
1307            func(self)
1308        }
1309
1310        fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
1311            func(self)
1312        }
1313
1314        fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
1315            func(self)
1316        }
1317
1318        fn field(&self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
1319            func(if name == "self" { Some(self) } else { None })
1320        }
1321
1322        fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
1323            func(if name == "self" { Some(self) } else { None })
1324        }
1325
1326        fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
1327            let this = std::mem::replace(self, value.take()?);
1328            Ok(Box::new(this))
1329        }
1330    };
1331}
1332
1333#[macro_export]
1334macro_rules! delegate_reflect {
1335    () => {
1336        fn source_path() -> &'static str {
1337            file!()
1338        }
1339
1340        fn derived_types() -> &'static [std::any::TypeId] {
1341            // TODO
1342            &[]
1343        }
1344
1345        fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
1346            Some(Box::new(self.clone()))
1347        }
1348
1349        fn query_derived_types(&self) -> &'static [std::any::TypeId] {
1350            Self::derived_types()
1351        }
1352
1353        fn type_name(&self) -> &'static str {
1354            self.deref().type_name()
1355        }
1356
1357        fn doc(&self) -> &'static str {
1358            self.deref().doc()
1359        }
1360
1361        fn assembly_name(&self) -> &'static str {
1362            self.deref().assembly_name()
1363        }
1364
1365        fn type_assembly_name() -> &'static str {
1366            env!("CARGO_PKG_NAME")
1367        }
1368
1369        fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
1370            self.deref().fields_ref(func)
1371        }
1372
1373        fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut])) {
1374            self.deref_mut().fields_mut(func)
1375        }
1376
1377        fn into_any(self: Box<Self>) -> Box<dyn Any> {
1378            (*self).into_any()
1379        }
1380
1381        fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
1382            self.deref().as_any(func)
1383        }
1384
1385        fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
1386            self.deref_mut().as_any_mut(func)
1387        }
1388
1389        fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
1390            self.deref().as_reflect(func)
1391        }
1392
1393        fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
1394            self.deref_mut().as_reflect_mut(func)
1395        }
1396
1397        fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
1398            self.deref_mut().set(value)
1399        }
1400
1401        fn field(&self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
1402            self.deref().field(name, func)
1403        }
1404
1405        fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
1406            self.deref_mut().field_mut(name, func)
1407        }
1408
1409        fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
1410            self.deref().as_array(func)
1411        }
1412
1413        fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
1414            self.deref_mut().as_array_mut(func)
1415        }
1416
1417        fn as_list(&self, func: &mut dyn FnMut(Option<&dyn ReflectList>)) {
1418            self.deref().as_list(func)
1419        }
1420
1421        fn as_list_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
1422            self.deref_mut().as_list_mut(func)
1423        }
1424    };
1425}
1426
1427#[macro_export]
1428macro_rules! newtype_reflect {
1429    () => {
1430        fn type_name(&self) -> &'static str {
1431            self.0.type_name()
1432        }
1433
1434        fn doc(&self) -> &'static str {
1435            self.0.doc()
1436        }
1437
1438        fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
1439            self.0.fields_ref(func)
1440        }
1441
1442        fn into_any(self: Box<Self>) -> Box<dyn Any> {
1443            self
1444        }
1445
1446        fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
1447            self.0.as_any(func)
1448        }
1449
1450        fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
1451            self.0.as_any_mut(func)
1452        }
1453
1454        fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
1455            self.0.as_reflect(func)
1456        }
1457
1458        fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
1459            self.0.as_reflect_mut(func)
1460        }
1461
1462        fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
1463            self.0.set(value)
1464        }
1465
1466        fn field(&self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
1467            self.0.field(name, func)
1468        }
1469
1470        fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
1471            self.0.field_mut(name, func)
1472        }
1473
1474        fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
1475            self.0.as_array(func)
1476        }
1477
1478        fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
1479            self.0.as_array_mut(func)
1480        }
1481
1482        fn as_list(&self, func: &mut dyn FnMut(Option<&dyn ReflectList>)) {
1483            self.0.as_list(func)
1484        }
1485
1486        fn as_list_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
1487            self.0.as_list_mut(func)
1488        }
1489
1490        fn as_inheritable_variable(
1491            &self,
1492            func: &mut dyn FnMut(Option<&dyn ReflectInheritableVariable>),
1493        ) {
1494            self.0.as_inheritable_variable(func)
1495        }
1496
1497        fn as_inheritable_variable_mut(
1498            &mut self,
1499            func: &mut dyn FnMut(Option<&mut dyn ReflectInheritableVariable>),
1500        ) {
1501            self.0.as_inheritable_variable_mut(func)
1502        }
1503
1504        fn as_hash_map(&self, func: &mut dyn FnMut(Option<&dyn ReflectHashMap>)) {
1505            self.0.as_hash_map(func)
1506        }
1507
1508        fn as_hash_map_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHashMap>)) {
1509            self.0.as_hash_map_mut(func)
1510        }
1511    };
1512}
1513
1514use crate::pool::ErasedHandle;
1515use crate::sstorage::ImmutableString;
1516use crate::variable::{InheritError, VariableFlags};
1517pub use blank_reflect;
1518pub use delegate_reflect;
1519
1520#[cfg(test)]
1521mod test {
1522    use super::prelude::*;
1523    use std::any::TypeId;
1524    use std::collections::HashMap;
1525
1526    #[derive(Reflect, Clone, Default, Debug)]
1527    struct Foo {
1528        bar: Bar,
1529        baz: f32,
1530        collection: Vec<Item>,
1531        hash_map: HashMap<String, Item>,
1532    }
1533
1534    #[derive(Reflect, Clone, Default, Debug)]
1535    struct Item {
1536        payload: u32,
1537    }
1538
1539    #[derive(Reflect, Clone, Default, Debug)]
1540    struct Bar {
1541        stuff: String,
1542    }
1543
1544    #[test]
1545    fn enumerate_fields_recursively() {
1546        let foo = Foo {
1547            bar: Default::default(),
1548            baz: 0.0,
1549            collection: vec![Item::default()],
1550            hash_map: [("Foobar".to_string(), Item::default())].into(),
1551        };
1552
1553        let mut names = Vec::new();
1554        (&foo as &dyn Reflect).enumerate_fields_recursively(
1555            &mut |path, _, _| {
1556                names.push(path.to_string());
1557            },
1558            &[],
1559        );
1560
1561        assert_eq!(names[0], "");
1562        assert_eq!(names[1], "bar");
1563        assert_eq!(names[2], "bar.stuff");
1564        assert_eq!(names[3], "baz");
1565        assert_eq!(names[4], "collection");
1566        assert_eq!(names[5], "collection[0]");
1567        assert_eq!(names[6], "collection[0].payload");
1568        assert_eq!(names[7], "hash_map");
1569        assert_eq!(names[8], "hash_map[Foobar]");
1570        assert_eq!(names[9], "hash_map[Foobar].payload");
1571    }
1572
1573    #[derive(Reflect, Clone, Debug)]
1574    #[reflect(derived_type = "Derived")]
1575    struct Base;
1576
1577    #[allow(dead_code)]
1578    struct Derived(Box<Base>);
1579
1580    #[test]
1581    fn test_derived() {
1582        let base = Base;
1583        assert_eq!(base.query_derived_types(), &[TypeId::of::<Derived>()])
1584    }
1585}