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