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