1mod 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
40pub trait FieldValue: Any + 'static {
42 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#[derive(Debug)]
54pub enum CastError {
55 TypeMismatch {
57 property_name: String,
59
60 expected_type_id: TypeId,
62
63 actual_type_id: TypeId,
65 },
66}
67
68pub struct FieldInfo<'a, 'b> {
69 pub owner_type_id: TypeId,
71
72 pub name: &'b str,
74
75 pub display_name: &'b str,
77
78 pub description: &'b str,
80
81 pub tag: &'b str,
84
85 pub type_name: &'b str,
87
88 pub doc: &'b str,
90
91 pub value: &'a dyn FieldValue,
95
96 pub reflect_value: &'a dyn Reflect,
98
99 pub read_only: bool,
101
102 pub immutable_collection: bool,
105
106 pub min_value: Option<f64>,
108
109 pub max_value: Option<f64>,
111
112 pub step: Option<f64>,
114
115 pub precision: Option<usize>,
117}
118
119impl FieldInfo<'_, '_> {
120 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
183pub 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 fn assembly_name(&self) -> &'static str;
231
232 fn type_assembly_name() -> &'static str
238 where
239 Self: Sized;
240
241 #[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
323pub 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
330pub 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 fn try_inherit(
366 &mut self,
367 parent: &dyn ReflectInheritableVariable,
368 ignored_types: &[TypeId],
369 ) -> Result<Option<Box<dyn Reflect>>, InheritError>;
370
371 fn reset_modified_flag(&mut self);
373
374 fn flags(&self) -> VariableFlags;
376
377 fn set_flags(&mut self, flags: VariableFlags);
378
379 fn is_modified(&self) -> bool;
381
382 fn value_equals(&self, other: &dyn ReflectInheritableVariable) -> bool;
384
385 fn clone_value_box(&self) -> Box<dyn Reflect>;
387
388 fn mark_modified(&mut self);
390
391 fn inner_value_mut(&mut self) -> &mut dyn Reflect;
393
394 fn inner_value_ref(&self) -> &dyn Reflect;
396}
397
398#[derive(Debug, PartialEq, Eq)]
400pub enum ReflectPathError<'a> {
401 UnclosedBrackets { s: &'a str },
403 InvalidIndexSyntax { s: &'a str },
404
405 UnknownField { s: &'a str },
407 NoItemForIndex { s: &'a str },
408
409 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
514pub 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
530pub 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
553unsafe 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 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 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
603pub 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 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 let (l, r) = path.split_at(i);
627 return Ok((Self::Field(l), r));
628 }
629
630 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 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
763impl 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 #[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 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 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 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 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 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
1088impl 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}