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#[cfg(not(feature = "reflect"))]
62macro_rules! impl_type_path_for_primitives {
63 ($($ty:ty),* $(,)?) => {
64 $(impl TypePath for $ty {})*
65 };
66}
67
68#[cfg(not(feature = "reflect"))]
69impl_type_path_for_primitives!(
70 (),
71 bool,
72 char,
73 str,
74 u8,
75 u16,
76 u32,
77 u64,
78 u128,
79 usize,
80 i8,
81 i16,
82 i32,
83 i64,
84 i128,
85 isize,
86 f32,
87 f64,
88);
89
90#[cfg(not(feature = "reflect"))]
91pub trait ReflectTypePath {}
92
93#[cfg(not(feature = "reflect"))]
94impl<T> ReflectTypePath for T {}
95
96#[cfg(not(feature = "reflect"))]
97pub trait GetTypeRegistration {}
98
99#[cfg(not(feature = "reflect"))]
100impl<T> GetTypeRegistration for T {}
101
102#[cfg(not(feature = "reflect"))]
103#[derive(Debug, Default, Clone, Copy)]
104pub struct TypeInfo;
105
106#[cfg(not(feature = "reflect"))]
107#[derive(Debug, Default)]
108pub struct TypeRegistry;
109
110#[cfg(not(feature = "reflect"))]
111impl TypeRegistry {
112 pub fn register<T>(&mut self) {
113 let _ = core::any::type_name::<T>();
114 }
115}
116
117pub trait ReflectTaskIntrospection {
119 fn reflect_task(&self, task_id: &str) -> Option<&dyn Reflect>;
121
122 fn reflect_task_mut(&mut self, task_id: &str) -> Option<&mut dyn Reflect>;
124
125 fn register_reflect_types(_registry: &mut TypeRegistry) {}
127
128 fn debug_state_type_path(_task_id: &str) -> Option<&'static str> {
130 None
131 }
132
133 fn with_debug_state<R>(&self, _task_id: &str, _f: impl FnOnce(&dyn Reflect) -> R) -> Option<R> {
135 None
136 }
137}
138
139#[cfg(feature = "reflect")]
143pub fn dump_type_registry_schema(registry: &TypeRegistry) -> String {
144 let mut entries: Vec<(&'static str, String)> = registry
145 .iter()
146 .map(|registration| {
147 let info = registration.type_info();
148 (info.type_path(), format!("{info:#?}"))
149 })
150 .collect();
151
152 entries.sort_by_key(|(left, _)| *left);
153
154 let mut dump = String::new();
155 for (type_path, info_dump) in entries {
156 dump.push_str("=== ");
157 dump.push_str(type_path);
158 dump.push_str(" ===\n");
159 dump.push_str(&info_dump);
160 dump.push('\n');
161 }
162 dump
163}
164
165#[cfg(not(feature = "reflect"))]
166pub fn dump_type_registry_schema(_registry: &TypeRegistry) -> String {
167 String::new()
168}
169
170#[cfg(all(test, not(feature = "reflect")))]
171mod tests {
172 use super::TypePath;
173
174 fn assert_type_path<T: TypePath + ?Sized>() {}
175
176 #[test]
177 fn unit_and_primitive_type_paths_exist_without_reflect() {
178 assert_type_path::<()>();
179 assert_type_path::<i8>();
180 }
181}