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