prime_forge/
forged_object.rs

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        // check if trait already exists
29        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    // Transform Trait Special
117    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);