bevy_reflect/
type_registry.rs

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