1use std::any::TypeId;
4use std::ops::{Deref, DerefMut};
5
6use crate as bevy_ecs;
7use crate::{system::Resource, world::World};
8use bevy_reflect::std_traits::ReflectDefault;
9use bevy_reflect::{Reflect, ReflectFromReflect, TypeRegistry, TypeRegistryArc};
10
11mod bundle;
12mod component;
13mod entity_commands;
14mod from_world;
15mod map_entities;
16mod resource;
17
18pub use bundle::{ReflectBundle, ReflectBundleFns};
19pub use component::{ReflectComponent, ReflectComponentFns};
20pub use entity_commands::ReflectCommandExt;
21pub use from_world::{ReflectFromWorld, ReflectFromWorldFns};
22pub use map_entities::{ReflectMapEntities, ReflectMapEntitiesResource};
23pub use resource::{ReflectResource, ReflectResourceFns};
24
25#[derive(Resource, Clone, Default)]
28pub struct AppTypeRegistry(pub TypeRegistryArc);
29
30impl Deref for AppTypeRegistry {
31 type Target = TypeRegistryArc;
32
33 #[inline]
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37}
38
39impl DerefMut for AppTypeRegistry {
40 #[inline]
41 fn deref_mut(&mut self) -> &mut Self::Target {
42 &mut self.0
43 }
44}
45
46fn from_reflect_with_fallback<T: Reflect>(
63 reflected: &dyn Reflect,
64 world: &mut World,
65 registry: &TypeRegistry,
66) -> T {
67 fn different_type_error<T>(reflected: &str) -> ! {
68 panic!(
69 "The registration for the reflected `{}` trait for the type `{}` produced \
70 a value of a different type",
71 reflected,
72 std::any::type_name::<T>(),
74 );
75 }
76
77 if let Some(reflect_from_reflect) =
80 registry.get_type_data::<ReflectFromReflect>(TypeId::of::<T>())
81 {
82 if let Some(value) = reflect_from_reflect.from_reflect(reflected) {
84 return value
85 .take::<T>()
86 .unwrap_or_else(|_| different_type_error::<T>("FromReflect"));
87 }
88 }
89
90 let mut value = if let Some(reflect_default) =
92 registry.get_type_data::<ReflectDefault>(TypeId::of::<T>())
93 {
94 reflect_default
95 .default()
96 .take::<T>()
97 .unwrap_or_else(|_| different_type_error::<T>("Default"))
98 } else if let Some(reflect_from_world) =
99 registry.get_type_data::<ReflectFromWorld>(TypeId::of::<T>())
100 {
101 reflect_from_world
102 .from_world(world)
103 .take::<T>()
104 .unwrap_or_else(|_| different_type_error::<T>("FromWorld"))
105 } else {
106 panic!(
107 "Couldn't create an instance of `{}` using the reflected `FromReflect`, \
108 `Default` or `FromWorld` traits. Are you perhaps missing a `#[reflect(Default)]` \
109 or `#[reflect(FromWorld)]`?",
110 std::any::type_name::<T>(),
112 );
113 };
114
115 value.apply(reflected);
116 value
117}