1#[cfg(feature = "reflect")]
4use alloc::format;
5use alloc::string::String;
6#[cfg(feature = "reflect")]
7use alloc::vec::Vec;
8
9#[cfg(feature = "reflect")]
10pub use bevy_reflect::*;
11#[cfg(feature = "reflect")]
12pub use bevy_reflect::{
13 array::{Array, ArrayInfo},
14 enums::{Enum, EnumInfo, VariantInfo, VariantType},
15 list::{List, ListInfo},
16 map::{Map, MapInfo},
17 set::{Set, SetInfo},
18 structs::{Struct, StructInfo},
19 tuple::{Tuple, TupleInfo},
20 tuple_struct::{TupleStruct, TupleStructInfo},
21};
22
23#[cfg(feature = "reflect")]
24pub trait ReflectTypePath: TypePath {}
25
26#[cfg(feature = "reflect")]
27impl<T: TypePath> ReflectTypePath for T {}
28
29#[cfg(not(feature = "reflect"))]
30pub use cu29_reflect_derive::Reflect;
31
32#[cfg(not(feature = "reflect"))]
33pub trait Reflect: 'static {}
34
35#[cfg(not(feature = "reflect"))]
36impl<T: 'static> Reflect for T {}
37
38#[cfg(not(feature = "reflect"))]
39pub trait TypePath {
40 fn type_path() -> &'static str {
41 core::any::type_name::<Self>()
42 }
43
44 fn short_type_path() -> &'static str {
45 core::any::type_name::<Self>()
46 }
47
48 fn type_ident() -> Option<&'static str> {
49 None
50 }
51
52 fn crate_name() -> Option<&'static str> {
53 None
54 }
55
56 fn module_path() -> Option<&'static str> {
57 None
58 }
59}
60
61#[doc(hidden)]
63#[inline]
64#[cfg(feature = "reflect")]
65pub fn __payload_type_path<T: TypePath>() -> &'static str {
66 T::type_path()
67}
68
69#[doc(hidden)]
71#[inline]
72#[cfg(not(feature = "reflect"))]
73pub fn __payload_type_path<T>() -> &'static str {
74 core::any::type_name::<T>()
75}
76
77#[cfg(not(feature = "reflect"))]
78macro_rules! impl_type_path_for_primitives {
79 ($($ty:ty),* $(,)?) => {
80 $(impl TypePath for $ty {})*
81 };
82}
83
84#[cfg(not(feature = "reflect"))]
85impl_type_path_for_primitives!(
86 (),
87 bool,
88 char,
89 str,
90 u8,
91 u16,
92 u32,
93 u64,
94 u128,
95 usize,
96 i8,
97 i16,
98 i32,
99 i64,
100 i128,
101 isize,
102 f32,
103 f64,
104);
105
106#[cfg(not(feature = "reflect"))]
107pub trait ReflectTypePath {}
108
109#[cfg(not(feature = "reflect"))]
110impl<T> ReflectTypePath for T {}
111
112#[cfg(not(feature = "reflect"))]
113pub trait GetTypeRegistration {}
114
115#[cfg(not(feature = "reflect"))]
116impl<T> GetTypeRegistration for T {}
117
118#[cfg(not(feature = "reflect"))]
119#[derive(Debug, Default, Clone, Copy)]
120pub struct TypeInfo;
121
122#[cfg(not(feature = "reflect"))]
123#[derive(Debug, Default)]
124pub struct TypeRegistry;
125
126#[cfg(not(feature = "reflect"))]
127impl TypeRegistry {
128 pub fn register<T>(&mut self) {
129 let _ = core::any::type_name::<T>();
130 }
131}
132
133pub trait ReflectTaskIntrospection {
135 fn reflect_task(&self, task_id: &str) -> Option<&dyn Reflect>;
137
138 fn reflect_task_mut(&mut self, task_id: &str) -> Option<&mut dyn Reflect>;
140
141 fn register_reflect_types(_registry: &mut TypeRegistry) {}
143
144 fn debug_state_type_path(_task_id: &str) -> Option<&'static str> {
146 None
147 }
148
149 fn with_debug_state<R>(&self, _task_id: &str, _f: impl FnOnce(&dyn Reflect) -> R) -> Option<R> {
151 None
152 }
153}
154
155#[cfg(feature = "reflect")]
159pub fn dump_type_registry_schema(registry: &TypeRegistry) -> String {
160 let mut entries: Vec<(&'static str, String)> = registry
161 .iter()
162 .map(|registration| {
163 let info = registration.type_info();
164 (info.type_path(), format!("{info:#?}"))
165 })
166 .collect();
167
168 entries.sort_by_key(|(left, _)| *left);
169
170 let mut dump = String::new();
171 for (type_path, info_dump) in entries {
172 dump.push_str("=== ");
173 dump.push_str(type_path);
174 dump.push_str(" ===\n");
175 dump.push_str(&info_dump);
176 dump.push('\n');
177 }
178 dump
179}
180
181#[cfg(not(feature = "reflect"))]
182pub fn dump_type_registry_schema(_registry: &TypeRegistry) -> String {
183 String::new()
184}
185
186#[cfg(all(test, not(feature = "reflect")))]
187mod tests {
188 use super::{__payload_type_path, TypePath};
189
190 struct PayloadWithoutTypePath;
191
192 fn assert_type_path<T: TypePath + ?Sized>() {}
193
194 #[test]
195 fn unit_and_primitive_type_paths_exist_without_reflect() {
196 assert_type_path::<()>();
197 assert_type_path::<i8>();
198 }
199
200 #[test]
201 fn payload_type_path_does_not_require_type_path_without_reflect() {
202 assert_eq!(
203 __payload_type_path::<PayloadWithoutTypePath>(),
204 core::any::type_name::<PayloadWithoutTypePath>()
205 );
206 }
207}