euv_engine/entity/impl.rs
1use crate::*;
2
3/// Implements static factory and ID generation methods for `Entity`.
4impl Entity {
5 /// Generates the next unique entity ID using a global atomic counter.
6 ///
7 /// # Returns
8 ///
9 /// - `u64` - The next unique ID.
10 pub fn generate_id() -> u64 {
11 NEXT_ENTITY_ID.fetch_add(1, Ordering::Relaxed)
12 }
13
14 /// Creates a new entity with the given name and a default identity transform.
15 ///
16 /// # Arguments
17 ///
18 /// - `&str` - The name of the entity.
19 ///
20 /// # Returns
21 ///
22 /// - `Entity` - The newly created entity.
23 pub fn create(name: &str) -> Entity {
24 Entity::new(
25 Self::generate_id(),
26 name.to_string(),
27 Transform2D::identity(),
28 true,
29 Vec::new(),
30 Vec::new(),
31 )
32 }
33
34 /// Creates a new entity at the specified position with a default name.
35 ///
36 /// # Arguments
37 ///
38 /// - `Vector2D` - The initial position.
39 ///
40 /// # Returns
41 ///
42 /// - `Entity` - The newly created entity.
43 pub fn create_at(position: Vector2D) -> Entity {
44 let mut entity: Entity = Self::create(DEFAULT_ENTITY_NAME);
45 entity.get_mut_transform().set_position(position);
46 entity
47 }
48}
49
50/// Implements lifecycle and component management methods for `Entity`.
51impl Entity {
52 /// Adds a component to this entity and calls its `on_start` lifecycle method.
53 ///
54 /// # Arguments
55 ///
56 /// - `ComponentRc` - The component to add.
57 pub fn add_component(&mut self, component: ComponentRc) {
58 component.borrow_mut().on_start();
59 self.get_mut_components().push(component);
60 }
61
62 /// Removes the first component matching the given name.
63 ///
64 /// # Arguments
65 ///
66 /// - `&str` - The component name to match.
67 ///
68 /// # Returns
69 ///
70 /// - `Option<ComponentRc>` - The removed component, if found.
71 pub fn remove_component_by_name(&mut self, name: &str) -> Option<ComponentRc> {
72 let position: Option<usize> = self
73 .get_components()
74 .iter()
75 .position(|component: &ComponentRc| component.borrow().name() == name);
76 let index: usize = position?;
77 let removed: ComponentRc = self.get_mut_components().remove(index);
78 removed.borrow_mut().on_destroy();
79 Some(removed)
80 }
81
82 /// Returns the first component matching the given name.
83 ///
84 /// # Arguments
85 ///
86 /// - `&str` - The component name to match.
87 ///
88 /// # Returns
89 ///
90 /// - `Option<ComponentRc>` - The matching component, if found.
91 pub fn get_component_by_name(&self, name: &str) -> Option<ComponentRc> {
92 self.get_components()
93 .iter()
94 .find(|component: &&ComponentRc| component.borrow().name() == name)
95 .cloned()
96 }
97
98 /// Calls `on_update` on all active components.
99 ///
100 /// # Arguments
101 ///
102 /// - `f64` - The delta time in seconds.
103 pub fn update(&mut self, delta_time: f64) {
104 if !self.get_active() {
105 return;
106 }
107 for component in self.get_components() {
108 component.borrow_mut().on_update(delta_time);
109 }
110 }
111
112 /// Calls `on_render` on all active components.
113 ///
114 /// # Arguments
115 ///
116 /// - `&CanvasRenderingContext2d` - The canvas rendering context.
117 pub fn render(&self, context: &CanvasRenderingContext2d) {
118 if !self.get_active() {
119 return;
120 }
121 let transform: Transform2D = self.get_transform();
122 for component in self.get_components() {
123 component.borrow_mut().on_render(context, &transform);
124 }
125 }
126
127 /// Calls `on_destroy` on all components and clears the component list.
128 pub fn destroy(&mut self) {
129 for component in self.get_components() {
130 component.borrow_mut().on_destroy();
131 }
132 self.get_mut_components().clear();
133 }
134
135 /// Adds a tag string to this entity.
136 ///
137 /// # Arguments
138 ///
139 /// - `String` - The tag to add.
140 pub fn add_tag(&mut self, tag: String) {
141 if !self.get_tags().contains(&tag) {
142 self.get_mut_tags().push(tag);
143 }
144 }
145
146 /// Tests whether this entity has the given tag.
147 ///
148 /// # Arguments
149 ///
150 /// - `&str` - The tag to check.
151 ///
152 /// # Returns
153 ///
154 /// - `bool` - True if the tag is present.
155 pub fn has_tag(&self, tag: &str) -> bool {
156 self.get_tags().iter().any(|t: &String| t == tag)
157 }
158}