1use std::{cell::RefCell, rc::Rc};
2
3use crate::{forged_trait::TransformSpecialTrait, lost_realm::LostRealm};
4
5use super::{forged_trait::ForgedTrait, lost_lands_fault::LostLostLandsFaultForgedObject};
6
7pub struct ForgedObject {
8 pub name: String,
9 pub id: uuid::Uuid,
10 pub forged_traits: Vec<Box<RefCell<dyn ForgedTrait>>>,
11 pub transform: Rc<RefCell<TransformSpecialTrait>>,
12}
13
14impl ForgedObject {
15 pub fn new(name: String) -> ForgedObject {
16 ForgedObject {
17 name,
18 id: uuid::Uuid::new_v4(),
19 forged_traits: Vec::new(),
20 transform: Rc::new(RefCell::new(TransformSpecialTrait::new())),
21 }
22 }
23
24 pub fn add_trait(
25 &mut self,
26 new_trait: Box<RefCell<dyn ForgedTrait>>,
27 ) -> Result<(), LostLostLandsFaultForgedObject> {
28 let trait_exists = self.forged_traits.iter().any(|trait_| {
30 trait_.borrow().as_any().type_id() == new_trait.borrow().as_any().type_id()
31 });
32 if trait_exists {
33 return Err(LostLostLandsFaultForgedObject::TraitAlreadyExists(
34 std::any::type_name::<dyn ForgedTrait>().to_string(),
35 ));
36 }
37
38 new_trait.borrow_mut().set_father(self.id.to_string());
39 self.forged_traits.push(new_trait);
40 Ok(())
41 }
42
43 pub fn add_traits<T: TraitBundle>(&mut self, traits: T) {
44 traits.craft_trait_bundle(self);
45 }
46
47 pub fn start(&self, lost_realm: &mut LostRealm) {
48 for trait_ in &self.forged_traits {
49 trait_.borrow_mut().start(lost_realm);
50 }
51 }
52
53 pub fn update(&self, lost_realm: &mut LostRealm, dt: f32) {
54 for trait_ in &self.forged_traits {
55 trait_.borrow_mut().update(lost_realm, dt);
56 }
57 }
58
59 pub fn get_trait<T: 'static + ForgedTrait>(
60 &self,
61 ) -> Result<&T, LostLostLandsFaultForgedObject> {
62 let forged_trait = self.forged_traits.iter().find(|forged_trait| {
63 forged_trait.borrow().as_any().type_id() == std::any::TypeId::of::<T>()
64 });
65
66 if let Some(forged_trait) = forged_trait {
67 let forged_trait = forged_trait.borrow();
68 let forged_trait = forged_trait.as_any().downcast_ref::<T>().unwrap();
69 let forged_trait = unsafe { std::mem::transmute::<&T, &'static T>(forged_trait) };
70 return Ok(forged_trait);
71 } else {
72 Err(LostLostLandsFaultForgedObject::TraitNotFound(
73 std::any::type_name::<T>().to_string(),
74 ))
75 }
76 }
77
78 pub fn get_trait_mut<T: 'static + ForgedTrait>(
79 &self,
80 ) -> Result<&mut T, LostLostLandsFaultForgedObject> {
81 let forged_trait = self.forged_traits.iter().find(|forged_trait| {
82 forged_trait.borrow().as_any().type_id() == std::any::TypeId::of::<T>()
83 });
84
85 if let Some(forged_trait) = forged_trait {
86 let mut forged_trait = forged_trait.borrow_mut();
87 let forged_trait = forged_trait.as_any_mut().downcast_mut::<T>().unwrap();
88 let forged_trait =
89 unsafe { std::mem::transmute::<&mut T, &'static mut T>(forged_trait) };
90 return Ok(forged_trait);
91 } else {
92 Err(LostLostLandsFaultForgedObject::TraitNotFound(
93 std::any::type_name::<T>().to_string(),
94 ))
95 }
96 }
97
98 pub fn remove_trait<T: 'static + ForgedTrait>(
99 &mut self,
100 ) -> Result<(), LostLostLandsFaultForgedObject> {
101 let forged_trait = self.forged_traits.iter().position(|forged_trait| {
102 println!("{:?}", forged_trait.borrow().as_any().type_id());
103 forged_trait.borrow().as_any().type_id() == std::any::TypeId::of::<T>()
104 });
105
106 if let Some(forged_trait) = forged_trait {
107 self.forged_traits.remove(forged_trait);
108 Ok(())
109 } else {
110 Err(LostLostLandsFaultForgedObject::TraitNotFound(
111 std::any::type_name::<T>().to_string(),
112 ))
113 }
114 }
115
116 pub fn set_transform_child(&self, child: Rc<RefCell<TransformSpecialTrait>>) {
118 self.transform
119 .borrow_mut()
120 .set_children(vec![child.clone()]);
121 child.borrow_mut().set_parent(self.transform.clone());
122 }
123
124 pub fn set_transform_parent(&self, parent: Rc<RefCell<TransformSpecialTrait>>) {
125 parent
126 .borrow_mut()
127 .set_children(vec![self.transform.clone()]);
128 self.transform.borrow_mut().set_parent(parent);
129 self.transform.borrow_mut().update_self_and_children();
130 }
131
132 pub fn set_transform_children(&self, children: Vec<Rc<RefCell<TransformSpecialTrait>>>) {
133 self.transform.borrow_mut().set_children(children.clone());
134 for child in children {
135 child.borrow_mut().set_parent(self.transform.clone());
136 }
137 self.transform.borrow_mut().update_self_and_children();
138 }
139}
140
141pub trait TraitBundle {
142 fn craft_trait_bundle(self, forged_object: &mut ForgedObject);
143}
144
145macro_rules! impl_trait_bundle {
146 ($(($name: ident, $index: tt)),*) => {
147 impl<$($name: ForgedTrait + 'static),*> TraitBundle for ($($name,)*) {
148 fn craft_trait_bundle(self, forged_object: &mut ForgedObject) {
149 $(forged_object.add_trait(Box::new(RefCell::new(self.$index))).unwrap();)*
150 }
151 }
152 };
153}
154impl_trait_bundle!((A, 0));
155impl_trait_bundle!((A, 0), (B, 1));
156impl_trait_bundle!((A, 0), (B, 1), (C, 2));
157impl_trait_bundle!((A, 0), (B, 1), (C, 2), (D, 3));
158impl_trait_bundle!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4));
159impl_trait_bundle!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5));
160impl_trait_bundle!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6));
161impl_trait_bundle!(
162 (A, 0),
163 (B, 1),
164 (C, 2),
165 (D, 3),
166 (E, 4),
167 (F, 5),
168 (G, 6),
169 (H, 7)
170);
171impl_trait_bundle!(
172 (A, 0),
173 (B, 1),
174 (C, 2),
175 (D, 3),
176 (E, 4),
177 (F, 5),
178 (G, 6),
179 (H, 7),
180 (I, 8)
181);
182impl_trait_bundle!(
183 (A, 0),
184 (B, 1),
185 (C, 2),
186 (D, 3),
187 (E, 4),
188 (F, 5),
189 (G, 6),
190 (H, 7),
191 (I, 8),
192 (J, 9)
193);
194impl_trait_bundle!(
195 (A, 0),
196 (B, 1),
197 (C, 2),
198 (D, 3),
199 (E, 4),
200 (F, 5),
201 (G, 6),
202 (H, 7),
203 (I, 8),
204 (J, 9),
205 (K, 10)
206);