feo_oop_engine/scene/game_object/
group.rs

1//! An empty object that can contain other GameObjects
2//! 
3//! TODO
4//! 
5use {
6    super::{
7        GameObject,
8        camera::Camera,
9        light::Light,
10    },
11    crate::{
12        registration::{
13            relation::{
14                Child, Parent,
15                ParentWrapper
16            },
17            named::Named,
18            id::ID,
19        },
20        scripting::{
21            Scriptable, 
22            globals::{EngineGlobals, Global},
23            Script,
24            executor::Spawner,
25        },
26        graphics::{
27            Drawable,
28            draw_pass_manager::DrawPassManager,
29            lighting_pass_manager::LightingPassManager,
30        },
31        event::UserEvent,
32        components::triangle_mesh::TriangleMesh
33    },
34    std::{
35        any::Any,
36        mem, 
37        sync::{Arc, RwLock}
38    },
39    feo_math::{
40        utils::space::Space, 
41        rotation::quaternion::Quaternion,
42        linear_algebra::vector3::Vector3
43    },
44    winit::event::Event,
45};
46
47#[derive(Scriptable, Drawable, GameObject, Child, Parent, Named)]
48pub struct Group {
49    pub id: ID,
50    pub name: String,
51    pub parent: ParentWrapper,
52
53    pub subspace: Space,
54
55    pub visible: bool,
56
57    pub script: Option<Box<Script<Self>>>,
58
59    pub children: Vec<Arc<RwLock<dyn GameObject>>>
60}
61
62impl std::fmt::Debug for Group {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        f.debug_struct("Group")
65            .field("id", &self.id)
66            .field("name", &self.name)
67            .field("parent", &self.parent)
68            .field("subspace", &self.subspace)
69            .field("visible", &self.visible)
70            .field("script", &self.script)
71            .field("children", &self.children).finish()
72    }
73}
74
75impl Clone for Group {
76    fn clone(&self) -> Self {
77        let id = self.id.get_system().take();
78        Group{
79            id,
80            name: self.name.clone(),
81            parent: self.parent.clone(),
82            visible: self.visible,
83            subspace: self.subspace,
84            script: self.script.clone(),
85            children: self.children.clone().into_iter().map(|_child| {
86                // Dangerous
87                todo!();
88            }).collect::<Vec<Arc<RwLock<dyn GameObject>>>>(),
89        }
90    }
91}
92
93impl PartialEq for Group{
94    fn eq(&self, other: &Self) -> bool {
95        self.get_id() == other.get_id()
96    }
97}
98
99impl Group {
100    #[allow(clippy::too_many_arguments)]
101    pub fn new(
102            name: Option<&str>,
103
104            parent: Option<Arc<RwLock<dyn GameObject>>>,
105        
106            position: Option<Vector3<f32>>, 
107            rotation: Option<Quaternion<f32>>,
108            scale_factor: Option<Vector3<f32>>,
109
110            visible: bool,
111
112            engine_globals: EngineGlobals,
113            script: Option<Box<Script<Self>>>) -> Arc<RwLock<Self>> {
114
115        let id = engine_globals.id_system.take();
116    
117        Arc::new(RwLock::new(Group{
118            name: match name {
119                Some(name) => name.to_string(),
120                None => String::from("group_") + id.to_string().as_str()
121            },
122            id,
123            parent: match parent {
124                Some(game_object) => ParentWrapper::GameObject(game_object),
125                None => ParentWrapper::Scene(engine_globals.scene)
126            },
127            subspace: Space::new(position, rotation, scale_factor),
128            visible,
129            script,
130            children: Vec::new()
131        }))
132    }
133}