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