Skip to main content

goud_engine/ecs/sparse_set/
ops.rs

1//! Iteration and advanced accessor methods for [`SparseSet`].
2//!
3//! This module extends `SparseSet<T>` with iteration helpers and
4//! lower-level dense-index accessors used by storage layers.
5
6use super::super::Entity;
7use super::core::SparseSet;
8use super::iter::{SparseSetIter, SparseSetIterMut};
9
10impl<T> SparseSet<T> {
11    // =========================================================================
12    // Iteration
13    // =========================================================================
14
15    /// Returns an iterator over `(Entity, &T)` pairs.
16    ///
17    /// Iteration is cache-friendly because it traverses the dense array
18    /// sequentially.
19    ///
20    /// # Example
21    ///
22    /// ```
23    /// use goud_engine::ecs::{Entity, SparseSet};
24    ///
25    /// let mut set = SparseSet::new();
26    /// set.insert(Entity::new(0, 1), "a");
27    /// set.insert(Entity::new(1, 1), "b");
28    ///
29    /// for (entity, value) in set.iter() {
30    ///     println!("{}: {}", entity, value);
31    /// }
32    /// ```
33    #[inline]
34    pub fn iter(&self) -> SparseSetIter<'_, T> {
35        SparseSetIter {
36            dense: self.dense.iter(),
37            values: self.values.iter(),
38        }
39    }
40
41    /// Returns a mutable iterator over `(Entity, &mut T)` pairs.
42    ///
43    /// # Example
44    ///
45    /// ```
46    /// use goud_engine::ecs::{Entity, SparseSet};
47    ///
48    /// let mut set = SparseSet::new();
49    /// set.insert(Entity::new(0, 1), 1);
50    /// set.insert(Entity::new(1, 1), 2);
51    ///
52    /// for (_, value) in set.iter_mut() {
53    ///     *value *= 10;
54    /// }
55    ///
56    /// assert_eq!(set.get(Entity::new(0, 1)), Some(&10));
57    /// assert_eq!(set.get(Entity::new(1, 1)), Some(&20));
58    /// ```
59    #[inline]
60    pub fn iter_mut(&mut self) -> SparseSetIterMut<'_, T> {
61        SparseSetIterMut {
62            dense: self.dense.iter(),
63            values: self.values.iter_mut(),
64        }
65    }
66
67    /// Returns an iterator over all entities in the set.
68    ///
69    /// # Example
70    ///
71    /// ```
72    /// use goud_engine::ecs::{Entity, SparseSet};
73    ///
74    /// let mut set = SparseSet::new();
75    /// set.insert(Entity::new(0, 1), "a");
76    /// set.insert(Entity::new(5, 1), "b");
77    ///
78    /// let entities: Vec<_> = set.entities().collect();
79    /// assert_eq!(entities.len(), 2);
80    /// ```
81    #[inline]
82    pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
83        self.dense.iter().copied()
84    }
85
86    /// Returns an iterator over all values in the set.
87    ///
88    /// # Example
89    ///
90    /// ```
91    /// use goud_engine::ecs::{Entity, SparseSet};
92    ///
93    /// let mut set = SparseSet::new();
94    /// set.insert(Entity::new(0, 1), 10);
95    /// set.insert(Entity::new(5, 1), 20);
96    ///
97    /// let sum: i32 = set.values().sum();
98    /// assert_eq!(sum, 30);
99    /// ```
100    #[inline]
101    pub fn values(&self) -> impl Iterator<Item = &T> {
102        self.values.iter()
103    }
104
105    /// Returns a mutable iterator over all values in the set.
106    ///
107    /// # Example
108    ///
109    /// ```
110    /// use goud_engine::ecs::{Entity, SparseSet};
111    ///
112    /// let mut set = SparseSet::new();
113    /// set.insert(Entity::new(0, 1), 10);
114    /// set.insert(Entity::new(1, 1), 20);
115    ///
116    /// for value in set.values_mut() {
117    ///     *value += 1;
118    /// }
119    ///
120    /// let sum: i32 = set.values().sum();
121    /// assert_eq!(sum, 32); // 11 + 21
122    /// ```
123    #[inline]
124    pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
125        self.values.iter_mut()
126    }
127
128    // =========================================================================
129    // Advanced / Internal Methods
130    // =========================================================================
131
132    /// Returns the raw entity array for direct access.
133    ///
134    /// This is useful for bulk operations or implementing custom iterators.
135    ///
136    /// # Example
137    ///
138    /// ```
139    /// use goud_engine::ecs::{Entity, SparseSet};
140    ///
141    /// let mut set = SparseSet::new();
142    /// set.insert(Entity::new(0, 1), "a");
143    /// set.insert(Entity::new(1, 1), "b");
144    ///
145    /// let dense = set.dense();
146    /// assert_eq!(dense.len(), 2);
147    /// ```
148    #[inline]
149    pub fn dense(&self) -> &[Entity] {
150        &self.dense
151    }
152
153    /// Returns the dense index for an entity, if it exists.
154    ///
155    /// This is an advanced method for implementing custom storage operations.
156    ///
157    /// # Arguments
158    ///
159    /// * `entity` - The entity to look up
160    ///
161    /// # Returns
162    ///
163    /// The index in the dense array, or `None` if the entity has no value.
164    #[inline]
165    pub fn dense_index(&self, entity: Entity) -> Option<usize> {
166        if entity.is_placeholder() {
167            return None;
168        }
169
170        let index = entity.index() as usize;
171
172        if index >= self.sparse.len() {
173            return None;
174        }
175
176        self.sparse[index]
177    }
178
179    /// Returns the value at the given dense index.
180    ///
181    /// # Safety
182    ///
183    /// This method does not validate the index. Use `dense_index()` to get
184    /// a valid index first.
185    ///
186    /// # Arguments
187    ///
188    /// * `dense_index` - Index into the dense/values arrays
189    #[inline]
190    pub fn get_by_dense_index(&self, dense_index: usize) -> Option<&T> {
191        self.values.get(dense_index)
192    }
193
194    /// Returns a mutable reference to the value at the given dense index.
195    #[inline]
196    pub fn get_mut_by_dense_index(&mut self, dense_index: usize) -> Option<&mut T> {
197        self.values.get_mut(dense_index)
198    }
199}