1use core::{
4 any::TypeId,
5 ops::{Deref, DerefMut},
6};
7
8use crate::{resource::Resource, world::World};
9use bevy_reflect::{
10 std_traits::ReflectDefault, PartialReflect, Reflect, ReflectFromReflect, TypePath,
11 TypeRegistry, TypeRegistryArc,
12};
13
14mod bundle;
15mod component;
16mod entity_commands;
17mod from_world;
18mod map_entities;
19mod resource;
20
21pub use bundle::{ReflectBundle, ReflectBundleFns};
22pub use component::{ReflectComponent, ReflectComponentFns};
23pub use entity_commands::ReflectCommandExt;
24pub use from_world::{ReflectFromWorld, ReflectFromWorldFns};
25pub use map_entities::ReflectMapEntities;
26pub use resource::{ReflectResource, ReflectResourceFns};
27
28#[derive(Resource, Clone, Default)]
31pub struct AppTypeRegistry(pub TypeRegistryArc);
32
33impl Deref for AppTypeRegistry {
34 type Target = TypeRegistryArc;
35
36 #[inline]
37 fn deref(&self) -> &Self::Target {
38 &self.0
39 }
40}
41
42impl DerefMut for AppTypeRegistry {
43 #[inline]
44 fn deref_mut(&mut self) -> &mut Self::Target {
45 &mut self.0
46 }
47}
48
49#[cfg(feature = "reflect_functions")]
54#[derive(Resource, Clone, Default)]
55pub struct AppFunctionRegistry(pub bevy_reflect::func::FunctionRegistryArc);
56
57#[cfg(feature = "reflect_functions")]
58impl Deref for AppFunctionRegistry {
59 type Target = bevy_reflect::func::FunctionRegistryArc;
60
61 #[inline]
62 fn deref(&self) -> &Self::Target {
63 &self.0
64 }
65}
66
67#[cfg(feature = "reflect_functions")]
68impl DerefMut for AppFunctionRegistry {
69 #[inline]
70 fn deref_mut(&mut self) -> &mut Self::Target {
71 &mut self.0
72 }
73}
74
75pub fn from_reflect_with_fallback<T: Reflect + TypePath>(
92 reflected: &dyn PartialReflect,
93 world: &mut World,
94 registry: &TypeRegistry,
95) -> T {
96 fn different_type_error<T: TypePath>(reflected: &str) -> ! {
97 panic!(
98 "The registration for the reflected `{}` trait for the type `{}` produced \
99 a value of a different type",
100 reflected,
101 T::type_path(),
102 );
103 }
104
105 if let Some(reflect_from_reflect) =
108 registry.get_type_data::<ReflectFromReflect>(TypeId::of::<T>())
109 {
110 if let Some(value) = reflect_from_reflect.from_reflect(reflected) {
112 return value
113 .take::<T>()
114 .unwrap_or_else(|_| different_type_error::<T>("FromReflect"));
115 }
116 }
117
118 let mut value = if let Some(reflect_default) =
120 registry.get_type_data::<ReflectDefault>(TypeId::of::<T>())
121 {
122 reflect_default
123 .default()
124 .take::<T>()
125 .unwrap_or_else(|_| different_type_error::<T>("Default"))
126 } else if let Some(reflect_from_world) =
127 registry.get_type_data::<ReflectFromWorld>(TypeId::of::<T>())
128 {
129 reflect_from_world
130 .from_world(world)
131 .take::<T>()
132 .unwrap_or_else(|_| different_type_error::<T>("FromWorld"))
133 } else {
134 panic!(
135 "Couldn't create an instance of `{}` using the reflected `FromReflect`, \
136 `Default` or `FromWorld` traits. Are you perhaps missing a `#[reflect(Default)]` \
137 or `#[reflect(FromWorld)]`?",
138 core::any::type_name::<T>(),
140 );
141 };
142
143 value.apply(reflected);
144 value
145}