bevy_reflect/
type_registry.rs

1use crate::{serde::Serializable, FromReflect, Reflect, TypeInfo, TypePath, Typed};
2use alloc::{boxed::Box, string::String};
3use bevy_platform::{
4    collections::{HashMap, HashSet},
5    sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard},
6};
7use bevy_ptr::{Ptr, PtrMut};
8use bevy_utils::TypeIdMap;
9use core::{
10    any::TypeId,
11    fmt::Debug,
12    ops::{Deref, DerefMut},
13};
14use downcast_rs::{impl_downcast, Downcast};
15use serde::Deserialize;
16
17/// A registry of [reflected] types.
18///
19/// This struct is used as the central store for type information.
20/// [Registering] a type will generate a new [`TypeRegistration`] entry in this store
21/// using a type's [`GetTypeRegistration`] implementation
22/// (which is automatically implemented when using [`#[derive(Reflect)]`](derive@crate::Reflect)).
23///
24/// See the [crate-level documentation] for more information.
25///
26/// [reflected]: crate
27/// [Registering]: TypeRegistry::register
28/// [crate-level documentation]: crate
29pub struct TypeRegistry {
30    registrations: TypeIdMap<TypeRegistration>,
31    short_path_to_id: HashMap<&'static str, TypeId>,
32    type_path_to_id: HashMap<&'static str, TypeId>,
33    ambiguous_names: HashSet<&'static str>,
34}
35
36// TODO:  remove this wrapper once we migrate to Atelier Assets and the Scene AssetLoader doesn't
37// need a TypeRegistry ref
38/// A synchronized wrapper around a [`TypeRegistry`].
39#[derive(Clone, Default)]
40pub struct TypeRegistryArc {
41    /// The wrapped [`TypeRegistry`].
42    pub internal: Arc<RwLock<TypeRegistry>>,
43}
44
45impl Debug for TypeRegistryArc {
46    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47        self.internal
48            .read()
49            .unwrap_or_else(PoisonError::into_inner)
50            .type_path_to_id
51            .keys()
52            .fmt(f)
53    }
54}
55
56/// A trait which allows a type to generate its [`TypeRegistration`]
57/// for registration into the [`TypeRegistry`].
58///
59/// This trait is automatically implemented for items using [`#[derive(Reflect)]`](derive@crate::Reflect).
60/// The macro also allows [`TypeData`] to be more easily registered.
61///
62/// If you need to use this trait as a generic bound along with other reflection traits,
63/// for your convenience, consider using [`Reflectable`] instead.
64///
65/// See the [crate-level documentation] for more information on type registration.
66///
67/// [`Reflectable`]: crate::Reflectable
68/// [crate-level documentation]: crate
69#[diagnostic::on_unimplemented(
70    message = "`{Self}` does not implement `GetTypeRegistration` so cannot provide type registration information",
71    note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
72)]
73pub trait GetTypeRegistration: 'static {
74    /// Returns the default [`TypeRegistration`] for this type.
75    fn get_type_registration() -> TypeRegistration;
76    /// Registers other types needed by this type.
77    ///
78    /// This method is called by [`TypeRegistry::register`] to register any other required types.
79    /// Often, this is done for fields of structs and enum variants to ensure all types are properly registered.
80    fn register_type_dependencies(_registry: &mut TypeRegistry) {}
81}
82
83impl Default for TypeRegistry {
84    fn default() -> Self {
85        Self::new()
86    }
87}
88
89impl TypeRegistry {
90    /// Create a type registry with *no* registered types.
91    pub fn empty() -> Self {
92        Self {
93            registrations: Default::default(),
94            short_path_to_id: Default::default(),
95            type_path_to_id: Default::default(),
96            ambiguous_names: Default::default(),
97        }
98    }
99
100    /// Create a type registry with default registrations for primitive types.
101    pub fn new() -> Self {
102        let mut registry = Self::empty();
103        registry.register::<bool>();
104        registry.register::<char>();
105        registry.register::<u8>();
106        registry.register::<u16>();
107        registry.register::<u32>();
108        registry.register::<u64>();
109        registry.register::<u128>();
110        registry.register::<usize>();
111        registry.register::<i8>();
112        registry.register::<i16>();
113        registry.register::<i32>();
114        registry.register::<i64>();
115        registry.register::<i128>();
116        registry.register::<isize>();
117        registry.register::<f32>();
118        registry.register::<f64>();
119        registry.register::<String>();
120        registry
121    }
122
123    /// Register all non-generic types annotated with `#[derive(Reflect)]`.
124    ///
125    /// Calling this method is equivalent to calling [`register`](Self::register) on all types without generic parameters
126    /// that derived [`Reflect`] trait.
127    ///
128    /// This method is supported on Linux, macOS, Windows, iOS, Android, and Web via the `inventory` crate.
129    /// It does nothing on platforms not supported by either of those crates.
130    ///
131    /// # Example
132    ///
133    /// ```
134    /// # use std::any::TypeId;
135    /// # use bevy_reflect::{Reflect, TypeRegistry, std_traits::ReflectDefault};
136    /// #[derive(Reflect, Default)]
137    /// #[reflect(Default)]
138    /// struct Foo {
139    ///   name: Option<String>,
140    ///   value: i32
141    /// }
142    ///
143    /// let mut type_registry = TypeRegistry::empty();
144    /// type_registry.register_derived_types();
145    ///
146    /// // The main type
147    /// assert!(type_registry.contains(TypeId::of::<Foo>()));
148    ///
149    /// // Its type dependencies
150    /// assert!(type_registry.contains(TypeId::of::<Option<String>>()));
151    /// assert!(type_registry.contains(TypeId::of::<i32>()));
152    ///
153    /// // Its type data
154    /// assert!(type_registry.get_type_data::<ReflectDefault>(TypeId::of::<Foo>()).is_some());
155    /// ```
156    #[cfg(feature = "auto_register")]
157    pub fn register_derived_types(&mut self) {
158        crate::__macro_exports::auto_register::register_types(self);
159    }
160
161    /// Attempts to register the type `T` if it has not yet been registered already.
162    ///
163    /// This will also recursively register any type dependencies as specified by [`GetTypeRegistration::register_type_dependencies`].
164    /// When deriving `Reflect`, this will generally be all the fields of the struct or enum variant.
165    /// As with any type registration, these type dependencies will not be registered more than once.
166    ///
167    /// If the registration for type `T` already exists, it will not be registered again and neither will its type dependencies.
168    /// To register the type, overwriting any existing registration, use [register](Self::overwrite_registration) instead.
169    ///
170    /// Additionally, this will add any reflect [type data](TypeData) as specified in the [`Reflect`] derive.
171    ///
172    /// # Example
173    ///
174    /// ```
175    /// # use core::any::TypeId;
176    /// # use bevy_reflect::{Reflect, TypeRegistry, std_traits::ReflectDefault};
177    /// #[derive(Reflect, Default)]
178    /// #[reflect(Default)]
179    /// struct Foo {
180    ///   name: Option<String>,
181    ///   value: i32
182    /// }
183    ///
184    /// let mut type_registry = TypeRegistry::default();
185    ///
186    /// type_registry.register::<Foo>();
187    ///
188    /// // The main type
189    /// assert!(type_registry.contains(TypeId::of::<Foo>()));
190    ///
191    /// // Its type dependencies
192    /// assert!(type_registry.contains(TypeId::of::<Option<String>>()));
193    /// assert!(type_registry.contains(TypeId::of::<i32>()));
194    ///
195    /// // Its type data
196    /// assert!(type_registry.get_type_data::<ReflectDefault>(TypeId::of::<Foo>()).is_some());
197    /// ```
198    pub fn register<T>(&mut self)
199    where
200        T: GetTypeRegistration,
201    {
202        if self.register_internal(TypeId::of::<T>(), T::get_type_registration) {
203            T::register_type_dependencies(self);
204        }
205    }
206
207    /// Attempts to register the referenced type `T` if it has not yet been registered.
208    ///
209    /// See [`register`] for more details.
210    ///
211    /// # Example
212    ///
213    /// ```
214    /// # use bevy_reflect::{Reflect, TypeRegistry};
215    /// # use core::any::TypeId;
216    /// #
217    /// # let mut type_registry = TypeRegistry::default();
218    /// #
219    /// #[derive(Reflect)]
220    /// struct Foo {
221    ///   bar: Bar,
222    /// }
223    ///
224    /// #[derive(Reflect)]
225    /// struct Bar;
226    ///
227    /// let foo = Foo { bar: Bar };
228    ///
229    /// // Equivalent to `type_registry.register::<Foo>()`
230    /// type_registry.register_by_val(&foo);
231    ///
232    /// assert!(type_registry.contains(TypeId::of::<Foo>()));
233    /// assert!(type_registry.contains(TypeId::of::<Bar>()));
234    /// ```
235    ///
236    /// [`register`]: Self::register
237    pub fn register_by_val<T>(&mut self, _: &T)
238    where
239        T: GetTypeRegistration,
240    {
241        self.register::<T>();
242    }
243
244    /// Attempts to register the type described by `registration`.
245    ///
246    /// If the registration for the type already exists, it will not be registered again.
247    ///
248    /// To forcibly register the type, overwriting any existing registration, use the
249    /// [`overwrite_registration`](Self::overwrite_registration) method instead.
250    ///
251    /// This method will _not_ register type dependencies.
252    /// Use [`register`](Self::register) to register a type with its dependencies.
253    ///
254    /// Returns `true` if the registration was added and `false` if it already exists.
255    pub fn add_registration(&mut self, registration: TypeRegistration) -> bool {
256        let type_id = registration.type_id();
257        self.register_internal(type_id, || registration)
258    }
259
260    /// Registers the type described by `registration`.
261    ///
262    /// If the registration for the type already exists, it will be overwritten.
263    ///
264    /// To avoid overwriting existing registrations, it's recommended to use the
265    /// [`register`](Self::register) or [`add_registration`](Self::add_registration) methods instead.
266    ///
267    /// This method will _not_ register type dependencies.
268    /// Use [`register`](Self::register) to register a type with its dependencies.
269    pub fn overwrite_registration(&mut self, registration: TypeRegistration) {
270        Self::update_registration_indices(
271            &registration,
272            &mut self.short_path_to_id,
273            &mut self.type_path_to_id,
274            &mut self.ambiguous_names,
275        );
276        self.registrations
277            .insert(registration.type_id(), registration);
278    }
279
280    /// Internal method to register a type with a given [`TypeId`] and [`TypeRegistration`].
281    ///
282    /// By using this method, we are able to reduce the number of `TypeId` hashes and lookups needed
283    /// to register a type.
284    ///
285    /// This method is internal to prevent users from accidentally registering a type with a `TypeId`
286    /// that does not match the type in the `TypeRegistration`.
287    fn register_internal(
288        &mut self,
289        type_id: TypeId,
290        get_registration: impl FnOnce() -> TypeRegistration,
291    ) -> bool {
292        use bevy_platform::collections::hash_map::Entry;
293
294        match self.registrations.entry(type_id) {
295            Entry::Occupied(_) => false,
296            Entry::Vacant(entry) => {
297                let registration = get_registration();
298                Self::update_registration_indices(
299                    &registration,
300                    &mut self.short_path_to_id,
301                    &mut self.type_path_to_id,
302                    &mut self.ambiguous_names,
303                );
304                entry.insert(registration);
305                true
306            }
307        }
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 e.g. [`ReflectSerialize`] 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: TypeData + FromType<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::from_type());
353    }
354
355    /// Whether the type with given [`TypeId`] has been registered in this registry.
356    pub fn contains(&self, type_id: TypeId) -> bool {
357        self.registrations.contains_key(&type_id)
358    }
359
360    /// Returns a reference to the [`TypeRegistration`] of the type with the
361    /// given [`TypeId`].
362    ///
363    /// If the specified type has not been registered, returns `None`.
364    #[inline]
365    pub fn get(&self, type_id: TypeId) -> Option<&TypeRegistration> {
366        self.registrations.get(&type_id)
367    }
368
369    /// Returns a mutable reference to the [`TypeRegistration`] of the type with
370    /// the given [`TypeId`].
371    ///
372    /// If the specified type has not been registered, returns `None`.
373    pub fn get_mut(&mut self, type_id: TypeId) -> Option<&mut TypeRegistration> {
374        self.registrations.get_mut(&type_id)
375    }
376
377    /// Returns a reference to the [`TypeRegistration`] of the type with the
378    /// given [type path].
379    ///
380    /// If no type with the given path has been registered, returns `None`.
381    ///
382    /// [type path]: TypePath::type_path
383    pub fn get_with_type_path(&self, type_path: &str) -> Option<&TypeRegistration> {
384        self.type_path_to_id
385            .get(type_path)
386            .and_then(|id| self.get(*id))
387    }
388
389    /// Returns a mutable reference to the [`TypeRegistration`] of the type with
390    /// the given [type path].
391    ///
392    /// If no type with the given type path has been registered, returns `None`.
393    ///
394    /// [type path]: TypePath::type_path
395    pub fn get_with_type_path_mut(&mut self, type_path: &str) -> Option<&mut TypeRegistration> {
396        self.type_path_to_id
397            .get(type_path)
398            .cloned()
399            .and_then(move |id| self.get_mut(id))
400    }
401
402    /// Returns a reference to the [`TypeRegistration`] of the type with
403    /// the given [short type path].
404    ///
405    /// If the short type path is ambiguous, or if no type with the given path
406    /// has been registered, returns `None`.
407    ///
408    /// [short type path]: TypePath::short_type_path
409    pub fn get_with_short_type_path(&self, short_type_path: &str) -> Option<&TypeRegistration> {
410        self.short_path_to_id
411            .get(short_type_path)
412            .and_then(|id| self.registrations.get(id))
413    }
414
415    /// Returns a mutable reference to the [`TypeRegistration`] of the type with
416    /// the given [short type path].
417    ///
418    /// If the short type path is ambiguous, or if no type with the given path
419    /// has been registered, returns `None`.
420    ///
421    /// [short type path]: TypePath::short_type_path
422    pub fn get_with_short_type_path_mut(
423        &mut self,
424        short_type_path: &str,
425    ) -> Option<&mut TypeRegistration> {
426        self.short_path_to_id
427            .get(short_type_path)
428            .and_then(|id| self.registrations.get_mut(id))
429    }
430
431    /// Returns `true` if the given [short type path] is ambiguous, that is, it matches multiple registered types.
432    ///
433    /// # Example
434    /// ```
435    /// # use bevy_reflect::TypeRegistry;
436    /// # mod foo {
437    /// #     use bevy_reflect::Reflect;
438    /// #     #[derive(Reflect)]
439    /// #     pub struct MyType;
440    /// # }
441    /// # mod bar {
442    /// #     use bevy_reflect::Reflect;
443    /// #     #[derive(Reflect)]
444    /// #     pub struct MyType;
445    /// # }
446    /// let mut type_registry = TypeRegistry::default();
447    /// type_registry.register::<foo::MyType>();
448    /// type_registry.register::<bar::MyType>();
449    /// assert_eq!(type_registry.is_ambiguous("MyType"), true);
450    /// ```
451    ///
452    /// [short type path]: TypePath::short_type_path
453    pub fn is_ambiguous(&self, short_type_path: &str) -> bool {
454        self.ambiguous_names.contains(short_type_path)
455    }
456
457    /// Returns a reference to the [`TypeData`] of type `T` associated with the given [`TypeId`].
458    ///
459    /// The returned value may be used to downcast [`Reflect`] trait objects to
460    /// trait objects of the trait used to generate `T`, provided that the
461    /// underlying reflected type has the proper `#[reflect(DoThing)]`
462    /// attribute.
463    ///
464    /// If the specified type has not been registered, or if `T` is not present
465    /// in its type registration, returns `None`.
466    pub fn get_type_data<T: TypeData>(&self, type_id: TypeId) -> Option<&T> {
467        self.get(type_id)
468            .and_then(|registration| registration.data::<T>())
469    }
470
471    /// Returns a mutable reference to the [`TypeData`] of type `T` associated with the given [`TypeId`].
472    ///
473    /// If the specified type has not been registered, or if `T` is not present
474    /// in its type registration, returns `None`.
475    pub fn get_type_data_mut<T: TypeData>(&mut self, type_id: TypeId) -> Option<&mut T> {
476        self.get_mut(type_id)
477            .and_then(|registration| registration.data_mut::<T>())
478    }
479
480    /// Returns the [`TypeInfo`] associated with the given [`TypeId`].
481    ///
482    /// If the specified type has not been registered, returns `None`.
483    pub fn get_type_info(&self, type_id: TypeId) -> Option<&'static TypeInfo> {
484        self.get(type_id).map(TypeRegistration::type_info)
485    }
486
487    /// Returns an iterator over the [`TypeRegistration`]s of the registered
488    /// types.
489    pub fn iter(&self) -> impl Iterator<Item = &TypeRegistration> {
490        self.registrations.values()
491    }
492
493    /// Returns a mutable iterator over the [`TypeRegistration`]s of the registered
494    /// types.
495    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TypeRegistration> {
496        self.registrations.values_mut()
497    }
498
499    /// Checks to see if the [`TypeData`] of type `T` is associated with each registered type,
500    /// returning a ([`TypeRegistration`], [`TypeData`]) iterator for all entries where data of that type was found.
501    pub fn iter_with_data<T: TypeData>(&self) -> impl Iterator<Item = (&TypeRegistration, &T)> {
502        self.registrations.values().filter_map(|item| {
503            let type_data = item.data::<T>();
504            type_data.map(|data| (item, data))
505        })
506    }
507}
508
509impl TypeRegistryArc {
510    /// Takes a read lock on the underlying [`TypeRegistry`].
511    pub fn read(&self) -> RwLockReadGuard<'_, TypeRegistry> {
512        self.internal.read().unwrap_or_else(PoisonError::into_inner)
513    }
514
515    /// Takes a write lock on the underlying [`TypeRegistry`].
516    pub fn write(&self) -> RwLockWriteGuard<'_, TypeRegistry> {
517        self.internal
518            .write()
519            .unwrap_or_else(PoisonError::into_inner)
520    }
521}
522
523/// Runtime storage for type metadata, registered into the [`TypeRegistry`].
524///
525/// An instance of `TypeRegistration` can be created using the [`TypeRegistration::of`] method,
526/// but is more often automatically generated using [`#[derive(Reflect)]`](derive@crate::Reflect) which itself generates
527/// an implementation of the [`GetTypeRegistration`] trait.
528///
529/// Along with the type's [`TypeInfo`],
530/// this struct also contains a type's registered [`TypeData`].
531///
532/// See the [crate-level documentation] for more information on type registration.
533///
534/// # Example
535///
536/// ```
537/// # use bevy_reflect::{TypeRegistration, std_traits::ReflectDefault, FromType};
538/// let mut registration = TypeRegistration::of::<Option<String>>();
539///
540/// assert_eq!("core::option::Option<alloc::string::String>", registration.type_info().type_path());
541/// assert_eq!("Option<String>", registration.type_info().type_path_table().short_path());
542///
543/// registration.insert::<ReflectDefault>(FromType::<Option<String>>::from_type());
544/// assert!(registration.data::<ReflectDefault>().is_some())
545/// ```
546///
547/// [crate-level documentation]: crate
548pub struct TypeRegistration {
549    data: TypeIdMap<Box<dyn TypeData>>,
550    type_info: &'static TypeInfo,
551}
552
553impl Debug for TypeRegistration {
554    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
555        f.debug_struct("TypeRegistration")
556            .field("type_info", &self.type_info)
557            .finish()
558    }
559}
560
561impl TypeRegistration {
562    /// Creates type registration information for `T`.
563    pub fn of<T: Reflect + Typed + TypePath>() -> Self {
564        Self {
565            data: Default::default(),
566            type_info: T::type_info(),
567        }
568    }
569
570    /// Returns the [`TypeId`] of the type.
571    #[inline]
572    pub fn type_id(&self) -> TypeId {
573        self.type_info.type_id()
574    }
575
576    /// Returns a reference to the registration's [`TypeInfo`]
577    pub fn type_info(&self) -> &'static TypeInfo {
578        self.type_info
579    }
580
581    /// Inserts an instance of `T` into this registration's [type data].
582    ///
583    /// If another instance of `T` was previously inserted, it is replaced.
584    ///
585    /// [type data]: TypeData
586    pub fn insert<T: TypeData>(&mut self, data: T) {
587        self.data.insert(TypeId::of::<T>(), Box::new(data));
588    }
589
590    /// Returns a reference to the value of type `T` in this registration's
591    /// [type data].
592    ///
593    /// Returns `None` if no such value exists.
594    ///
595    /// For a dynamic version of this method, see [`data_by_id`].
596    ///
597    /// [type data]: TypeData
598    /// [`data_by_id`]: Self::data_by_id
599    pub fn data<T: TypeData>(&self) -> Option<&T> {
600        self.data
601            .get(&TypeId::of::<T>())
602            .and_then(|value| value.downcast_ref())
603    }
604
605    /// Returns a reference to the value with the given [`TypeId`] in this registration's
606    /// [type data].
607    ///
608    /// Returns `None` if no such value exists.
609    ///
610    /// For a static version of this method, see [`data`].
611    ///
612    /// [type data]: TypeData
613    /// [`data`]: Self::data
614    pub fn data_by_id(&self, type_id: TypeId) -> Option<&dyn TypeData> {
615        self.data.get(&type_id).map(Deref::deref)
616    }
617
618    /// Returns a mutable reference to the value of type `T` in this registration's
619    /// [type data].
620    ///
621    /// Returns `None` if no such value exists.
622    ///
623    /// For a dynamic version of this method, see [`data_mut_by_id`].
624    ///
625    /// [type data]: TypeData
626    /// [`data_mut_by_id`]: Self::data_mut_by_id
627    pub fn data_mut<T: TypeData>(&mut self) -> Option<&mut T> {
628        self.data
629            .get_mut(&TypeId::of::<T>())
630            .and_then(|value| value.downcast_mut())
631    }
632
633    /// Returns a mutable reference to the value with the given [`TypeId`] in this registration's
634    /// [type data].
635    ///
636    /// Returns `None` if no such value exists.
637    ///
638    /// For a static version of this method, see [`data_mut`].
639    ///
640    /// [type data]: TypeData
641    /// [`data_mut`]: Self::data_mut
642    pub fn data_mut_by_id(&mut self, type_id: TypeId) -> Option<&mut dyn TypeData> {
643        self.data.get_mut(&type_id).map(DerefMut::deref_mut)
644    }
645
646    /// Returns true if this registration contains the given [type data].
647    ///
648    /// For a dynamic version of this method, see [`contains_by_id`].
649    ///
650    /// [type data]: TypeData
651    /// [`contains_by_id`]: Self::contains_by_id
652    pub fn contains<T: TypeData>(&self) -> bool {
653        self.data.contains_key(&TypeId::of::<T>())
654    }
655
656    /// Returns true if this registration contains the given [type data] with [`TypeId`].
657    ///
658    /// For a static version of this method, see [`contains`].
659    ///
660    /// [type data]: TypeData
661    /// [`contains`]: Self::contains
662    pub fn contains_by_id(&self, type_id: TypeId) -> bool {
663        self.data.contains_key(&type_id)
664    }
665
666    /// The total count of [type data] in this registration.
667    ///
668    /// [type data]: TypeData
669    pub fn len(&self) -> usize {
670        self.data.len()
671    }
672
673    /// Returns true if this registration has no [type data].
674    ///
675    /// [type data]: TypeData
676    pub fn is_empty(&self) -> bool {
677        self.data.is_empty()
678    }
679
680    /// Returns an iterator over all [type data] in this registration.
681    ///
682    /// The iterator yields a tuple of the [`TypeId`] and its corresponding type data.
683    ///
684    /// [type data]: TypeData
685    pub fn iter(&self) -> impl ExactSizeIterator<Item = (TypeId, &dyn TypeData)> {
686        self.data.iter().map(|(id, data)| (*id, data.deref()))
687    }
688
689    /// Returns a mutable iterator over all [type data] in this registration.
690    ///
691    /// The iterator yields a tuple of the [`TypeId`] and its corresponding type data.
692    ///
693    /// [type data]: TypeData
694    pub fn iter_mut(&mut self) -> impl ExactSizeIterator<Item = (TypeId, &mut dyn TypeData)> {
695        self.data
696            .iter_mut()
697            .map(|(id, data)| (*id, data.deref_mut()))
698    }
699}
700
701impl Clone for TypeRegistration {
702    fn clone(&self) -> Self {
703        let mut data = TypeIdMap::default();
704        for (id, type_data) in &self.data {
705            data.insert(*id, (*type_data).clone_type_data());
706        }
707
708        TypeRegistration {
709            data,
710            type_info: self.type_info,
711        }
712    }
713}
714
715/// A trait used to type-erase type metadata.
716///
717/// Type data can be registered to the [`TypeRegistry`] and stored on a type's [`TypeRegistration`].
718///
719/// While type data is often generated using the [`#[reflect_trait]`](crate::reflect_trait) macro,
720/// almost any type that implements [`Clone`] can be considered "type data".
721/// This is because it has a blanket implementation over all `T` where `T: Clone + Send + Sync + 'static`.
722///
723/// See the [crate-level documentation] for more information on type data and type registration.
724///
725/// [crate-level documentation]: crate
726pub trait TypeData: Downcast + Send + Sync {
727    /// Creates a type-erased clone of this value.
728    fn clone_type_data(&self) -> Box<dyn TypeData>;
729}
730
731impl_downcast!(TypeData);
732
733impl<T: 'static + Send + Sync> TypeData for T
734where
735    T: Clone,
736{
737    fn clone_type_data(&self) -> Box<dyn TypeData> {
738        Box::new(self.clone())
739    }
740}
741
742/// Trait used to generate [`TypeData`] for trait reflection.
743///
744/// This is used by the `#[derive(Reflect)]` macro to generate an implementation
745/// of [`TypeData`] to pass to [`TypeRegistration::insert`].
746pub trait FromType<T> {
747    /// Creates an instance of `Self` for type `T`.
748    fn from_type() -> Self;
749}
750
751/// A struct used to serialize reflected instances of a type.
752///
753/// A `ReflectSerialize` for type `T` can be obtained via
754/// [`FromType::from_type`].
755#[derive(Clone)]
756pub struct ReflectSerialize {
757    get_serializable: fn(value: &dyn Reflect) -> Serializable,
758}
759
760impl<T: TypePath + FromReflect + erased_serde::Serialize> FromType<T> for ReflectSerialize {
761    fn from_type() -> Self {
762        ReflectSerialize {
763            get_serializable: |value| {
764                value
765                    .downcast_ref::<T>()
766                    .map(|value| Serializable::Borrowed(value))
767                    .or_else(|| T::from_reflect(value.as_partial_reflect()).map(|value| Serializable::Owned(Box::new(value))))
768                    .unwrap_or_else(|| {
769                        panic!(
770                            "FromReflect::from_reflect failed when called on type `{}` with this value: {value:?}",
771                            T::type_path(),
772                        );
773                    })
774            },
775        }
776    }
777}
778
779impl ReflectSerialize {
780    /// Turn the value into a serializable representation
781    pub fn get_serializable<'a>(&self, value: &'a dyn Reflect) -> Serializable<'a> {
782        (self.get_serializable)(value)
783    }
784}
785
786/// A struct used to deserialize reflected instances of a type.
787///
788/// A `ReflectDeserialize` for type `T` can be obtained via
789/// [`FromType::from_type`].
790#[derive(Clone)]
791pub struct ReflectDeserialize {
792    /// Function used by [`ReflectDeserialize::deserialize`] to
793    /// perform deserialization.
794    pub func: fn(
795        deserializer: &mut dyn erased_serde::Deserializer,
796    ) -> Result<Box<dyn Reflect>, erased_serde::Error>,
797}
798
799impl ReflectDeserialize {
800    /// Deserializes a reflected value.
801    ///
802    /// The underlying type of the reflected value, and thus the expected
803    /// structure of the serialized data, is determined by the type used to
804    /// construct this `ReflectDeserialize` value.
805    pub fn deserialize<'de, D>(&self, deserializer: D) -> Result<Box<dyn Reflect>, D::Error>
806    where
807        D: serde::Deserializer<'de>,
808    {
809        let mut erased = <dyn erased_serde::Deserializer>::erase(deserializer);
810        (self.func)(&mut erased)
811            .map_err(<<D as serde::Deserializer<'de>>::Error as serde::de::Error>::custom)
812    }
813}
814
815impl<T: for<'a> Deserialize<'a> + Reflect> FromType<T> for ReflectDeserialize {
816    fn from_type() -> Self {
817        ReflectDeserialize {
818            func: |deserializer| Ok(Box::new(T::deserialize(deserializer)?)),
819        }
820    }
821}
822
823/// [`Reflect`] values are commonly used in situations where the actual types of values
824/// are not known at runtime. In such situations you might have access to a `*const ()` pointer
825/// that you know implements [`Reflect`], but have no way of turning it into a `&dyn Reflect`.
826///
827/// This is where [`ReflectFromPtr`] comes in, when creating a [`ReflectFromPtr`] for a given type `T: Reflect`.
828/// Internally, this saves a concrete function `*const T -> const dyn Reflect` which lets you create a trait object of [`Reflect`]
829/// from a pointer.
830///
831/// # Example
832/// ```
833/// use bevy_reflect::{TypeRegistry, Reflect, ReflectFromPtr};
834/// use bevy_ptr::Ptr;
835/// use core::ptr::NonNull;
836///
837/// #[derive(Reflect)]
838/// struct Reflected(String);
839///
840/// let mut type_registry = TypeRegistry::default();
841/// type_registry.register::<Reflected>();
842///
843/// let mut value = Reflected("Hello world!".to_string());
844/// let value = Ptr::from(&value);
845///
846/// let reflect_data = type_registry.get(core::any::TypeId::of::<Reflected>()).unwrap();
847/// let reflect_from_ptr = reflect_data.data::<ReflectFromPtr>().unwrap();
848/// // SAFE: `value` is of type `Reflected`, which the `ReflectFromPtr` was created for
849/// let value = unsafe { reflect_from_ptr.as_reflect(value) };
850///
851/// assert_eq!(value.downcast_ref::<Reflected>().unwrap().0, "Hello world!");
852/// ```
853#[derive(Clone)]
854pub struct ReflectFromPtr {
855    type_id: TypeId,
856    from_ptr: unsafe fn(Ptr) -> &dyn Reflect,
857    from_ptr_mut: unsafe fn(PtrMut) -> &mut dyn Reflect,
858}
859
860#[expect(
861    unsafe_code,
862    reason = "We must interact with pointers here, which are inherently unsafe."
863)]
864impl ReflectFromPtr {
865    /// Returns the [`TypeId`] that the [`ReflectFromPtr`] was constructed for.
866    pub fn type_id(&self) -> TypeId {
867        self.type_id
868    }
869
870    /// Convert `Ptr` into `&dyn Reflect`.
871    ///
872    /// # Safety
873    ///
874    /// `val` must be a pointer to value of the type that the [`ReflectFromPtr`] was constructed for.
875    /// This can be verified by checking that the type id returned by [`ReflectFromPtr::type_id`] is the expected one.
876    pub unsafe fn as_reflect<'a>(&self, val: Ptr<'a>) -> &'a dyn Reflect {
877        // SAFETY: contract uphold by the caller.
878        unsafe { (self.from_ptr)(val) }
879    }
880
881    /// Convert `PtrMut` into `&mut dyn Reflect`.
882    ///
883    /// # Safety
884    ///
885    /// `val` must be a pointer to a value of the type that the [`ReflectFromPtr`] was constructed for
886    /// This can be verified by checking that the type id returned by [`ReflectFromPtr::type_id`] is the expected one.
887    pub unsafe fn as_reflect_mut<'a>(&self, val: PtrMut<'a>) -> &'a mut dyn Reflect {
888        // SAFETY: contract uphold by the caller.
889        unsafe { (self.from_ptr_mut)(val) }
890    }
891    /// Get a function pointer to turn a `Ptr` into `&dyn Reflect` for
892    /// the type this [`ReflectFromPtr`] was constructed for.
893    ///
894    /// # Safety
895    ///
896    /// When calling the unsafe function returned by this method you must ensure that:
897    /// - The input `Ptr` points to the `Reflect` type this `ReflectFromPtr`
898    ///   was constructed for.
899    pub fn from_ptr(&self) -> unsafe fn(Ptr) -> &dyn Reflect {
900        self.from_ptr
901    }
902    /// Get a function pointer to turn a `PtrMut` into `&mut dyn Reflect` for
903    /// the type this [`ReflectFromPtr`] was constructed for.
904    ///
905    /// # Safety
906    ///
907    /// When calling the unsafe function returned by this method you must ensure that:
908    /// - The input `PtrMut` points to the `Reflect` type this `ReflectFromPtr`
909    ///   was constructed for.
910    pub fn from_ptr_mut(&self) -> unsafe fn(PtrMut) -> &mut dyn Reflect {
911        self.from_ptr_mut
912    }
913}
914
915#[expect(
916    unsafe_code,
917    reason = "We must interact with pointers here, which are inherently unsafe."
918)]
919impl<T: Reflect> FromType<T> for ReflectFromPtr {
920    fn from_type() -> Self {
921        ReflectFromPtr {
922            type_id: TypeId::of::<T>(),
923            from_ptr: |ptr| {
924                // SAFETY: `from_ptr_mut` is either called in `ReflectFromPtr::as_reflect`
925                // or returned by `ReflectFromPtr::from_ptr`, both lay out the invariants
926                // required by `deref`
927                unsafe { ptr.deref::<T>() as &dyn Reflect }
928            },
929            from_ptr_mut: |ptr| {
930                // SAFETY: same as above, but for `as_reflect_mut`, `from_ptr_mut` and `deref_mut`.
931                unsafe { ptr.deref_mut::<T>() as &mut dyn Reflect }
932            },
933        }
934    }
935}
936
937#[cfg(test)]
938#[expect(
939    unsafe_code,
940    reason = "We must interact with pointers here, which are inherently unsafe."
941)]
942mod test {
943    use super::*;
944
945    #[test]
946    fn test_reflect_from_ptr() {
947        #[derive(Reflect)]
948        struct Foo {
949            a: f32,
950        }
951
952        let foo_registration = <Foo as GetTypeRegistration>::get_type_registration();
953        let reflect_from_ptr = foo_registration.data::<ReflectFromPtr>().unwrap();
954
955        // not required in this situation because we no nobody messed with the TypeRegistry,
956        // but in the general case somebody could have replaced the ReflectFromPtr with an
957        // instance for another type, so then we'd need to check that the type is the expected one
958        assert_eq!(reflect_from_ptr.type_id(), TypeId::of::<Foo>());
959
960        let mut value = Foo { a: 1.0 };
961        {
962            let value = PtrMut::from(&mut value);
963            // SAFETY: reflect_from_ptr was constructed for the correct type
964            let dyn_reflect = unsafe { reflect_from_ptr.as_reflect_mut(value) };
965            match dyn_reflect.reflect_mut() {
966                bevy_reflect::ReflectMut::Struct(strukt) => {
967                    strukt.field_mut("a").unwrap().apply(&2.0f32);
968                }
969                _ => panic!("invalid reflection"),
970            }
971        }
972
973        {
974            // SAFETY: reflect_from_ptr was constructed for the correct type
975            let dyn_reflect = unsafe { reflect_from_ptr.as_reflect(Ptr::from(&value)) };
976            match dyn_reflect.reflect_ref() {
977                bevy_reflect::ReflectRef::Struct(strukt) => {
978                    let a = strukt
979                        .field("a")
980                        .unwrap()
981                        .try_downcast_ref::<f32>()
982                        .unwrap();
983                    assert_eq!(*a, 2.0);
984                }
985                _ => panic!("invalid reflection"),
986            }
987        }
988    }
989
990    #[test]
991    fn type_data_iter() {
992        #[derive(Reflect)]
993        struct Foo;
994
995        #[derive(Clone)]
996        struct DataA(i32);
997
998        let mut registration = TypeRegistration::of::<Foo>();
999        registration.insert(DataA(123));
1000
1001        let mut iter = registration.iter();
1002
1003        let (id, data) = iter.next().unwrap();
1004        assert_eq!(id, TypeId::of::<DataA>());
1005        assert_eq!(data.downcast_ref::<DataA>().unwrap().0, 123);
1006
1007        assert!(iter.next().is_none());
1008    }
1009
1010    #[test]
1011    fn type_data_iter_mut() {
1012        #[derive(Reflect)]
1013        struct Foo;
1014
1015        #[derive(Clone)]
1016        struct DataA(i32);
1017
1018        let mut registration = TypeRegistration::of::<Foo>();
1019        registration.insert(DataA(123));
1020
1021        {
1022            let mut iter = registration.iter_mut();
1023
1024            let (_, data) = iter.next().unwrap();
1025            data.downcast_mut::<DataA>().unwrap().0 = 456;
1026
1027            assert!(iter.next().is_none());
1028        }
1029
1030        let data = registration.data::<DataA>().unwrap();
1031        assert_eq!(data.0, 456);
1032    }
1033}