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