entity_component/
components.rs

1use crate::{create_bitset, Entity, BitSetVec, BitSet, ComponentIterator, ComponentIteratorMut, BITSET_SIZE};
2
3use std::collections::HashMap;
4use std::any::{TypeId, Any};
5use std::sync::Mutex;
6use atomic_refcell_try::AtomicRefMut;
7
8lazy_static::lazy_static! {
9    #[doc(hidden)]
10    pub static ref COMPONENT_REGISTRY: Mutex<HashMap<TypeId, Box<dyn Fn(AtomicRefMut<dyn Any+'static>, &[Entity]) + Send + Sync>>> = Mutex::new(HashMap::default());
11}
12
13/// Holds components of a given type indexed by `Entity`.
14/// We do not check if the given entity is alive here, this should be done using
15/// `Entities`.
16pub struct Components<T> {
17    bitset: BitSetVec,
18    components: Vec<Option<T>>,
19}
20
21impl<T: 'static> Default for Components<T> {
22    fn default() -> Self {
23        // Registers all the component downcasting and cleaning code in one globally accessible
24        // place. This seems to be the best way of doing it that doesn't involve
25        // heavily modifying how the `world_dispatcher` crate works.
26        COMPONENT_REGISTRY.lock().unwrap().insert(TypeId::of::<Self>(), Box::new(|any, entities| {
27            let mut me = AtomicRefMut::map(any, |j| j.downcast_mut::<Self>().unwrap());
28            for e in entities {
29                me.remove(*e);
30            }
31        }));
32        Self {
33            bitset: create_bitset(),
34            // Approximation of a good default.
35            components: Vec::with_capacity(BITSET_SIZE >> 4),
36        }
37    }
38}
39
40impl<T> Components<T> {
41    /// Inserts a component for the given `Entity` index.
42    /// Returns the previous component, if any.
43    pub fn insert(&mut self, entity: Entity, component: T) -> Option<T> {
44        let mut insertion = Some(component);
45        if self.bitset.bit_test(entity.index() as usize) {
46            std::mem::swap(
47                &mut insertion,
48                &mut self.components[entity.index() as usize],
49            );
50            insertion
51        } else {
52            self.allocate_enough(entity.index() as usize);
53            self.bitset.bit_set(entity.index() as usize);
54            self.components[entity.index() as usize] = insertion;
55            None
56        }
57    }
58    /// Ensures that we have the vec filled at least until the `until`
59    /// variable. Usually, set this to `entity.index`.
60    fn allocate_enough(&mut self, until: usize) {
61        if self.components.len() <= until {
62            let qty = (until - self.components.len()) + 1;
63            for _ in 0..qty {
64                self.components.push(None);
65            }
66        }
67    }
68    /// Gets an immutable reference to the component of `Entity`.
69    pub fn get(&self, entity: Entity) -> Option<&T> {
70        if self.bitset.bit_test(entity.index() as usize) {
71            self.components[entity.index() as usize].as_ref()
72        } else {
73            None
74        }
75    }
76    /// Gets a mutable reference to the component of `Entity`.
77    pub fn get_mut(&mut self, entity: Entity) -> Option<&mut T> {
78        if self.bitset.bit_test(entity.index() as usize) {
79            self.components[entity.index() as usize].as_mut()
80        } else {
81            None
82        }
83    }
84    /// Removes the component of `Entity`.
85    /// Returns `Some(T)` if the entity did have the component.
86    /// Returns `None` if the entity did not have the component.
87    pub fn remove(&mut self, entity: Entity) -> Option<T> {
88        let idx = entity.index() as usize;
89        if self.bitset.bit_test(idx) {
90            self.bitset.bit_reset(idx);
91            let mut ret = None;
92            std::mem::swap(&mut ret, &mut self.components[idx]);
93            ret
94        } else {
95            None
96        }
97    }
98    /// Iterates immutably over all components of this type.
99    /// Very fast but doesn't allow joining with other component types.
100    pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T> {
101        self.components.iter().flatten()
102    }
103    /// Iterates mutably over all components of this type.
104    /// Very fast but doesn't allow joining with other component types.
105    pub fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut T> {
106        self.components.iter_mut().flatten()
107    }
108    /// Iterates immutably over the components of this type where `bitset`
109    /// indicates the indices of entities.
110    /// Slower than `iter()` but allows joining between multiple component types.
111    pub fn iter_with_bitset<'a>(&'a self, bitset: std::rc::Rc<BitSetVec>) -> ComponentIterator<'a, T> {
112        ComponentIterator {
113            current_id: 0,
114            max_id: self.components.len(),
115            storage: &self.components,
116            bitset,
117        }
118    }
119    /// Iterates mutable over the components of this type where `bitset`
120    /// indicates the indices of entities.
121    /// Slower than `iter()` but allows joining between multiple component types.
122    pub fn iter_mut_with_bitset<'a>(
123        &'a mut self,
124        bitset: std::rc::Rc<BitSetVec>,
125    ) -> ComponentIteratorMut<'a, T> {
126        ComponentIteratorMut {
127            current_id: 0,
128            max_id: self.components.len(),
129            storage: &mut self.components,
130            bitset,
131        }
132    }
133    /// Returns the bitset indicating which entity indices have a component
134    /// associated to them.
135    /// Useful to build conditions between multiple `Components`' bitsets.
136    ///
137    /// For example, take two bitsets from two different `Components` types.
138    /// Then, bitset1.clone().bit_and(bitset2);
139    /// And finally, you can use bitset1 in `iter_with_bitset` and `iter_mut_with_bitset`.
140    /// This will iterate over the components of the entity only for entities that have both
141    /// components.
142    pub fn bitset(&self) -> &BitSetVec {
143        &self.bitset
144    }
145}
146
147#[cfg(test)]
148mod tests {
149    use crate::*;
150    #[test]
151    fn create_remove_components() {
152        #[derive(Debug, Clone, PartialEq, Eq)]
153        struct A;
154
155        let mut entities = Entities::default();
156        let e1 = entities.create();
157        let e2 = entities.create();
158        
159        let mut storage = Components::<A>::default();
160        storage.insert(e1, A);
161        storage.insert(e2, A);
162        assert!(storage.get(e1).is_some());
163        storage.remove(e1);
164        assert!(storage.get(e1).is_none());
165        assert_eq!(storage.iter().cloned().collect::<Vec<_>>(), vec![A])
166    }
167}
168
169