unity_mirror_rs/unity_engine/
mono_behaviour_factory.rs

1use crate::commons::Object;
2use crate::commons::RevelArc;
3use crate::commons::RevelWeak;
4use crate::metadata_settings::Settings;
5use crate::unity_engine::mono_behaviour::MonoBehaviour;
6use crate::unity_engine::GameObject;
7use once_cell::sync::Lazy;
8use std::any::TypeId;
9use std::cell::RefCell;
10use std::collections::HashMap;
11
12static mut MONO_BEHAVIOUR_FACTORIES: Lazy<
13    RefCell<
14        HashMap<
15            String,
16            fn(
17                weak_game_object: RevelWeak<GameObject>,
18                metadata: &Box<dyn Settings>,
19            ) -> Vec<(RevelArc<Box<dyn MonoBehaviour>>, TypeId)>,
20        >,
21    >,
22> = Lazy::new(|| RefCell::new(HashMap::new()));
23
24pub struct MonoBehaviourFactory;
25
26impl MonoBehaviourFactory {
27    pub fn register<T: Object>(
28        factory: fn(
29            weak_game_object: RevelWeak<GameObject>,
30            metadata: &Box<dyn Settings>,
31        ) -> Vec<(RevelArc<Box<dyn MonoBehaviour>>, TypeId)>,
32    ) {
33        // log::info!(
34        //     "Register MonoBehaviour: {} {}",
35        //     std::any::type_name::<T>(),
36        //     T::get_full_name()
37        // );
38        let full_name = T::get_full_name();
39        #[allow(static_mut_refs)]
40        unsafe {
41            if MONO_BEHAVIOUR_FACTORIES.borrow().contains_key(full_name) {
42                panic!("Component name {} is already registered", full_name);
43            }
44            MONO_BEHAVIOUR_FACTORIES
45                .borrow_mut()
46                .insert(full_name.to_string(), factory);
47        }
48    }
49
50    pub fn create(
51        full_name: &str,
52        weak_game_object: RevelWeak<GameObject>,
53        settings: &Box<dyn Settings>,
54    ) -> Vec<(RevelArc<Box<dyn MonoBehaviour>>, TypeId)> {
55        #[allow(static_mut_refs)]
56        unsafe {
57            match MONO_BEHAVIOUR_FACTORIES.borrow().get(full_name) {
58                None => panic!("Component name {} is not registered", full_name),
59                Some(factory) => {
60                    // let metadata = settings
61                    //     .as_any()
62                    //     .downcast_ref::<MetadataComponentWrapper>()
63                    //     .unwrap();
64                    factory(weak_game_object, settings)
65                }
66            }
67        }
68    }
69}
70
71// #[cfg(test)]
72// mod tests {
73//     use super::*;
74//     use crate::unity_engine::mono_behaviour::MonoBehaviourMetadata;
75//     use crate::unity_engine::transform::Transform;
76//     use unity_mirror_rs_macro::namespace;
77//
78//     #[namespace]
79//     struct TestComponent;
80//
81//     impl MonoBehaviour for TestComponent {
82//         fn update(&mut self) {
83//             println!("TestComponent update");
84//         }
85//     }
86//
87//     #[ctor::ctor]
88//     fn init() {
89//         MonoBehaviourFactory::register::<TestComponent>(|metadata| Box::new(TestComponent));
90//     }
91// }