checs/
component.rs

1//! Storing and managing components.
2
3use crate::entity;
4use crate::iter;
5use crate::sparse;
6
7/// A densely packed growable array for associating entities with components.
8///
9/// # Examples
10///
11/// ```
12/// use checs::ComponentVec;
13///
14/// let mut entities = checs::entity::Allocator::new();
15///
16/// let e0 = entities.alloc();
17/// let e1 = entities.alloc();
18/// let e2 = entities.alloc();
19/// let e3 = entities.alloc();
20///
21/// let mut vec = ComponentVec::new();
22/// vec.insert(e0, 42);
23/// vec.insert(e1, 17);
24/// vec.insert(e2, 99);
25/// assert_eq!(vec.len(), 3);
26///
27/// assert_eq!(vec.get(e0), Some(&42));
28/// assert_eq!(vec.contains(e1), true);
29/// assert_eq!(vec.get_mut(e2), Some(&mut 99));
30/// assert_eq!(vec.get(e3), None);
31///
32/// assert_eq!(vec.remove(e2), Some(99));
33/// assert_eq!(vec.get(e2), None);
34///
35/// for (entity, int) in &vec {
36///     println!("{entity:?}: {int}");
37/// }
38/// ```
39pub struct ComponentVec<T> {
40    entities: sparse::Set,
41    components: Vec<T>,
42}
43
44impl<T> ComponentVec<T> {
45    /// Constructs a new empty `ComponentVec<T>`.
46    ///
47    /// The vector will not allocate until elements are pushed onto it.
48    #[must_use]
49    #[inline]
50    pub fn new() -> Self {
51        Self {
52            components: Vec::new(),
53            entities: sparse::Set::new(),
54        }
55    }
56
57    /// Returns the number of elements in the vector, also referred to as its 'length'.
58    #[must_use]
59    #[inline]
60    pub fn len(&self) -> usize {
61        self.components.len()
62    }
63
64    /// Returns `true` if the vector contains no elements.
65    #[must_use]
66    #[inline]
67    pub fn is_empty(&self) -> bool {
68        self.components.is_empty()
69    }
70
71    /// Returns `true` if the vector contains a component for the `entity`.
72    #[must_use]
73    #[inline]
74    pub fn contains(&self, entity: entity::Entity) -> bool {
75        self.entities.contains(entity)
76    }
77
78    /// Returns a reference to the `entity`'s component, or `None` if the entity does not have that
79    /// component.
80    #[must_use]
81    #[inline]
82    pub fn get(&self, entity: entity::Entity) -> Option<&T> {
83        let index = self.entities.index_of(entity)?;
84        self.components.get(index)
85    }
86
87    /// Returns a mutable reference to an `entity`'s component, or `None` if the `entity` does not
88    /// have that component.
89    #[must_use]
90    #[inline]
91    pub fn get_mut(&mut self, entity: entity::Entity) -> Option<&mut T> {
92        let index = self.entities.index_of(entity)?;
93        self.components.get_mut(index)
94    }
95
96    /// Adds a component to the `entity`.
97    ///
98    /// If the `entity` already had that component its value is updated and the old value is
99    /// returned.
100    #[inline]
101    pub fn insert(&mut self, entity: entity::Entity, component: T) -> Option<T> {
102        if let Some(value) = self.get_mut(entity) {
103            Some(std::mem::replace(value, component))
104        } else {
105            self.entities.insert(entity);
106            self.components.push(component);
107            None
108        }
109    }
110
111    /// Removes a component from the `entity` and returns the component.
112    #[inline]
113    pub fn remove(&mut self, entity: entity::Entity) -> Option<T> {
114        if let Some(index) = self.entities.index_of(entity) {
115            self.entities.remove(entity);
116            Some(self.components.swap_remove(index))
117        } else {
118            None
119        }
120    }
121
122    /// Reserves capacity for at least `additional` more elements to be inserted into the vector.
123    #[inline]
124    pub fn reserve(&mut self, additional: usize) {
125        self.entities.reserve(additional);
126        self.components.reserve(additional);
127    }
128
129    /// Returns an iterator that yields entities and their components as references.
130    #[inline]
131    pub fn iter(&self) -> Iter<'_, T> {
132        self.entities.iter().zip(self.components.iter())
133    }
134
135    /// Returns an iterator that yields entities and their components as mutable references.
136    #[inline]
137    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
138        self.entities.iter().zip(self.components.iter_mut())
139    }
140}
141
142impl<T> Default for ComponentVec<T> {
143    #[inline]
144    fn default() -> ComponentVec<T> {
145        ComponentVec::new()
146    }
147}
148
149use std::iter::Zip;
150use std::slice;
151
152/// An iterator that yields entities and their components as references.
153pub type Iter<'a, T> = Zip<iter::Iter<'a, entity::Entity>, slice::Iter<'a, T>>;
154
155/// An iterator that yields entities and their components as mutable references.
156pub type IterMut<'a, T> = Zip<iter::Iter<'a, entity::Entity>, slice::IterMut<'a, T>>;
157
158impl<'a, T> IntoIterator for &'a ComponentVec<T> {
159    type IntoIter = Iter<'a, T>;
160    type Item = (entity::Entity, &'a T);
161
162    #[inline]
163    fn into_iter(self) -> Self::IntoIter {
164        self.iter()
165    }
166}
167
168impl<'a, T> IntoIterator for &'a mut ComponentVec<T> {
169    type IntoIter = IterMut<'a, T>;
170    type Item = (entity::Entity, &'a mut T);
171
172    #[inline]
173    fn into_iter(self) -> Self::IntoIter {
174        self.iter_mut()
175    }
176}
177
178mod sealed {
179    use super::ComponentVec;
180
181    pub trait Sealed {}
182
183    impl<T> Sealed for &ComponentVec<T> {}
184    impl<T> Sealed for &mut ComponentVec<T> {}
185}
186
187use sealed::Sealed;
188
189/// A reference to a [`ComponentVec`] that is generic over mutability.
190///
191/// # Note
192///
193/// This type is not meant to be used directly. It is used as part of a [`Query`], which is why it
194/// must be public.
195///
196/// [`Query`]: crate::Query
197pub struct RefOrMut<'a, T> {
198    pub(crate) entities: &'a sparse::Set,
199    components: T,
200}
201
202/// A trait for converting a value into a [`RefOrMut`].
203pub trait IntoRefOrMut<'a>: Sealed {
204    /// The type of slice containing the components. Either a shared or a mutable reference.
205    type Components;
206
207    /// Converts `self` into a [`RefOrMut`].
208    fn into_ref_or_mut(self) -> RefOrMut<'a, Self::Components>;
209}
210
211impl<'a, T> IntoRefOrMut<'a> for &'a ComponentVec<T> {
212    type Components = &'a [T];
213
214    #[inline]
215    fn into_ref_or_mut(self) -> RefOrMut<'a, Self::Components> {
216        RefOrMut {
217            entities: &self.entities,
218            components: &self.components,
219        }
220    }
221}
222
223impl<'a, T> IntoRefOrMut<'a> for &'a mut ComponentVec<T> {
224    type Components = &'a mut [T];
225
226    #[inline]
227    fn into_ref_or_mut(self) -> RefOrMut<'a, Self::Components> {
228        RefOrMut {
229            entities: &self.entities,
230            components: &mut self.components,
231        }
232    }
233}
234
235impl<'l, 'a, T> iter::Lifetime<'l> for RefOrMut<'a, &'a [T]> {
236    type Item = &'l T;
237}
238
239impl<'l, 'a, T> iter::Lifetime<'l> for RefOrMut<'a, &'a mut [T]> {
240    type Item = &'l mut T;
241}
242
243/// A trait for returning a shared or mutable reference to a component.
244pub trait GetRefOrMut: for<'l> iter::Lifetime<'l> {
245    /// Returns a shared or mutable reference to an `entity`'s component, or `None` if the `entity`
246    /// does not have that component.
247    fn get_ref_or_mut(
248        &mut self,
249        entity: entity::Entity,
250    ) -> Option<<Self as iter::Lifetime<'_>>::Item>;
251}
252
253impl<'a, T> GetRefOrMut for RefOrMut<'a, &'a [T]> {
254    #[inline]
255    fn get_ref_or_mut(
256        &mut self,
257        entity: entity::Entity,
258    ) -> Option<<Self as iter::Lifetime<'_>>::Item> {
259        let index = self.entities.index_of(entity)?;
260        self.components.get(index)
261    }
262}
263
264impl<'a, T> GetRefOrMut for RefOrMut<'a, &'a mut [T]> {
265    #[inline]
266    fn get_ref_or_mut(
267        &mut self,
268        entity: entity::Entity,
269    ) -> Option<<Self as iter::Lifetime<'_>>::Item> {
270        let index = self.entities.index_of(entity)?;
271        self.components.get_mut(index)
272    }
273}
274
275#[cfg(test)]
276mod tests {
277    use super::*;
278
279    #[test]
280    fn components_i32_put_then_delete() {
281        let mut components = ComponentVec::new();
282
283        let e0 = entity::Entity::from(0);
284        let e1 = entity::Entity::from(1);
285
286        components.insert(e0, 42);
287        assert_eq!(components.components.len(), 1);
288
289        components.insert(e1, 17);
290        assert_eq!(components.components.len(), 2);
291
292        assert_eq!(components.get(e0), Some(&42));
293        assert_eq!(components.get(e1), Some(&17));
294        assert_eq!(components.get_mut(e0), Some(&mut 42));
295        assert_eq!(components.get_mut(e1), Some(&mut 17));
296
297        components.remove(e0);
298        assert_eq!(components.components.len(), 1);
299
300        assert_eq!(components.get(e0), None);
301        assert_eq!(components.get(e1), Some(&17));
302        assert_eq!(components.get_mut(e0), None);
303        assert_eq!(components.get_mut(e1), Some(&mut 17));
304
305        components.remove(e1);
306        assert_eq!(components.components.len(), 0);
307
308        assert_eq!(components.get(e0), None);
309        assert_eq!(components.get(e1), None);
310        assert_eq!(components.get_mut(e0), None);
311        assert_eq!(components.get_mut(e1), None);
312    }
313
314    #[test]
315    fn reserve() {
316        let mut vec = ComponentVec::<i32>::new();
317
318        assert_eq!(vec.components.capacity(), 0);
319
320        let additional = 100;
321        vec.reserve(additional);
322
323        assert!(vec.components.capacity() >= vec.components.len() + additional);
324    }
325
326    #[test]
327    fn contains() {
328        let mut components = ComponentVec::<i32>::new();
329
330        let e0 = entity::Entity::from(0);
331        let e1 = entity::Entity::from(1);
332        let e2 = entity::Entity::from(2);
333
334        components.insert(e0, 42);
335        components.insert(e2, 17);
336
337        assert_eq!(components.contains(e0), true);
338        assert_eq!(components.contains(e1), false);
339        assert_eq!(components.contains(e2), true);
340    }
341}