goud_engine/ecs/components/hierarchy/children.rs
1//! [`Children`] component for listing child entities.
2
3use crate::ecs::entity::Entity;
4use crate::ecs::Component;
5use std::fmt;
6
7// =============================================================================
8// Children Component
9// =============================================================================
10
11/// Component containing a list of child entities.
12///
13/// This component stores references to all immediate children of an entity.
14/// The order of children is preserved and can be significant for rendering
15/// order or other order-dependent operations.
16///
17/// # Capacity and Performance
18///
19/// Internally uses a `Vec<Entity>`, so:
20/// - Adding children is O(1) amortized
21/// - Removing children is O(n) where n is the number of children
22/// - Iteration is cache-friendly
23///
24/// For entities with many children, consider using `with_capacity` to
25/// pre-allocate memory.
26///
27/// # Example
28///
29/// ```
30/// use goud_engine::ecs::Entity;
31/// use goud_engine::ecs::components::Children;
32///
33/// let mut children = Children::new();
34///
35/// let child1 = Entity::new(1, 1);
36/// let child2 = Entity::new(2, 1);
37///
38/// children.push(child1);
39/// children.push(child2);
40///
41/// assert_eq!(children.len(), 2);
42/// assert!(children.contains(child1));
43/// ```
44#[derive(Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
45pub struct Children {
46 /// The list of child entities in order.
47 pub(crate) children: Vec<Entity>,
48}
49
50impl Children {
51 /// Creates an empty Children component.
52 #[inline]
53 pub fn new() -> Self {
54 Self {
55 children: Vec::new(),
56 }
57 }
58
59 /// Creates a Children component with pre-allocated capacity.
60 ///
61 /// Use this when you know approximately how many children the entity will have.
62 #[inline]
63 pub fn with_capacity(capacity: usize) -> Self {
64 Self {
65 children: Vec::with_capacity(capacity),
66 }
67 }
68
69 /// Creates a Children component from a slice of entities.
70 #[inline]
71 pub fn from_slice(children: &[Entity]) -> Self {
72 Self {
73 children: children.to_vec(),
74 }
75 }
76
77 /// Returns the number of children.
78 #[inline]
79 pub fn len(&self) -> usize {
80 self.children.len()
81 }
82
83 /// Returns `true` if there are no children.
84 #[inline]
85 pub fn is_empty(&self) -> bool {
86 self.children.is_empty()
87 }
88
89 /// Adds a child entity to the end of the children list.
90 #[inline]
91 pub fn push(&mut self, child: Entity) {
92 self.children.push(child);
93 }
94
95 /// Inserts a child entity at a specific index.
96 ///
97 /// # Panics
98 ///
99 /// Panics if `index > len`.
100 #[inline]
101 pub fn insert(&mut self, index: usize, child: Entity) {
102 self.children.insert(index, child);
103 }
104
105 /// Removes and returns the child at the specified index.
106 ///
107 /// # Panics
108 ///
109 /// Panics if `index >= len`.
110 #[inline]
111 pub fn remove(&mut self, index: usize) -> Entity {
112 self.children.remove(index)
113 }
114
115 /// Removes a child entity if it exists, preserving order.
116 ///
117 /// Returns `true` if the child was found and removed, `false` otherwise.
118 /// This is O(n) as it must search for the child and shift elements.
119 pub fn remove_child(&mut self, child: Entity) -> bool {
120 if let Some(index) = self.children.iter().position(|&e| e == child) {
121 self.children.remove(index);
122 true
123 } else {
124 false
125 }
126 }
127
128 /// Removes a child entity using swap-remove (faster but doesn't preserve order).
129 ///
130 /// Returns `true` if the child was found and removed, `false` otherwise.
131 /// O(n) for the search but O(1) for the actual removal.
132 pub fn swap_remove_child(&mut self, child: Entity) -> bool {
133 if let Some(index) = self.children.iter().position(|&e| e == child) {
134 self.children.swap_remove(index);
135 true
136 } else {
137 false
138 }
139 }
140
141 /// Returns `true` if the given entity is a child.
142 #[inline]
143 pub fn contains(&self, child: Entity) -> bool {
144 self.children.contains(&child)
145 }
146
147 /// Returns the child at the given index, if any.
148 #[inline]
149 pub fn get(&self, index: usize) -> Option<Entity> {
150 self.children.get(index).copied()
151 }
152
153 /// Returns the first child, if any.
154 #[inline]
155 pub fn first(&self) -> Option<Entity> {
156 self.children.first().copied()
157 }
158
159 /// Returns the last child, if any.
160 #[inline]
161 pub fn last(&self) -> Option<Entity> {
162 self.children.last().copied()
163 }
164
165 /// Returns an iterator over the children.
166 #[inline]
167 pub fn iter(&self) -> impl Iterator<Item = &Entity> {
168 self.children.iter()
169 }
170
171 /// Returns the index of a child entity, if it exists.
172 ///
173 /// Returns `Some(index)` if found, `None` otherwise.
174 #[inline]
175 pub fn index_of(&self, child: Entity) -> Option<usize> {
176 self.children.iter().position(|&e| e == child)
177 }
178
179 /// Removes all children.
180 #[inline]
181 pub fn clear(&mut self) {
182 self.children.clear();
183 }
184
185 /// Returns the children as a slice.
186 #[inline]
187 pub fn as_slice(&self) -> &[Entity] {
188 &self.children
189 }
190
191 /// Retains only the children that satisfy the predicate.
192 ///
193 /// # Example
194 ///
195 /// ```
196 /// use goud_engine::ecs::Entity;
197 /// use goud_engine::ecs::components::Children;
198 ///
199 /// let mut children = Children::from_slice(&[
200 /// Entity::new(1, 1),
201 /// Entity::new(2, 1),
202 /// Entity::new(3, 1),
203 /// ]);
204 ///
205 /// // Keep only entities with even indices
206 /// children.retain(|e| e.index() % 2 == 0);
207 ///
208 /// assert_eq!(children.len(), 1);
209 /// assert!(children.contains(Entity::new(2, 1)));
210 /// ```
211 #[inline]
212 pub fn retain<F>(&mut self, f: F)
213 where
214 F: FnMut(&Entity) -> bool,
215 {
216 self.children.retain(f);
217 }
218
219 /// Sorts children by their entity index for deterministic ordering.
220 pub fn sort_by_index(&mut self) {
221 self.children.sort_by_key(|e| e.index());
222 }
223
224 /// Sorts children using a custom comparison function.
225 pub fn sort_by<F>(&mut self, compare: F)
226 where
227 F: FnMut(&Entity, &Entity) -> std::cmp::Ordering,
228 {
229 self.children.sort_by(compare);
230 }
231}
232
233impl Default for Children {
234 #[inline]
235 fn default() -> Self {
236 Self::new()
237 }
238}
239
240impl fmt::Debug for Children {
241 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
242 f.debug_struct("Children")
243 .field("count", &self.children.len())
244 .field("children", &self.children)
245 .finish()
246 }
247}
248
249impl fmt::Display for Children {
250 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
251 write!(f, "Children({})", self.children.len())
252 }
253}
254
255impl<'a> IntoIterator for &'a Children {
256 type Item = &'a Entity;
257 type IntoIter = std::slice::Iter<'a, Entity>;
258
259 #[inline]
260 fn into_iter(self) -> Self::IntoIter {
261 self.children.iter()
262 }
263}
264
265impl IntoIterator for Children {
266 type Item = Entity;
267 type IntoIter = std::vec::IntoIter<Entity>;
268
269 #[inline]
270 fn into_iter(self) -> Self::IntoIter {
271 self.children.into_iter()
272 }
273}
274
275impl From<Vec<Entity>> for Children {
276 #[inline]
277 fn from(children: Vec<Entity>) -> Self {
278 Self { children }
279 }
280}
281
282impl From<&[Entity]> for Children {
283 #[inline]
284 fn from(children: &[Entity]) -> Self {
285 Self::from_slice(children)
286 }
287}
288
289impl From<Children> for Vec<Entity> {
290 #[inline]
291 fn from(children: Children) -> Self {
292 children.children
293 }
294}
295
296// Implement Component trait
297impl Component for Children {}