Skip to main content

cu29_runtime/
reflect.rs

1//! Runtime reflection helpers built on top of `bevy_reflect`.
2
3#[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
12#[cfg(feature = "reflect")]
13pub trait ReflectTypePath: TypePath {}
14
15#[cfg(feature = "reflect")]
16impl<T: TypePath> ReflectTypePath for T {}
17
18#[cfg(not(feature = "reflect"))]
19pub use cu29_reflect_derive::Reflect;
20
21#[cfg(not(feature = "reflect"))]
22pub trait Reflect: 'static {}
23
24#[cfg(not(feature = "reflect"))]
25impl<T: 'static> Reflect for T {}
26
27#[cfg(not(feature = "reflect"))]
28pub trait TypePath {
29    fn type_path() -> &'static str {
30        core::any::type_name::<Self>()
31    }
32
33    fn short_type_path() -> &'static str {
34        core::any::type_name::<Self>()
35    }
36
37    fn type_ident() -> Option<&'static str> {
38        None
39    }
40
41    fn crate_name() -> Option<&'static str> {
42        None
43    }
44
45    fn module_path() -> Option<&'static str> {
46        None
47    }
48}
49
50#[cfg(not(feature = "reflect"))]
51pub trait ReflectTypePath {}
52
53#[cfg(not(feature = "reflect"))]
54impl<T> ReflectTypePath for T {}
55
56#[cfg(not(feature = "reflect"))]
57pub trait GetTypeRegistration {}
58
59#[cfg(not(feature = "reflect"))]
60impl<T> GetTypeRegistration for T {}
61
62#[cfg(not(feature = "reflect"))]
63#[derive(Debug, Default, Clone, Copy)]
64pub struct TypeInfo;
65
66#[cfg(not(feature = "reflect"))]
67#[derive(Debug, Default)]
68pub struct TypeRegistry;
69
70#[cfg(not(feature = "reflect"))]
71impl TypeRegistry {
72    pub fn register<T>(&mut self) {
73        let _ = core::any::type_name::<T>();
74    }
75}
76
77/// Runtime task-reflect contract exposed by generated Copper applications.
78pub trait ReflectTaskIntrospection {
79    /// Returns a reflected immutable task instance for the given task id.
80    fn reflect_task(&self, task_id: &str) -> Option<&dyn Reflect>;
81
82    /// Returns a reflected mutable task instance for the given task id.
83    fn reflect_task_mut(&mut self, task_id: &str) -> Option<&mut dyn Reflect>;
84
85    /// Registers reflected schema types for this mission's app (tasks, messages, bridges).
86    fn register_reflect_types(_registry: &mut TypeRegistry) {}
87}
88
89/// Dumps a stable, human-readable schema snapshot for the registered reflected types.
90///
91/// This is intended for diagnostics, examples, and contract validation.
92#[cfg(feature = "reflect")]
93pub fn dump_type_registry_schema(registry: &TypeRegistry) -> String {
94    let mut entries: Vec<(&'static str, String)> = registry
95        .iter()
96        .map(|registration| {
97            let info = registration.type_info();
98            (info.type_path(), format!("{info:#?}"))
99        })
100        .collect();
101
102    entries.sort_by(|(left, _), (right, _)| left.cmp(right));
103
104    let mut dump = String::new();
105    for (type_path, info_dump) in entries {
106        dump.push_str("=== ");
107        dump.push_str(type_path);
108        dump.push_str(" ===\n");
109        dump.push_str(&info_dump);
110        dump.push('\n');
111    }
112    dump
113}
114
115#[cfg(not(feature = "reflect"))]
116pub fn dump_type_registry_schema(_registry: &TypeRegistry) -> String {
117    String::new()
118}