Skip to main content

bevy_reflect/
type_registry.rs

1use crate::{
2    convert::ReflectConvert, serde::Serializable, FromReflect, Reflect, TypeData, TypeInfo,
3    TypePath, Typed,
4};
5use alloc::{boxed::Box, string::String};
6use bevy_platform::{
7    collections::{HashMap, HashSet},
8    sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard},
9};
10use bevy_ptr::{Ptr, PtrMut};
11use bevy_reflect::CreateTypeData;
12use bevy_utils::TypeIdHashMap;
13use core::{
14    any::{Any, TypeId},
15    fmt::Debug,
16    ops::{Deref, DerefMut},
17};
18use serde::{Deserialize, Serialize};
19
20/// A registry of [reflected] types.
21///
22/// This struct is used as the central store for type information.
23/// [Registering] a type will generate a new [`TypeRegistration`] entry in this store
24/// using a type's [`GetTypeRegistration`] implementation
25/// (which is automatically implemented when using [`#[derive(Reflect)]`](derive@crate::Reflect)).
26///
27/// See the [crate-level documentation] for more information.
28///
29/// [reflected]: crate
30/// [Registering]: TypeRegistry::register
31/// [crate-level documentation]: crate
32pub struct TypeRegistry {
33    registrations: TypeIdHashMap<TypeRegistration>,
34    short_path_to_id: HashMap<&'static str, TypeId>,
35    type_path_to_id: HashMap<&'static str, TypeId>,
36    ambiguous_names: HashSet<&'static str>,
37}
38
39// TODO:  remove this wrapper once we migrate to Atelier Assets and the Scene AssetLoader doesn't
40// need a TypeRegistry ref
41/// A synchronized wrapper around a [`TypeRegistry`].
42#[derive(Clone, Default)]
43pub struct TypeRegistryArc {
44    /// The wrapped [`TypeRegistry`].
45    pub internal: Arc<RwLock<TypeRegistry>>,
46}
47
48impl Debug for TypeRegistryArc {
49    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
50        self.internal
51            .read()
52            .unwrap_or_else(PoisonError::into_inner)
53            .type_path_to_id
54            .keys()
55            .fmt(f)
56    }
57}
58
59/// A trait which allows a type to generate its [`TypeRegistration`]
60/// for registration into the [`TypeRegistry`].
61///
62/// This trait is automatically implemented for items using [`#[derive(Reflect)]`](derive@crate::Reflect).
63/// The macro also allows [`TypeData`] to be more easily registered.
64///
65/// If you need to use this trait as a generic bound along with other reflection traits,
66/// for your convenience, consider using [`Reflectable`] instead.
67///
68/// See the [crate-level documentation] for more information on type registration.
69///
70/// [`Reflectable`]: crate::Reflectable
71/// [crate-level documentation]: crate
72#[diagnostic::on_unimplemented(
73    message = "`{Self}` does not implement `GetTypeRegistration` so cannot provide type registration information",
74    note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
75)]
76pub trait GetTypeRegistration: 'static {
77    /// Returns the default [`TypeRegistration`] for this type.
78    fn get_type_registration() -> TypeRegistration;
79    /// Registers other types needed by this type.
80    ///
81    /// This method is called by [`TypeRegistry::register`] to register any other required types.
82    /// Often, this is done for fields of structs and enum variants to ensure all types are properly registered.
83    fn register_type_dependencies(_registry: &mut TypeRegistry) {}
84}
85
86impl Default for TypeRegistry {
87    fn default() -> Self {
88        Self::new()
89    }
90}
91
92impl TypeRegistry {
93    /// Create a type registry with *no* registered types.
94    pub fn empty() -> Self {
95        Self {
96            registrations: Default::default(),
97            short_path_to_id: Default::default(),
98            type_path_to_id: Default::default(),
99            ambiguous_names: Default::default(),
100        }
101    }
102
103    /// Create a type registry with default registrations for primitive types.
104    pub fn new() -> Self {
105        let mut registry = Self::empty();
106        registry.register::<()>();
107        registry.register::<bool>();
108        registry.register::<char>();
109        registry.register::<u8>();
110        registry.register::<u16>();
111        registry.register::<u32>();
112        registry.register::<u64>();
113        registry.register::<u128>();
114        registry.register::<usize>();
115        registry.register::<i8>();
116        registry.register::<i16>();
117        registry.register::<i32>();
118        registry.register::<i64>();
119        registry.register::<i128>();
120        registry.register::<isize>();
121        registry.register::<f32>();
122        registry.register::<f64>();
123        registry.register::<String>();
124        registry
125    }
126
127    /// Register all non-generic types annotated with `#[derive(Reflect)]`.
128    ///
129    /// Calling this method is equivalent to calling [`register`](Self::register) on all types without generic parameters
130    /// that derived [`Reflect`] trait.
131    ///
132    /// This method is supported on Linux, macOS, Windows, iOS, Android, and Web via the `inventory` crate.
133    /// It does nothing on platforms not supported by either of those crates.
134    ///
135    /// # Example
136    ///
137    /// ```
138    /// # use std::any::TypeId;
139    /// # use bevy_reflect::{Reflect, TypeRegistry, std_traits::ReflectDefault};
140    /// #[derive(Reflect, Default)]
141    /// #[reflect(Default)]
142    /// struct Foo {
143    ///   name: Option<String>,
144    ///   value: i32
145    /// }
146    ///
147    /// let mut type_registry = TypeRegistry::empty();
148    /// type_registry.register_derived_types();
149    ///
150    /// // The main type
151    /// assert!(type_registry.contains(TypeId::of::<Foo>()));
152    ///
153    /// // Its type dependencies
154    /// assert!(type_registry.contains(TypeId::of::<Option<String>>()));
155    /// assert!(type_registry.contains(TypeId::of::<i32>()));
156    ///
157    /// // Its type data
158    /// assert!(type_registry.get_type_data::<ReflectDefault>(TypeId::of::<Foo>()).is_some());
159    /// ```
160    #[cfg(feature = "auto_register")]
161    pub fn register_derived_types(&mut self) {
162        crate::__macro_exports::auto_register::register_types(self);
163    }
164
165    /// Attempts to register the type `T` if it has not yet been registered already.
166    ///
167    /// This will also recursively register any type dependencies as specified by [`GetTypeRegistration::register_type_dependencies`].
168    /// When deriving `Reflect`, this will generally be all the fields of the struct or enum variant.
169    /// As with any type registration, these type dependencies will not be registered more than once.
170    ///
171    /// If the registration for type `T` already exists, it will not be registered again and neither will its type dependencies.
172    /// To register the type, overwriting any existing registration, use [register](Self::overwrite_registration) instead.
173    ///
174    /// Additionally, this will add any reflect [type data](TypeData) as specified in the [`Reflect`] derive.
175    ///
176    /// # Example
177    ///
178    /// ```
179    /// # use core::any::TypeId;
180    /// # use bevy_reflect::{Reflect, TypeRegistry, std_traits::ReflectDefault};
181    /// #[derive(Reflect, Default)]
182    /// #[reflect(Default)]
183    /// struct Foo {
184    ///   name: Option<String>,
185    ///   value: i32
186    /// }
187    ///
188    /// let mut type_registry = TypeRegistry::default();
189    ///
190    /// type_registry.register::<Foo>();
191    ///
192    /// // The main type
193    /// assert!(type_registry.contains(TypeId::of::<Foo>()));
194    ///
195    /// // Its type dependencies
196    /// assert!(type_registry.contains(TypeId::of::<Option<String>>()));
197    /// assert!(type_registry.contains(TypeId::of::<i32>()));
198    ///
199    /// // Its type data
200    /// assert!(type_registry.get_type_data::<ReflectDefault>(TypeId::of::<Foo>()).is_some());
201    /// ```
202    pub fn register<T>(&mut self)
203    where
204        T: GetTypeRegistration,
205    {
206        if self.register_internal(TypeId::of::<T>(), T::get_type_registration) {
207            T::register_type_dependencies(self);
208        }
209    }
210
211    /// Attempts to register the referenced type `T` if it has not yet been registered.
212    ///
213    /// See [`register`] for more details.
214    ///
215    /// # Example
216    ///
217    /// ```
218    /// # use bevy_reflect::{Reflect, TypeRegistry};
219    /// # use core::any::TypeId;
220    /// #
221    /// # let mut type_registry = TypeRegistry::default();
222    /// #
223    /// #[derive(Reflect)]
224    /// struct Foo {
225    ///   bar: Bar,
226    /// }
227    ///
228    /// #[derive(Reflect)]
229    /// struct Bar;
230    ///
231    /// let foo = Foo { bar: Bar };
232    ///
233    /// // Equivalent to `type_registry.register::<Foo>()`
234    /// type_registry.register_by_val(&foo);
235    ///
236    /// assert!(type_registry.contains(TypeId::of::<Foo>()));
237    /// assert!(type_registry.contains(TypeId::of::<Bar>()));
238    /// ```
239    ///
240    /// [`register`]: Self::register
241    pub fn register_by_val<T>(&mut self, _: &T)
242    where
243        T: GetTypeRegistration,
244    {
245        self.register::<T>();
246    }
247
248    /// Attempts to register the type described by `registration`.
249    ///
250    /// If the registration for the type already exists, it will not be registered again.
251    ///
252    /// To forcibly register the type, overwriting any existing registration, use the
253    /// [`overwrite_registration`](Self::overwrite_registration) method instead.
254    ///
255    /// This method will _not_ register type dependencies.
256    /// Use [`register`](Self::register) to register a type with its dependencies.
257    ///
258    /// Returns `true` if the registration was added and `false` if it already exists.
259    pub fn add_registration(&mut self, registration: TypeRegistration) -> bool {
260        let type_id = registration.type_id();
261        self.register_internal(type_id, || registration)
262    }
263
264    /// Registers the type described by `registration`.
265    ///
266    /// If the registration for the type already exists, it will be overwritten.
267    ///
268    /// To avoid overwriting existing registrations, it's recommended to use the
269    /// [`register`](Self::register) or [`add_registration`](Self::add_registration) methods instead.
270    ///
271    /// This method will _not_ register type dependencies.
272    /// Use [`register`](Self::register) to register a type with its dependencies.
273    pub fn overwrite_registration(&mut self, registration: TypeRegistration) {
274        Self::update_registration_indices(
275            &registration,
276            &mut self.short_path_to_id,
277            &mut self.type_path_to_id,
278            &mut self.ambiguous_names,
279        );
280        self.registrations
281            .insert(registration.type_id(), registration);
282    }
283
284    /// Internal method to register a type with a given [`TypeId`] and [`TypeRegistration`].
285    ///
286    /// By using this method, we are able to reduce the number of `TypeId` hashes and lookups needed
287    /// to register a type.
288    ///
289    /// This method is internal to prevent users from accidentally registering a type with a `TypeId`
290    /// that does not match the type in the `TypeRegistration`.
291    fn register_internal(
292        &mut self,
293        type_id: TypeId,
294        get_registration: impl FnOnce() -> TypeRegistration,
295    ) -> bool {
296        if self.registrations.contains_key(&type_id) {
297            return false;
298        }
299        let registration = get_registration();
300        Self::update_registration_indices(
301            &registration,
302            &mut self.short_path_to_id,
303            &mut self.type_path_to_id,
304            &mut self.ambiguous_names,
305        );
306        self.registrations.insert(type_id, registration);
307        true
308    }
309
310    /// Internal method to register additional lookups for a given [`TypeRegistration`].
311    fn update_registration_indices(
312        registration: &TypeRegistration,
313        short_path_to_id: &mut HashMap<&'static str, TypeId>,
314        type_path_to_id: &mut HashMap<&'static str, TypeId>,
315        ambiguous_names: &mut HashSet<&'static str>,
316    ) {
317        let short_name = registration.type_info().type_path_table().short_path();
318        if short_path_to_id.contains_key(short_name) || ambiguous_names.contains(short_name) {
319            // name is ambiguous. fall back to long names for all ambiguous types
320            short_path_to_id.remove(short_name);
321            ambiguous_names.insert(short_name);
322        } else {
323            short_path_to_id.insert(short_name, registration.type_id());
324        }
325        type_path_to_id.insert(registration.type_info().type_path(), registration.type_id());
326    }
327
328    /// Registers the type data `D` for type `T`.
329    ///
330    /// Most of the time [`TypeRegistry::register`] can be used instead to register a type you derived [`Reflect`] for.
331    /// However, in cases where you want to add a piece of type data that was not included in the list of `#[reflect(...)]` type data in the derive,
332    /// or where the type is generic and cannot register the type data unconditionally without knowing the specific type parameters,
333    /// this method can be used to insert additional type data.
334    ///
335    /// # Example
336    /// ```
337    /// use bevy_reflect::{TypeRegistry, ReflectSerialize, ReflectDeserialize};
338    ///
339    /// let mut type_registry = TypeRegistry::default();
340    /// type_registry.register::<Option<String>>();
341    /// type_registry.register_type_data::<Option<String>, ReflectSerialize>();
342    /// type_registry.register_type_data::<Option<String>, ReflectDeserialize>();
343    /// ```
344    pub fn register_type_data<T: Reflect + TypePath, D: CreateTypeData<T>>(&mut self) {
345        let data = self.get_mut(TypeId::of::<T>()).unwrap_or_else(|| {
346            panic!(
347                "attempted to call `TypeRegistry::register_type_data` for type `{T}` with data `{D}` without registering `{T}` first",
348                T = T::type_path(),
349                D = core::any::type_name::<D>(),
350            )
351        });
352        data.insert(D::create_type_data(()));
353    }
354
355    /// Registers the type data `D` with parameter `P` for type `T`.
356    ///
357    /// Most of the time [`TypeRegistry::register`] can be used instead to register a type you derived [`Reflect`] for.
358    /// However, in cases where you want to add a piece of type data that was not included in the list of `#[reflect(...)]` type data in the derive,
359    /// or where the type is generic and cannot register the type data unconditionally without knowing the specific type parameters,
360    /// this method can be used to insert additional type data.
361    ///
362    /// If no parameters are needed for the type data or the type data does not accept parameters,
363    /// then [`TypeRegistry::register_type_data`] may be used instead.
364    pub fn register_type_data_with<T: Reflect + TypePath, D: CreateTypeData<T, P>, P>(
365        &mut self,
366        params: P,
367    ) {
368        let data = self.get_mut(TypeId::of::<T>()).unwrap_or_else(|| {
369            panic!(
370                "attempted to call `TypeRegistry::register_type_data_with` for type `{T}` with data `{D}` and params `{P}` without registering `{T}` first",
371                T = T::type_path(),
372                D = ::core::any::type_name::<D>(),
373                P = ::core::any::type_name::<P>(),
374            )
375        });
376        data.insert(D::create_type_data(params));
377    }
378
379    /// Registers a fallible conversion from type T to U with the reflection
380    /// system.
381    ///
382    /// The supplied closure is expected to produce a value of type U, given an
383    /// instance of type T. If the conversion fails, the closure should return
384    /// the input value, wrapped in an `Err` variant.
385    ///
386    /// # Example
387    /// ```
388    /// # use bevy_reflect::TypeRegistry;
389    ///
390    /// let mut type_registry = TypeRegistry::default();
391    /// type_registry.register::<i32>();
392    /// type_registry.register::<String>();
393    /// type_registry.register_type_conversion::<i32, String, _>(|n| Ok(n.to_string()));
394    /// ```
395    pub fn register_type_conversion<T, U, F>(&mut self, function: F)
396    where
397        T: Reflect + TypePath,
398        U: Reflect + TypePath,
399        F: Fn(T) -> Result<U, T> + Clone + Send + Sync + 'static,
400    {
401        let data = self.get_mut(TypeId::of::<U>()).unwrap_or_else(|| {
402            panic!(
403                "attempted to call `TypeRegistry::register_type_conversion` for type `{U}` without registering `{U}` first",
404                U = U::type_path(),
405            )
406        });
407        data.get_or_insert_data_with(ReflectConvert::default)
408            .register_type_conversion(function);
409    }
410
411    /// Given types T and U, where `U: From<T>`, registers that conversion with
412    /// the reflection system.
413    ///
414    /// # Example
415    /// ```
416    /// # use bevy_reflect::TypeRegistry;
417    ///
418    /// let mut type_registry = TypeRegistry::default();
419    /// type_registry.register::<u8>();
420    /// type_registry.register::<u32>();
421    /// type_registry.register_type_conversion::<u8, u32, _>(|n| Ok(n.into()));
422    /// ```
423    pub fn register_into_type_conversion<T, U>(&mut self)
424    where
425        T: Reflect + TypePath,
426        U: Reflect + TypePath + From<T>,
427    {
428        let data = self.get_mut(TypeId::of::<U>()).unwrap_or_else(|| {
429            panic!(
430                "attempted to call `TypeRegistry::register_type_conversion` for type `{U}` without registering `{U}` first",
431                U = U::type_path(),
432            )
433        });
434        data.get_or_insert_data_with(ReflectConvert::default)
435            .register_type_conversion::<T, U, _>(|input| Ok(input.into()));
436    }
437
438    /// Whether the type with given [`TypeId`] has been registered in this registry.
439    pub fn contains(&self, type_id: TypeId) -> bool {
440        self.registrations.contains_key(&type_id)
441    }
442
443    /// Returns a reference to the [`TypeRegistration`] of the type with the
444    /// given [`TypeId`].
445    ///
446    /// If the specified type has not been registered, returns `None`.
447    #[inline]
448    pub fn get(&self, type_id: TypeId) -> Option<&TypeRegistration> {
449        self.registrations.get(&type_id)
450    }
451
452    /// Returns a mutable reference to the [`TypeRegistration`] of the type with
453    /// the given [`TypeId`].
454    ///
455    /// If the specified type has not been registered, returns `None`.
456    pub fn get_mut(&mut self, type_id: TypeId) -> Option<&mut TypeRegistration> {
457        self.registrations.get_mut(&type_id)
458    }
459
460    /// Returns a reference to the [`TypeRegistration`] of the type with the
461    /// given [type path].
462    ///
463    /// If no type with the given path has been registered, returns `None`.
464    ///
465    /// [type path]: TypePath::type_path
466    pub fn get_with_type_path(&self, type_path: &str) -> Option<&TypeRegistration> {
467        self.type_path_to_id
468            .get(type_path)
469            .and_then(|id| self.get(*id))
470    }
471
472    /// Returns a mutable reference to the [`TypeRegistration`] of the type with
473    /// the given [type path].
474    ///
475    /// If no type with the given type path has been registered, returns `None`.
476    ///
477    /// [type path]: TypePath::type_path
478    pub fn get_with_type_path_mut(&mut self, type_path: &str) -> Option<&mut TypeRegistration> {
479        self.type_path_to_id
480            .get(type_path)
481            .cloned()
482            .and_then(move |id| self.get_mut(id))
483    }
484
485    /// Returns a reference to the [`TypeRegistration`] of the type with
486    /// the given [short type path].
487    ///
488    /// If the short type path is ambiguous, or if no type with the given path
489    /// has been registered, returns `None`.
490    ///
491    /// [short type path]: TypePath::short_type_path
492    pub fn get_with_short_type_path(&self, short_type_path: &str) -> Option<&TypeRegistration> {
493        self.short_path_to_id
494            .get(short_type_path)
495            .and_then(|id| self.registrations.get(id))
496    }
497
498    /// Returns a mutable reference to the [`TypeRegistration`] of the type with
499    /// the given [short type path].
500    ///
501    /// If the short type path is ambiguous, or if no type with the given path
502    /// has been registered, returns `None`.
503    ///
504    /// [short type path]: TypePath::short_type_path
505    pub fn get_with_short_type_path_mut(
506        &mut self,
507        short_type_path: &str,
508    ) -> Option<&mut TypeRegistration> {
509        self.short_path_to_id
510            .get(short_type_path)
511            .and_then(|id| self.registrations.get_mut(id))
512    }
513
514    /// Returns `true` if the given [short type path] is ambiguous, that is, it matches multiple registered types.
515    ///
516    /// # Example
517    /// ```
518    /// # use bevy_reflect::TypeRegistry;
519    /// # mod foo {
520    /// #     use bevy_reflect::Reflect;
521    /// #     #[derive(Reflect)]
522    /// #     pub struct MyType;
523    /// # }
524    /// # mod bar {
525    /// #     use bevy_reflect::Reflect;
526    /// #     #[derive(Reflect)]
527    /// #     pub struct MyType;
528    /// # }
529    /// let mut type_registry = TypeRegistry::default();
530    /// type_registry.register::<foo::MyType>();
531    /// type_registry.register::<bar::MyType>();
532    /// assert_eq!(type_registry.is_ambiguous("MyType"), true);
533    /// ```
534    ///
535    /// [short type path]: TypePath::short_type_path
536    pub fn is_ambiguous(&self, short_type_path: &str) -> bool {
537        self.ambiguous_names.contains(short_type_path)
538    }
539
540    /// Returns a reference to the [`TypeData`] of type `T` associated with the given [`TypeId`].
541    ///
542    /// The returned value may be used to downcast [`Reflect`] trait objects to
543    /// trait objects of the trait used to generate `T`, provided that the
544    /// underlying reflected type has the proper `#[reflect(DoThing)]`
545    /// attribute.
546    ///
547    /// If the specified type has not been registered, or if `T` is not present
548    /// in its type registration, returns `None`.
549    pub fn get_type_data<T: TypeData>(&self, type_id: TypeId) -> Option<&T> {
550        self.get(type_id)
551            .and_then(|registration| registration.data::<T>())
552    }
553
554    /// Returns a mutable reference to the [`TypeData`] of type `T` associated with the given [`TypeId`].
555    ///
556    /// If the specified type has not been registered, or if `T` is not present
557    /// in its type registration, returns `None`.
558    pub fn get_type_data_mut<T: TypeData>(&mut self, type_id: TypeId) -> Option<&mut T> {
559        self.get_mut(type_id)
560            .and_then(|registration| registration.data_mut::<T>())
561    }
562
563    /// Returns the [`TypeInfo`] associated with the given [`TypeId`].
564    ///
565    /// If the specified type has not been registered, returns `None`.
566    pub fn get_type_info(&self, type_id: TypeId) -> Option<&'static TypeInfo> {
567        self.get(type_id).map(TypeRegistration::type_info)
568    }
569
570    /// Returns an iterator over the [`TypeRegistration`]s of the registered
571    /// types.
572    pub fn iter(&self) -> impl Iterator<Item = &TypeRegistration> {
573        self.registrations.values()
574    }
575
576    /// Returns a mutable iterator over the [`TypeRegistration`]s of the registered
577    /// types.
578    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TypeRegistration> {
579        self.registrations.values_mut()
580    }
581
582    /// Checks to see if the [`TypeData`] of type `T` is associated with each registered type,
583    /// returning a ([`TypeRegistration`], [`TypeData`]) iterator for all entries where data of that type was found.
584    pub fn iter_with_data<T: TypeData>(&self) -> impl Iterator<Item = (&TypeRegistration, &T)> {
585        self.registrations.values().filter_map(|item| {
586            let type_data = item.data::<T>();
587            type_data.map(|data| (item, data))
588        })
589    }
590}
591
592impl TypeRegistryArc {
593    /// Takes a read lock on the underlying [`TypeRegistry`].
594    pub fn read(&self) -> RwLockReadGuard<'_, TypeRegistry> {
595        self.internal.read().unwrap_or_else(PoisonError::into_inner)
596    }
597
598    /// Takes a write lock on the underlying [`TypeRegistry`].
599    pub fn write(&self) -> RwLockWriteGuard<'_, TypeRegistry> {
600        self.internal
601            .write()
602            .unwrap_or_else(PoisonError::into_inner)
603    }
604}
605
606/// Runtime storage for type metadata, registered into the [`TypeRegistry`].
607///
608/// An instance of `TypeRegistration` can be created using the [`TypeRegistration::of`] method,
609/// but is more often automatically generated using [`#[derive(Reflect)]`](derive@crate::Reflect) which itself generates
610/// an implementation of the [`GetTypeRegistration`] trait.
611///
612/// Along with the type's [`TypeInfo`],
613/// this struct also contains a type's registered [`TypeData`].
614///
615/// See the [crate-level documentation] for more information on type registration.
616///
617/// # Example
618///
619/// ```
620/// # use bevy_reflect::{TypeRegistration, std_traits::ReflectDefault, CreateTypeData};
621/// let mut registration = TypeRegistration::of::<Option<String>>();
622///
623/// assert_eq!("core::option::Option<alloc::string::String>", registration.type_info().type_path());
624/// assert_eq!("Option<String>", registration.type_info().type_path_table().short_path());
625///
626/// registration.insert::<ReflectDefault>(CreateTypeData::<Option<String>>::create_type_data(()));
627/// assert!(registration.data::<ReflectDefault>().is_some())
628/// ```
629///
630/// [crate-level documentation]: crate
631pub struct TypeRegistration {
632    data: TypeIdHashMap<Box<dyn TypeData>>,
633    type_info: &'static TypeInfo,
634}
635
636impl Debug for TypeRegistration {
637    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
638        f.debug_struct("TypeRegistration")
639            .field("type_info", &self.type_info)
640            .finish()
641    }
642}
643
644impl TypeRegistration {
645    /// Creates type registration information for `T`.
646    pub fn of<T: Reflect + Typed + TypePath>() -> Self {
647        Self {
648            data: Default::default(),
649            type_info: T::type_info(),
650        }
651    }
652
653    /// Returns the [`TypeId`] of the type.
654    #[inline]
655    pub fn type_id(&self) -> TypeId {
656        self.type_info.type_id()
657    }
658
659    /// Returns a reference to the registration's [`TypeInfo`]
660    pub fn type_info(&self) -> &'static TypeInfo {
661        self.type_info
662    }
663
664    /// Inserts an instance of `T` into this registration's [type data].
665    ///
666    /// If another instance of `T` was previously inserted, it is replaced.
667    ///
668    /// Note that unlike [`TypeRegistration::register_type_data`], this will not
669    /// automatically insert any type data dependencies for `T`.
670    /// That will need to be done manually using [`CreateTypeData::insert_dependencies`].
671    ///
672    /// [type data]: TypeData
673    pub fn insert<T: TypeData>(&mut self, data: T) {
674        self.data.insert(TypeId::of::<T>(), Box::new(data));
675    }
676
677    /// Gets the instance of `T` into this registration's [type data], if it exists. If it does not
678    /// exist, it will insert a new instance using `get_data` and then return it.
679    ///
680    /// [type data]: TypeData
681    pub fn get_or_insert_data_with<T: TypeData>(&mut self, get_data: impl FnOnce() -> T) -> &mut T {
682        let boxed_data = self
683            .data
684            .entry(TypeId::of::<T>())
685            .or_insert_with(|| Box::new(get_data()));
686        boxed_data.downcast_mut::<T>().unwrap()
687    }
688
689    /// Inserts the [`TypeData`] instance of `T` created for `V`, and inserts any
690    /// [`TypeData`] dependencies for that combination of `T` and `V`.
691    ///
692    /// To register [`TypeData`] that requires input (i.e. it doesn't take `()` as its input),
693    /// see [`TypeRegistration::register_type_data_with`].
694    #[inline]
695    pub fn register_type_data<T: CreateTypeData<V>, V>(&mut self) {
696        self.insert(T::create_type_data(()));
697        T::insert_dependencies(self);
698    }
699
700    /// Inserts the [`TypeData`] instance of `T` created for `V` with some input `I`,
701    /// and inserts any [`TypeData`] dependencies for that combination of `T`, `V`, and `I`.
702    ///
703    /// To register [`TypeData`] that doesn't require input (i.e. it expects `()`),
704    /// see [`TypeRegistration::register_type_data`].
705    #[inline]
706    pub fn register_type_data_with<T: CreateTypeData<V, I>, V, I>(&mut self, input: I) {
707        self.insert(T::create_type_data(input));
708        T::insert_dependencies(self);
709    }
710
711    /// Returns a reference to the value of type `T` in this registration's
712    /// [type data].
713    ///
714    /// Returns `None` if no such value exists.
715    ///
716    /// For a dynamic version of this method, see [`data_by_id`].
717    ///
718    /// [type data]: TypeData
719    /// [`data_by_id`]: Self::data_by_id
720    pub fn data<T: TypeData>(&self) -> Option<&T> {
721        self.data
722            .get(&TypeId::of::<T>())
723            .and_then(|value| value.downcast_ref())
724    }
725
726    /// Returns a reference to the value with the given [`TypeId`] in this registration's
727    /// [type data].
728    ///
729    /// Returns `None` if no such value exists.
730    ///
731    /// For a static version of this method, see [`data`].
732    ///
733    /// [type data]: TypeData
734    /// [`data`]: Self::data
735    pub fn data_by_id(&self, type_id: TypeId) -> Option<&dyn TypeData> {
736        self.data.get(&type_id).map(Deref::deref)
737    }
738
739    /// Returns a mutable reference to the value of type `T` in this registration's
740    /// [type data].
741    ///
742    /// Returns `None` if no such value exists.
743    ///
744    /// For a dynamic version of this method, see [`data_mut_by_id`].
745    ///
746    /// [type data]: TypeData
747    /// [`data_mut_by_id`]: Self::data_mut_by_id
748    pub fn data_mut<T: TypeData>(&mut self) -> Option<&mut T> {
749        self.data
750            .get_mut(&TypeId::of::<T>())
751            .and_then(|value| value.downcast_mut())
752    }
753
754    /// Returns a mutable reference to the value with the given [`TypeId`] in this registration's
755    /// [type data].
756    ///
757    /// Returns `None` if no such value exists.
758    ///
759    /// For a static version of this method, see [`data_mut`].
760    ///
761    /// [type data]: TypeData
762    /// [`data_mut`]: Self::data_mut
763    pub fn data_mut_by_id(&mut self, type_id: TypeId) -> Option<&mut dyn TypeData> {
764        self.data.get_mut(&type_id).map(DerefMut::deref_mut)
765    }
766
767    /// Returns true if this registration contains the given [type data].
768    ///
769    /// For a dynamic version of this method, see [`contains_by_id`].
770    ///
771    /// [type data]: TypeData
772    /// [`contains_by_id`]: Self::contains_by_id
773    pub fn contains<T: TypeData>(&self) -> bool {
774        self.data.contains_key(&TypeId::of::<T>())
775    }
776
777    /// Returns true if this registration contains the given [type data] with [`TypeId`].
778    ///
779    /// For a static version of this method, see [`contains`].
780    ///
781    /// [type data]: TypeData
782    /// [`contains`]: Self::contains
783    pub fn contains_by_id(&self, type_id: TypeId) -> bool {
784        self.data.contains_key(&type_id)
785    }
786
787    /// The total count of [type data] in this registration.
788    ///
789    /// [type data]: TypeData
790    pub fn len(&self) -> usize {
791        self.data.len()
792    }
793
794    /// Returns true if this registration has no [type data].
795    ///
796    /// [type data]: TypeData
797    pub fn is_empty(&self) -> bool {
798        self.data.is_empty()
799    }
800
801    /// Returns an iterator over all [type data] in this registration.
802    ///
803    /// The iterator yields a tuple of the [`TypeId`] and its corresponding type data.
804    ///
805    /// [type data]: TypeData
806    pub fn iter(&self) -> impl ExactSizeIterator<Item = (TypeId, &dyn TypeData)> {
807        self.data.iter().map(|(id, data)| (*id, data.deref()))
808    }
809
810    /// Returns a mutable iterator over all [type data] in this registration.
811    ///
812    /// The iterator yields a tuple of the [`TypeId`] and its corresponding type data.
813    ///
814    /// [type data]: TypeData
815    pub fn iter_mut(&mut self) -> impl ExactSizeIterator<Item = (TypeId, &mut dyn TypeData)> {
816        self.data
817            .iter_mut()
818            .map(|(id, data)| (*id, data.deref_mut()))
819    }
820}
821
822impl Clone for TypeRegistration {
823    fn clone(&self) -> Self {
824        let mut data = TypeIdHashMap::default();
825        for (id, type_data) in &self.data {
826            data.insert(*id, (*type_data).clone_type_data());
827        }
828
829        TypeRegistration {
830            data,
831            type_info: self.type_info,
832        }
833    }
834}
835
836/// A struct used to serialize reflected instances of a type.
837///
838/// A `ReflectSerialize` for type `T` can be obtained via
839/// [`CreateTypeData::create_type_data`].
840#[derive(Clone)]
841pub struct ReflectSerialize {
842    get_serializable: fn(value: &dyn Reflect) -> Serializable,
843}
844
845impl<T: TypePath + FromReflect + erased_serde::Serialize> CreateTypeData<T> for ReflectSerialize {
846    fn create_type_data(_input: ()) -> Self {
847        ReflectSerialize {
848            get_serializable: |value| {
849                value
850                    .downcast_ref::<T>()
851                    .map(|value| Serializable::Borrowed(value))
852                    .or_else(|| T::from_reflect(value.as_partial_reflect()).map(|value| Serializable::Owned(Box::new(value))))
853                    .unwrap_or_else(|| {
854                        panic!(
855                            "FromReflect::from_reflect failed when called on type `{}` with this value: {value:?}",
856                            T::type_path(),
857                        );
858                    })
859            },
860        }
861    }
862}
863
864impl ReflectSerialize {
865    /// Turn the value into a serializable representation
866    pub fn get_serializable<'a>(&self, value: &'a dyn Reflect) -> Serializable<'a> {
867        (self.get_serializable)(value)
868    }
869
870    /// Serializes a reflected value.
871    pub fn serialize<S>(&self, value: &dyn Reflect, serializer: S) -> Result<S::Ok, S::Error>
872    where
873        S: serde::Serializer,
874    {
875        (self.get_serializable)(value).serialize(serializer)
876    }
877}
878
879/// A struct used to deserialize reflected instances of a type.
880///
881/// A `ReflectDeserialize` for type `T` can be obtained via
882/// [`CreateTypeData::create_type_data`].
883#[derive(Clone)]
884pub struct ReflectDeserialize {
885    /// Function used by [`ReflectDeserialize::deserialize`] to
886    /// perform deserialization.
887    pub func: fn(
888        deserializer: &mut dyn erased_serde::Deserializer,
889    ) -> Result<Box<dyn Reflect>, erased_serde::Error>,
890}
891
892impl ReflectDeserialize {
893    /// Deserializes a reflected value.
894    ///
895    /// The underlying type of the reflected value, and thus the expected
896    /// structure of the serialized data, is determined by the type used to
897    /// construct this `ReflectDeserialize` value.
898    pub fn deserialize<'de, D>(&self, deserializer: D) -> Result<Box<dyn Reflect>, D::Error>
899    where
900        D: serde::Deserializer<'de>,
901    {
902        let mut erased = <dyn erased_serde::Deserializer>::erase(deserializer);
903        (self.func)(&mut erased)
904            .map_err(<<D as serde::Deserializer<'de>>::Error as serde::de::Error>::custom)
905    }
906}
907
908impl<T: for<'a> Deserialize<'a> + Reflect> CreateTypeData<T> for ReflectDeserialize {
909    fn create_type_data(_input: ()) -> Self {
910        ReflectDeserialize {
911            func: |deserializer| Ok(Box::new(T::deserialize(deserializer)?)),
912        }
913    }
914}
915
916/// [`Reflect`] values are commonly used in situations where the actual types of values
917/// are not known at runtime. In such situations you might have access to a `*const ()` pointer
918/// that you know implements [`Reflect`], but have no way of turning it into a `&dyn Reflect`.
919///
920/// This is where [`ReflectFromPtr`] comes in, when creating a [`ReflectFromPtr`] for a given type `T: Reflect`.
921/// Internally, this saves a concrete function `*mut T -> *mut dyn Reflect` which lets you create a trait object of [`Reflect`]
922/// from a pointer.
923///
924/// # Example
925/// ```
926/// use bevy_reflect::{TypeRegistry, Reflect, ReflectFromPtr};
927/// use core::any::Any;
928///
929/// #[derive(Reflect)]
930/// struct Reflected(String);
931///
932/// let mut type_registry = TypeRegistry::default();
933/// type_registry.register::<Reflected>();
934///
935/// let mut value = Reflected("Hello world!".to_string());
936/// let value: &dyn Any = &value;
937///
938/// let reflect_data = type_registry.get(core::any::TypeId::of::<Reflected>()).unwrap();
939/// let reflect_from_ptr = reflect_data.data::<ReflectFromPtr>().unwrap();
940/// let value = reflect_from_ptr.as_reflect(value).unwrap();
941///
942/// assert_eq!(value.downcast_ref::<Reflected>().unwrap().0, "Hello world!");
943/// ```
944#[derive(Clone)]
945pub struct ReflectFromPtr {
946    /// The type ID that this cast is generated for.
947    ///
948    /// This **may be** different from the type ID used to fetch this type data from the type
949    /// registration, if a user creates this instance for type A, but then inserts it into type B's
950    /// type registration. Therefore, for safety, we store it in this type data so that users can
951    /// assert to ensure soundness.
952    type_id: TypeId,
953    /// The thunk for casting from an arbitrary pointer to a [`dyn Reflect`] pointer.
954    ///
955    /// This thunk effectively just adds the vtable pointer for [`Reflect`] for the type to whatever
956    /// pointer you pass in. This function does no validation.
957    cast_ptr: fn(*mut ()) -> *mut dyn Reflect,
958}
959
960#[expect(
961    unsafe_code,
962    reason = "We must interact with pointers here, which are inherently unsafe."
963)]
964impl ReflectFromPtr {
965    /// Returns the [`TypeId`] that the [`ReflectFromPtr`] was constructed for.
966    pub fn type_id(&self) -> TypeId {
967        self.type_id
968    }
969
970    /// Returns the underlying function to cast from an arbitrary pointer to a [`dyn Reflect`]
971    /// pointer.
972    ///
973    /// This function effectively just adds the vtable pointer for [`Reflect`] for the type this
974    /// [`ReflectFromPtr`] was constructed for, to whatever pointer you pass in. This function does
975    /// no validation or manipulation - it just does a pointer cast.
976    ///
977    /// The returned function is technically safe. We simply manipulate some pointers. However,
978    /// using the result of this function requires the normal safety requirements. In particular,
979    /// you must ensure that the original pointer actually pointed to a value of the type that this
980    /// [`ReflectFromPtr`] was constructed for. This can be verified by checking that the type ID
981    /// returned by [`ReflectFromPtr::type_id`] matches the original pointer's runtime type ID.
982    /// Note: It is **not** sufficient that you got this [`ReflectFromPtr`] from the type registry
983    /// for type ID A. It is possible for someone to overwrite the [`ReflectFromPtr`] type data with
984    /// that of a different type. Therefore, to ensure soundness, you must check [`ReflectFromPtr::type_id`].
985    ///
986    /// If you need to call this function for a `*const ()`, you may simple use
987    /// [`cast_mut`] for the input and [`cast_const`] for the output.
988    ///
989    /// [`cast_mut`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_mut
990    /// [`cast_const`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_const
991    pub fn raw_pointer_cast(&self) -> fn(*mut ()) -> *mut dyn Reflect {
992        self.cast_ptr
993    }
994
995    /// Converts a [`&dyn Any`] into a [`&dyn Reflect`] if the type matches the type used to
996    /// construct this [`ReflectFromPtr`].
997    pub fn as_reflect<'a>(&self, any: &'a dyn Any) -> Option<&'a dyn Reflect> {
998        if (*any).type_id() != self.type_id {
999            return None;
1000        }
1001
1002        let data_ptr = core::ptr::from_ref(any).cast::<()>().cast_mut();
1003        let reflect_ptr: *const dyn Reflect = (self.cast_ptr)(data_ptr).cast_const();
1004
1005        // SAFETY: We only casted the data pointer of the `any`, so the new reference we create has
1006        // the same validity as the `any` reference. Since the type_id of `any` and `self.type_id`
1007        // matches, we know that the data in `any` actually holds this type, which impls `Reflect`.
1008        // This function definition also ensures that the new borrow does not outlive `any`.
1009        Some(unsafe { &*reflect_ptr })
1010    }
1011
1012    /// Converts a [`&mut dyn Any`] into a [`&mut dyn Reflect`] if the type matches the type used to
1013    /// construct this [`ReflectFromPtr`].
1014    pub fn as_reflect_mut<'a>(&self, any: &'a mut dyn Any) -> Option<&'a mut dyn Reflect> {
1015        if (*any).type_id() != self.type_id {
1016            return None;
1017        }
1018
1019        let data_ptr = core::ptr::from_mut(any).cast();
1020        let reflect_ptr: *mut dyn Reflect = (self.cast_ptr)(data_ptr);
1021
1022        // SAFETY: We only casted the data pointer of the `any`, so the new reference we create has
1023        // the same validity as the `any` reference. Since the type_id of `any` and `self.type_id`
1024        // matches, we know that the data in `any` actually holds this type, which impls `Reflect`.
1025        // This function definition also ensures that the new borrow does not outlive `any`.
1026        Some(unsafe { &mut *reflect_ptr })
1027    }
1028
1029    /// Converts a [`Box<dyn Any>`] into a [`Box<dyn Reflect>`] if the type matches the type used to
1030    /// construct this [`ReflectFromPtr`].
1031    ///
1032    /// If the type does not match [`Self::type_id`], returns an [`Err`] holding `any`.
1033    pub fn box_as_reflect(&self, any: Box<dyn Any>) -> Result<Box<dyn Reflect>, Box<dyn Any>> {
1034        if (*any).type_id() != self.type_id {
1035            return Err(any);
1036        }
1037
1038        let data_ptr = Box::into_raw(any).cast();
1039        let reflect_ptr: *mut dyn Reflect = (self.cast_ptr)(data_ptr);
1040
1041        // SAFETY: We just leaked the box, and haven't given the pointer anywhere else, so we still
1042        // own this pointer. We only casted the pointer of the `any`, so the pointer has the same
1043        // validity as the original box. Since the type_id of `any` and `self.type_id` matches, we
1044        // know that the data in `any` actually holds this type, which impls `Reflect`.
1045        Ok(unsafe { Box::from_raw(reflect_ptr) })
1046    }
1047
1048    /// Converts a [`Arc<dyn Any>`] into a [`Arc<dyn Reflect>`] if the type matches the type used to
1049    /// construct this [`ReflectFromPtr`].
1050    ///
1051    /// If the type does not match [`Self::type_id`], returns an [`Err`] holding `any`.
1052    pub fn arc_as_reflect(&self, any: Arc<dyn Any>) -> Result<Arc<dyn Reflect>, Arc<dyn Any>> {
1053        if (*any).type_id() != self.type_id {
1054            return Err(any);
1055        }
1056
1057        let data_ptr = Arc::into_raw(any).cast::<()>().cast_mut();
1058        let reflect_ptr: *const dyn Reflect = (self.cast_ptr)(data_ptr).cast_const();
1059
1060        // SAFETY: We just got this data pointer from Arc::into_raw, so we can convert it back
1061        // from_raw. Since the type_id of `any` and `self.type_id` matches, we know that the data in
1062        // `any` actually holds this type, which impls `Reflect`.
1063        Ok(unsafe { Arc::from_raw(reflect_ptr) })
1064    }
1065
1066    /// Convert `Ptr` into `&dyn Reflect`.
1067    ///
1068    /// # Safety
1069    ///
1070    /// `val` must be a pointer to value of the type that the [`ReflectFromPtr`] was constructed for.
1071    /// This can be verified by checking that the type id returned by [`ReflectFromPtr::type_id`] is the expected one.
1072    pub unsafe fn ptr_as_reflect<'a>(&self, val: Ptr<'a>) -> &'a dyn Reflect {
1073        let reflect_raw_pointer = (self.cast_ptr)(val.as_ptr().cast::<()>().cast_mut());
1074        // SAFETY: cast_ptr is guaranteed not to change the original pointer. We know the pointer is
1075        // non-null and that it is aligned (since `Ptr` includes the IsAligned) type state. Caller
1076        // guarantees that `val` points to a value of the type that we were constructed for.
1077        unsafe { &*reflect_raw_pointer }
1078    }
1079
1080    /// Convert `PtrMut` into `&mut dyn Reflect`.
1081    ///
1082    /// # Safety
1083    ///
1084    /// `val` must be a pointer to a value of the type that the [`ReflectFromPtr`] was constructed for
1085    /// This can be verified by checking that the type id returned by [`ReflectFromPtr::type_id`] is the expected one.
1086    pub unsafe fn ptr_as_reflect_mut<'a>(&self, val: PtrMut<'a>) -> &'a mut dyn Reflect {
1087        let reflect_raw_pointer = (self.cast_ptr)(val.as_ptr().cast());
1088        // SAFETY: cast_ptr is guaranteed not to change the original pointer. We know the pointer is
1089        // non-null and that it is aligned (since `Ptr` includes the IsAligned) type state. Caller
1090        // guarantees that `val` points to a value of the type that we were constructed for.
1091        unsafe { &mut *reflect_raw_pointer }
1092    }
1093}
1094
1095impl<T: Reflect> CreateTypeData<T> for ReflectFromPtr {
1096    fn create_type_data(_input: ()) -> Self {
1097        ReflectFromPtr {
1098            type_id: TypeId::of::<T>(),
1099            // First, cast the `*mut ()` into a `*mut T` (which lets Rust know what type we're
1100            // talking about). Then, cast it into a `*mut dyn Reflect` which Rust then inserts the
1101            // vtable for `T` into.
1102            cast_ptr: |ptr| ptr.cast::<T>() as *mut dyn Reflect,
1103        }
1104    }
1105}
1106
1107#[cfg(test)]
1108#[expect(
1109    unsafe_code,
1110    reason = "We must interact with pointers here, which are inherently unsafe."
1111)]
1112mod test {
1113    use super::*;
1114
1115    #[derive(Reflect, PartialEq, Debug, Clone)]
1116    struct Foo {
1117        a: f32,
1118    }
1119
1120    #[test]
1121    fn test_reflect_from_ptr() {
1122        let foo_registration = <Foo as GetTypeRegistration>::get_type_registration();
1123        let reflect_from_ptr = foo_registration.data::<ReflectFromPtr>().unwrap();
1124
1125        // not required in this situation because we no nobody messed with the TypeRegistry,
1126        // but in the general case somebody could have replaced the ReflectFromPtr with an
1127        // instance for another type, so then we'd need to check that the type is the expected one
1128        assert_eq!(reflect_from_ptr.type_id(), TypeId::of::<Foo>());
1129
1130        let mut value = Foo { a: 1.0 };
1131        {
1132            let value = PtrMut::from(&mut value);
1133            // SAFETY: reflect_from_ptr was constructed for the correct type
1134            let dyn_reflect = unsafe { reflect_from_ptr.ptr_as_reflect_mut(value) };
1135            match dyn_reflect.reflect_mut() {
1136                bevy_reflect::ReflectMut::Struct(strukt) => {
1137                    strukt.field_mut("a").unwrap().apply(&2.0f32);
1138                }
1139                _ => panic!("invalid reflection"),
1140            }
1141        }
1142
1143        {
1144            // SAFETY: reflect_from_ptr was constructed for the correct type
1145            let dyn_reflect = unsafe { reflect_from_ptr.ptr_as_reflect(Ptr::from(&value)) };
1146            match dyn_reflect.reflect_ref() {
1147                bevy_reflect::ReflectRef::Struct(strukt) => {
1148                    let a = strukt
1149                        .field("a")
1150                        .unwrap()
1151                        .try_downcast_ref::<f32>()
1152                        .unwrap();
1153                    assert_eq!(*a, 2.0);
1154                }
1155                _ => panic!("invalid reflection"),
1156            }
1157        }
1158    }
1159
1160    #[test]
1161    fn convert_any_ref_to_reflect() {
1162        let foo_registration = <Foo as GetTypeRegistration>::get_type_registration();
1163        let reflect_from_ptr = foo_registration.data::<ReflectFromPtr>().unwrap();
1164
1165        let object = Foo { a: 1.0 };
1166
1167        let any: &dyn Any = &object;
1168        let reflect = reflect_from_ptr.as_reflect(any).unwrap();
1169
1170        let object_from_reflect = Foo::from_reflect(reflect).unwrap();
1171        assert_eq!(object_from_reflect, object);
1172    }
1173
1174    #[test]
1175    fn convert_any_mut_to_reflect() {
1176        let foo_registration = <Foo as GetTypeRegistration>::get_type_registration();
1177        let reflect_from_ptr = foo_registration.data::<ReflectFromPtr>().unwrap();
1178
1179        let mut object = Foo { a: 1.0 };
1180
1181        let any: &mut dyn Any = &mut object;
1182        let reflect = reflect_from_ptr.as_reflect_mut(any).unwrap();
1183
1184        let replacement = Foo { a: 2.0 };
1185        reflect.apply(&replacement);
1186
1187        // We mutated `object` through `reflect` which we casted through `&mut dyn Any`.
1188        assert_eq!(object, replacement);
1189    }
1190
1191    #[test]
1192    fn convert_box_to_reflect() {
1193        let foo_registration = <Foo as GetTypeRegistration>::get_type_registration();
1194        let reflect_from_ptr = foo_registration.data::<ReflectFromPtr>().unwrap();
1195
1196        let any: Box<dyn Any> = Box::new(Foo { a: 1.0 });
1197        let mut reflect = reflect_from_ptr.box_as_reflect(any).unwrap();
1198
1199        let replacement = Foo { a: 2.0 };
1200        reflect.apply(&replacement);
1201
1202        // We consumed the value, which was mutated through reflection.
1203        let final_object: Foo = reflect.take().unwrap();
1204        assert_eq!(final_object, replacement);
1205    }
1206
1207    #[test]
1208    fn convert_arc_to_reflect() {
1209        let foo_registration = <Foo as GetTypeRegistration>::get_type_registration();
1210        let reflect_from_ptr = foo_registration.data::<ReflectFromPtr>().unwrap();
1211
1212        let any: Arc<dyn Any> = Arc::new(Foo { a: 1.0 });
1213        let reflect = reflect_from_ptr.arc_as_reflect(any).unwrap();
1214
1215        // We can use reflection to access the "a" field.
1216        match reflect.reflect_ref() {
1217            crate::ReflectRef::Struct(strukt) => {
1218                let a = strukt
1219                    .field("a")
1220                    .unwrap()
1221                    .try_downcast_ref::<f32>()
1222                    .unwrap();
1223                assert_eq!(*a, 1.0);
1224            }
1225            _ => panic!("unexpected meta-type"),
1226        }
1227    }
1228
1229    #[test]
1230    fn checks_type_ids_for_any_conversions() {
1231        let foo_registration = <Foo as GetTypeRegistration>::get_type_registration();
1232        let reflect_from_ptr = foo_registration.data::<ReflectFromPtr>().unwrap();
1233
1234        let mut right_type = Foo { a: 1.0 };
1235        let mut wrong_type = 2.0;
1236        assert!(reflect_from_ptr.as_reflect(&right_type).is_some());
1237        assert!(reflect_from_ptr.as_reflect(&wrong_type).is_none());
1238        assert!(reflect_from_ptr.as_reflect_mut(&mut right_type).is_some());
1239        assert!(reflect_from_ptr.as_reflect_mut(&mut wrong_type).is_none());
1240        assert!(reflect_from_ptr
1241            .box_as_reflect(Box::new(right_type.clone()))
1242            .is_ok());
1243        assert!(reflect_from_ptr
1244            .box_as_reflect(Box::new(wrong_type))
1245            .is_err());
1246        assert!(reflect_from_ptr
1247            .arc_as_reflect(Arc::new(right_type))
1248            .is_ok());
1249        assert!(reflect_from_ptr
1250            .arc_as_reflect(Arc::new(wrong_type))
1251            .is_err());
1252    }
1253
1254    #[test]
1255    fn type_data_iter() {
1256        #[derive(Reflect)]
1257        struct Foo;
1258
1259        #[derive(Clone)]
1260        struct DataA(i32);
1261
1262        let mut registration = TypeRegistration::of::<Foo>();
1263        registration.insert(DataA(123));
1264
1265        let mut iter = registration.iter();
1266
1267        let (id, data) = iter.next().unwrap();
1268        assert_eq!(id, TypeId::of::<DataA>());
1269        assert_eq!(data.downcast_ref::<DataA>().unwrap().0, 123);
1270
1271        assert!(iter.next().is_none());
1272    }
1273
1274    #[test]
1275    fn type_data_iter_mut() {
1276        #[derive(Reflect)]
1277        struct Foo;
1278
1279        #[derive(Clone)]
1280        struct DataA(i32);
1281
1282        let mut registration = TypeRegistration::of::<Foo>();
1283        registration.insert(DataA(123));
1284
1285        {
1286            let mut iter = registration.iter_mut();
1287
1288            let (_, data) = iter.next().unwrap();
1289            data.downcast_mut::<DataA>().unwrap().0 = 456;
1290
1291            assert!(iter.next().is_none());
1292        }
1293
1294        let data = registration.data::<DataA>().unwrap();
1295        assert_eq!(data.0, 456);
1296    }
1297}