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 /// Creates a new entity with the given name and a default identity transform.
17 ///
18 /// # Arguments
19 ///
20 /// - `N: AsRef<str>` - The name of the entity.
21 ///
22 /// # Returns
23 ///
24 /// - `Entity` - The newly created entity.
25 pub fn create<N>(name: N) -> Entity
26 where
27 N: AsRef<str>,
28 {
29 Entity::new(
30 Self::generate_id(),
31 name.as_ref().to_string(),
32 Transform2D::identity(),
33 true,
34 Vec::new(),
35 Vec::new(),
36 )
37 }
38
39 /// Creates a new entity at the specified position with a default name.
40 ///
41 /// # Arguments
42 ///
43 /// - `Vector2D` - The initial position.
44 ///
45 /// # Returns
46 ///
47 /// - `Entity` - The newly created entity.
48 pub fn create_at(position: Vector2D) -> Entity {
49 let mut entity: Entity = Self::create(DEFAULT_ENTITY_NAME);
50 entity.get_mut_transform().set_position(position);
51 entity
52 }
53}
54
55/// Implements lifecycle and component management methods for `Entity`.
56impl Entity {
57 /// Adds a component to this entity and calls its `on_start` lifecycle method.
58 ///
59 /// # Arguments
60 ///
61 /// - `ComponentRc` - The component to add.
62 pub fn add_component(&mut self, component: ComponentRc) {
63 component.borrow_mut().on_start();
64 self.get_mut_components().push(component);
65 }
66
67 /// Removes the first component matching the given name.
68 ///
69 /// # Arguments
70 ///
71 /// - `&str` - The component name to match.
72 ///
73 /// # Returns
74 ///
75 /// - `Option<ComponentRc>` - The removed component, if found.
76 pub fn remove_component_by_name<N>(&mut self, name: N) -> Option<ComponentRc>
77 where
78 N: AsRef<str>,
79 {
80 let target: &str = name.as_ref();
81 let position: Option<usize> = self
82 .get_components()
83 .iter()
84 .position(|component: &ComponentRc| component.borrow().name() == target);
85 let index: usize = position?;
86 let removed: ComponentRc = self.get_mut_components().remove(index);
87 removed.borrow_mut().on_destroy();
88 Some(removed)
89 }
90
91 /// Returns the first component matching the given name.
92 ///
93 /// # Arguments
94 ///
95 /// - `&str` - The component name to match.
96 ///
97 /// # Returns
98 ///
99 /// - `Option<ComponentRc>` - The matching component, if found.
100 pub fn get_component_by_name<N>(&self, name: N) -> Option<ComponentRc>
101 where
102 N: AsRef<str>,
103 {
104 let target: &str = name.as_ref();
105 self.get_components()
106 .iter()
107 .find(|component: &&ComponentRc| component.borrow().name() == target)
108 .cloned()
109 }
110
111 /// Calls `on_update` on all active components.
112 ///
113 /// # Arguments
114 ///
115 /// - `f64` - The delta time in seconds.
116 pub fn update(&mut self, delta_time: f64) {
117 if !self.get_active() {
118 return;
119 }
120 for component in self.get_components() {
121 component.borrow_mut().on_update(delta_time);
122 }
123 }
124
125 /// Calls `on_render` on all active components.
126 ///
127 /// # Arguments
128 ///
129 /// - `&CanvasRenderingContext2d` - The canvas rendering context.
130 pub fn render(&self, context: &CanvasRenderingContext2d) {
131 if !self.get_active() {
132 return;
133 }
134 let transform: Transform2D = self.get_transform();
135 for component in self.get_components() {
136 component.borrow_mut().on_render(context, &transform);
137 }
138 }
139
140 /// Calls `on_destroy` on all components and clears the component list.
141 pub fn destroy(&mut self) {
142 for component in self.get_components() {
143 component.borrow_mut().on_destroy();
144 }
145 self.get_mut_components().clear();
146 }
147
148 /// Adds a tag string to this entity.
149 ///
150 /// # Arguments
151 ///
152 /// - `String` - The tag to add.
153 pub fn add_tag(&mut self, tag: String) {
154 if !self.get_tags().contains(&tag) {
155 self.get_mut_tags().push(tag);
156 }
157 }
158
159 /// Tests whether this entity has the given tag.
160 ///
161 /// # Arguments
162 ///
163 /// - `&str` - The tag to check.
164 ///
165 /// # Returns
166 ///
167 /// - `bool` - True if the tag is present.
168 pub fn has_tag<T>(&self, tag: T) -> bool
169 where
170 T: AsRef<str>,
171 {
172 let target: &str = tag.as_ref();
173 self.get_tags().iter().any(|t: &String| t == target)
174 }
175}
176
177/// Implements event subscription, emission, and management for `EventBus`.
178impl EventBus {
179 /// Creates a new empty event bus.
180 ///
181 /// # Returns
182 ///
183 /// - `EventBus` - The new event bus.
184 pub fn create() -> EventBus {
185 EventBus::new()
186 }
187
188 /// Subscribes a handler to the named event channel.
189 ///
190 /// # Arguments
191 ///
192 /// - `String` - The event name to subscribe to.
193 /// - `EventHandler` - The handler closure to call when the event is emitted.
194 pub fn subscribe(&mut self, event_name: String, handler: EventHandler) {
195 self.get_mut_handlers()
196 .entry(event_name)
197 .or_default()
198 .push(handler);
199 }
200
201 /// Emits an event to all handlers subscribed to the matching channel.
202 ///
203 /// The event name is derived from the `EntityEvent` variant.
204 ///
205 /// # Arguments
206 ///
207 /// - `&EntityEvent` - The event to emit.
208 pub fn emit(&self, event: &EntityEvent) {
209 let event_name: String = Self::event_name(event);
210 if let Some(handlers) = self.get_handlers().get(&event_name) {
211 for handler in handlers {
212 handler(event);
213 }
214 }
215 }
216
217 /// Removes all handlers for the named event channel.
218 ///
219 /// # Arguments
220 ///
221 /// - `E: AsRef<str>` - The event name to clear.
222 pub fn unsubscribe_all<E>(&mut self, event_name: E)
223 where
224 E: AsRef<str>,
225 {
226 self.get_mut_handlers().remove(event_name.as_ref());
227 }
228
229 /// Returns the number of handlers registered for the named event.
230 ///
231 /// # Arguments
232 ///
233 /// - `&str` - The event name.
234 ///
235 /// # Returns
236 ///
237 /// - `usize` - The handler count.
238 pub fn handler_count<E>(&self, event_name: E) -> usize
239 where
240 E: AsRef<str>,
241 {
242 self.get_handlers()
243 .get(event_name.as_ref())
244 .map(|handlers: &Vec<EventHandler>| handlers.len())
245 .unwrap_or(0)
246 }
247
248 /// Derives the event channel name from an `EntityEvent` variant.
249 ///
250 /// # Arguments
251 ///
252 /// - `&EntityEvent` - The event.
253 ///
254 /// # Returns
255 ///
256 /// - `String` - The channel name.
257 fn event_name(event: &EntityEvent) -> String {
258 match event {
259 EntityEvent::Collision { .. } => "collision".to_string(),
260 EntityEvent::TriggerEnter { .. } => "trigger_enter".to_string(),
261 EntityEvent::TriggerExit { .. } => "trigger_exit".to_string(),
262 EntityEvent::Spawn => "spawn".to_string(),
263 EntityEvent::Destroy => "destroy".to_string(),
264 EntityEvent::Custom { name, .. } => name.clone(),
265 }
266 }
267}
268
269/// Implements `Default` for `EventBus` as a new empty bus.
270impl Default for EventBus {
271 fn default() -> EventBus {
272 EventBus::create()
273 }
274}