Skip to main content

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 {}