pico_ecs/
component_storage.rs

1use super::component::Component;
2use super::entity::Entity;
3use crate::MAX_ENTITIES;
4
5/// Storage for a specific component type
6pub struct ComponentStorage<T: Component> {
7    /// Sparse array - indexed by entity ID
8    /// None means entity doesn't have this component
9    components: [Option<T>; MAX_ENTITIES],
10    /// Count of active components
11    count: usize,
12}
13
14impl<T: Component> ComponentStorage<T> {
15    /// Create new empty component storage
16    pub fn new() -> Self {
17        ComponentStorage {
18            components: [const { None }; MAX_ENTITIES],
19            count: 0,
20        }
21    }
22    
23    /// Add a component to an entity
24    pub fn insert(&mut self, entity: Entity, component: T) {
25        let idx = entity.id();
26        if idx < MAX_ENTITIES {
27            if self.components[idx].is_none() {
28                self.count += 1;
29            }
30            self.components[idx] = Some(component);
31        }
32    }
33    
34    /// Remove a component from an entity
35    pub fn remove(&mut self, entity: Entity) -> Option<T> {
36        let idx = entity.id();
37        if idx < MAX_ENTITIES {
38            if let Some(comp) = self.components[idx].take() {
39                self.count -= 1;
40                return Some(comp);
41            }
42        }
43        None
44    }
45    
46    /// Get a component for an entity
47    pub fn get(&self, entity: Entity) -> Option<&T> {
48        let idx = entity.id();
49        if idx < MAX_ENTITIES {
50            self.components[idx].as_ref()
51        } else {
52            None
53        }
54    }
55    
56    /// Get a mutable component for an entity
57    pub fn get_mut(&mut self, entity: Entity) -> Option<&mut T> {
58        let idx = entity.id();
59        if idx < MAX_ENTITIES {
60            self.components[idx].as_mut()
61        } else {
62            None
63        }
64    }
65    
66    /// Check if entity has this component
67    pub fn has(&self, entity: Entity) -> bool {
68        let idx = entity.id();
69        idx < MAX_ENTITIES && self.components[idx].is_some()
70    }
71    
72    /// Get number of active components
73    pub fn count(&self) -> usize {
74        self.count
75    }
76    
77    /// Iterate over all entities with this component
78    pub fn iter(&self) -> impl Iterator<Item = (Entity, &T)> {
79        self.components
80            .iter()
81            .enumerate()
82            .filter_map(|(i, opt)| {
83                opt.as_ref().map(|c| (Entity(i as u8), c))
84            })
85    }
86    
87    /// Iterate mutably over all entities with this component
88    pub fn iter_mut(&mut self) -> impl Iterator<Item = (Entity, &mut T)> {
89        self.components
90            .iter_mut()
91            .enumerate()
92            .filter_map(|(i, opt)| {
93                opt.as_mut().map(|c| (Entity(i as u8), c))
94            })
95    }
96}