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