unity_mirror_rs/unity_engine/
game_object.rs

1use crate::commons::RevelArc;
2use crate::commons::RevelWeak;
3use crate::metadata_settings::metadata_component::MetadataComponentWrapper;
4use crate::metadata_settings::metadata_prefab::MetadataPrefab;
5use crate::unity_engine::mono_behaviour::MonoBehaviour;
6use crate::unity_engine::mono_behaviour_factory::MonoBehaviourFactory;
7use crate::unity_engine::transform::Transform;
8use crate::unity_engine::WorldManager;
9use once_cell::sync::Lazy;
10use rand::RngCore;
11use std::any::TypeId;
12use std::collections::HashMap;
13
14static mut COMPONENT_LOADING: Lazy<Vec<(RevelWeak<GameObject>, MetadataComponentWrapper)>> =
15    Lazy::new(|| vec![]);
16
17fn append_component_loading(
18    weak_game_object: RevelWeak<GameObject>,
19    component: MetadataComponentWrapper,
20) {
21    #[allow(static_mut_refs)]
22    unsafe {
23        COMPONENT_LOADING.push((weak_game_object, component));
24    }
25}
26
27fn component_loading() {
28    #[allow(static_mut_refs)]
29    unsafe {
30        COMPONENT_LOADING.reverse();
31        while let Some((arc_game_object, metadata_prefab)) = COMPONENT_LOADING.pop() {
32            GameObject::load_component(arc_game_object, &metadata_prefab);
33        }
34    }
35}
36
37#[derive(Default)]
38pub struct GameObject {
39    pub id: u64,
40    pub name: String,
41    pub asset_id: u32,
42    pub asset_path: String,
43    pub tag: String,
44    pub layer: i32,
45    pub is_static: bool,
46    is_active: bool,
47    pub transform: RevelArc<Transform>,
48    pub parent: RevelWeak<GameObject>,
49    pub children: HashMap<u64, RevelArc<GameObject>>,
50    // pub components: IndexMap<TypeId, RevelArc<Box<dyn MonoBehaviour>>>>,
51    component_mapping: HashMap<TypeId, Vec<usize>>,
52    // pub components: Vec<RevelArc<Box<dyn MonoBehaviour>>>>,
53    pub components: Vec<Vec<RevelArc<Box<dyn MonoBehaviour>>>>,
54}
55
56impl GameObject {
57    pub(super) fn instance(metadata_prefab: &MetadataPrefab) -> RevelArc<GameObject> {
58        let arc_game_object = Self::new(RevelWeak::default(), metadata_prefab);
59        Self::recursive_children(arc_game_object.downgrade(), &metadata_prefab.children);
60        component_loading();
61        arc_game_object
62    }
63
64    pub fn instantiate(metadata_prefab: &MetadataPrefab) -> RevelArc<GameObject> {
65        log::debug!("Instantiate: {}", metadata_prefab.name);
66        let arc_game_object = Self::instance(metadata_prefab);
67        if let Some(world) = WorldManager::active_world().get() {
68            world.add_game_object(arc_game_object.clone());
69        }
70        arc_game_object
71    }
72
73    pub fn default() -> GameObject {
74        Self {
75            id: rand::rng().next_u64(),
76            ..Default::default()
77        }
78    }
79
80    fn new(parent: RevelWeak<GameObject>, metadata_prefab: &MetadataPrefab) -> RevelArc<GameObject> {
81        // 随机数
82        let mut rng = rand::rng();
83        let mut game_object = GameObject {
84            id: rng.next_u64(),
85            name: metadata_prefab.name.clone(),
86            tag: metadata_prefab.tag.clone(),
87            layer: metadata_prefab.layer,
88            is_static: metadata_prefab.is_static,
89            is_active: metadata_prefab.is_active,
90            asset_id: metadata_prefab.asset_id,
91            asset_path: metadata_prefab.asset_path.clone(),
92            parent: parent.clone(),
93            components: Default::default(),
94            transform: Default::default(),
95            children: HashMap::default(),
96            component_mapping: Default::default(),
97        };
98
99        let mut transform = Transform::new_with_metadata(&metadata_prefab.transform);
100
101        if let Some(parent_game_object) = parent.get() {
102            transform.parent = parent_game_object.transform.downgrade()
103        }
104
105        game_object.transform = RevelArc::new(transform);
106        let mut arc_game_object = RevelArc::new(game_object);
107
108        append_component_loading(
109            arc_game_object.downgrade(),
110            metadata_prefab.components.clone(),
111        );
112
113        arc_game_object.transform.game_object = arc_game_object.downgrade();
114        arc_game_object
115    }
116
117    fn recursive_children(parent: RevelWeak<GameObject>, children: &Vec<MetadataPrefab>) {
118        for metadata_prefab in children {
119            let arc_game_object = Self::new(parent.clone(), metadata_prefab);
120
121            let weak_game_object = arc_game_object.downgrade();
122
123            if let Some(parent) = parent.get() {
124                parent.children.insert(arc_game_object.id, arc_game_object);
125            }
126
127            if metadata_prefab.children.len() > 0 {
128                Self::recursive_children(weak_game_object.clone(), &metadata_prefab.children);
129            }
130
131            if let Some(game_object) = weak_game_object.get() {
132                for (_, children_game_object) in &game_object.children {
133                    game_object
134                        .transform
135                        .children
136                        .push(children_game_object.transform.downgrade());
137                }
138            }
139        }
140    }
141
142    fn load_component(
143        weak_game_object: RevelWeak<GameObject>,
144        component: &MetadataComponentWrapper,
145    ) {
146        for (full_path, component_settings) in component.group_by_full_name() {
147            let mono_behaviour_chain = MonoBehaviourFactory::create(
148                &full_path,
149                weak_game_object.clone(),
150                &component_settings,
151            );
152
153            let mut mono_behaviours = vec![];
154            for (mono_behaviour, type_id) in mono_behaviour_chain {
155                // let arc_mono_behaviour = RevelArc::new(mono_behaviour);
156                mono_behaviours.push((mono_behaviour, type_id));
157            }
158
159            if let Some(game_object) = weak_game_object.get() {
160                game_object.add_component(mono_behaviours);
161            }
162        }
163    }
164}
165
166impl GameObject {
167    pub fn add_component(&mut self, mono_behaviour_chain: Vec<(RevelArc<Box<dyn MonoBehaviour + 'static>>, TypeId)>) {
168        if mono_behaviour_chain.len() == 0 {
169            panic!("MonoBehaviourChain is empty");
170        }
171        let index = self.components.len();
172        let mut arc_mono_behaviours = Vec::new();
173        for (mono_behaviour, type_id) in mono_behaviour_chain {
174            arc_mono_behaviours.push(mono_behaviour);
175            if !self.component_mapping.contains_key(&type_id) {
176                self.component_mapping.insert(type_id, vec![index]);
177            } else {
178                if let Some(mapping) = self.component_mapping.get_mut(&type_id) {
179                    mapping.push(index);
180                };
181            }
182        }
183        self.components.push(arc_mono_behaviours);
184
185        if let Some(component) = self.components.last_mut() {
186            if let Some(component) = component.last_mut() {
187                component.awake();
188            }
189        }
190    }
191
192    pub fn try_get_component<T: MonoBehaviour + 'static>(&self) -> Option<RevelWeak<Box<dyn MonoBehaviour>>> {
193        let type_id = TypeId::of::<T>();
194
195        let vec_index = self
196            .component_mapping
197            .get(&type_id)
198            .cloned()
199            .unwrap_or(vec![]);
200        if vec_index.len() == 0 {
201            return None;
202        }
203
204        Some(
205            self.components
206                .get(vec_index[0])?
207                .last()
208                .cloned()?
209                .downgrade(),
210        )
211    }
212
213    pub fn try_get_component2<T: MonoBehaviour + 'static>(&self) -> Option<RevelArc<Box<T>>> {
214        // log::debug!("{}", self.components.iter().map(|c| c.last().unwrap().type_name()).collect::<Vec<_>>().join("\n"));
215        if let Some(weak_mono) = self.try_get_component::<T>() {
216            if let Some(weak_t) = weak_mono.downcast::<T>() {
217                return weak_t.upgrade();
218            }
219        }
220        None
221    }
222
223    pub fn get_components<T: MonoBehaviour + 'static>(&self) -> Vec<RevelWeak<Box<dyn MonoBehaviour>>> {
224        let type_id = TypeId::of::<T>();
225
226        let vec_index = self
227            .component_mapping
228            .get(&type_id)
229            .cloned()
230            .unwrap_or(vec![]);
231        if vec_index.len() == 0 {
232            return vec![];
233        }
234
235        let mut result = vec![];
236        for index in vec_index {
237            if let Some(component) = self.components.get(index) {
238                if let Some(component) = component.last() {
239                    result.push(component.downgrade());
240                }
241            }
242        }
243        result
244    }
245
246    // pub fn find_component<T: MonoBehaviour>(
247    //     &self,
248    //     t: impl Any,
249    // ) -> Option<RevelWeak<Box<dyn MonoBehaviour>>> {
250    //     let x = t as *const dyn MonoBehaviour;
251    //     // let x1 = x.eq(&self.components.as_ptr());
252    //
253    //     for component in self.components.iter() {
254    //         let x2 = component.last().unwrap().as_ref();
255    //         let x3 = x2 as *const dyn MonoBehaviour;
256    //         if x == x3 {
257    //             return Some(component.last().unwrap().downgrade());
258    //         }
259    //     }
260    //     None
261    // }
262
263    pub fn find_transform(&self, instance_id: &i32) -> Option<RevelWeak<Transform>> {
264        if self.transform.instance_id == *instance_id {
265            return Some(self.transform.downgrade());
266        }
267        for (_, children_game_object) in self.children.iter() {
268            if let Some(weak_transform) = children_game_object.find_transform(instance_id) {
269                return Some(weak_transform);
270            }
271        }
272        None
273    }
274
275    pub fn is_active(&self) -> bool {
276        self.is_active
277    }
278    pub fn set_active(&mut self, active: bool) {
279        self.is_active = active
280    }
281}
282
283//调用了start的组件map
284static mut STARTED_COMPONENT: Vec<RevelWeak<Box<dyn MonoBehaviour>>> = Vec::new();
285
286macro_rules! recursive_event_fn {
287    ($($fn_name:ident),*) => {
288        $(
289            pub(crate) fn $fn_name(&mut self) {
290                for children_game_object in self.children.values_mut() {
291                     children_game_object.$fn_name()
292                }
293                for component_chain in self.components.iter_mut() {
294                    if let Some(component) = component_chain.last_mut() {
295                        component.$fn_name();
296                    }
297                }
298            }
299        )*
300    };
301}
302
303#[allow(unused)]
304impl GameObject {
305    recursive_event_fn!(
306        awake,
307        on_enable,
308        on_validate,
309        start,
310        fixed_update,
311        late_update,
312        on_disable
313    );
314
315    pub(crate) fn update(&mut self) {
316        for children_game_object in self.children.values_mut() {
317            children_game_object.update()
318        }
319        for component_chain in self.components.clone().iter_mut() {
320            if let Some(component) = component_chain.last_mut() {
321                #[allow(static_mut_refs)]
322                unsafe {
323                    let started = STARTED_COMPONENT.iter().any(|weak_component| {
324                        weak_component.ptr_eq(&component.downgrade())
325                    });
326                    if !started {
327                        component.start();
328                        STARTED_COMPONENT.push(component.downgrade())
329                    }
330                }
331                component.update()
332            }
333        }
334    }
335
336    pub(crate) fn on_destroy(&mut self) {
337        for children_game_object in self.children.values_mut() {
338            children_game_object.on_destroy();
339        }
340        for component_chain in self.components.iter_mut() {
341            if let Some(component) = component_chain.last_mut() {
342                #[allow(static_mut_refs)]
343                unsafe {
344                    STARTED_COMPONENT.retain(|weak_component| !weak_component.ptr_eq(&component.downgrade()));
345                }
346                component.on_destroy();
347            }
348        }
349    }
350}