async_ecs/storage/
dense_vec_storage.rs

1use std::mem::MaybeUninit;
2
3use hibitset::BitSetLike;
4
5use crate::{entity::Index, storage::Storage};
6
7use super::DistinctStorage;
8
9/// Dense vector storage. Has a redirection 2-way table
10/// between entities and components, allowing to leave
11/// no gaps within the data.
12///
13/// Note that this only stores the data (`T`) densely; indices
14/// to the data are stored in a sparse `Vec`.
15///
16/// `as_slice()` and `as_mut_slice()` indices are local to this
17/// `DenseVecStorage` at this particular moment. These indices
18/// cannot be compared with indices from any other storage, and
19/// a particular entity's position within this slice may change
20/// over time.
21pub struct DenseVecStorage<T> {
22    data: Vec<T>,
23    entity_id: Vec<Index>,
24    data_id: Vec<MaybeUninit<Index>>,
25}
26
27impl<T> Default for DenseVecStorage<T> {
28    fn default() -> Self {
29        Self {
30            data: Default::default(),
31            entity_id: Default::default(),
32            data_id: Default::default(),
33        }
34    }
35}
36
37impl<T> Storage<T> for DenseVecStorage<T> {
38    unsafe fn get(&self, index: Index) -> &T {
39        let index = self.data_id.get_unchecked(index as usize).assume_init();
40
41        self.data.get_unchecked(index as usize)
42    }
43
44    unsafe fn get_mut(&mut self, index: Index) -> &mut T {
45        let index = self.data_id.get_unchecked(index as usize).assume_init();
46
47        self.data.get_unchecked_mut(index as usize)
48    }
49
50    unsafe fn insert(&mut self, index: Index, v: T) {
51        let index = index as usize;
52
53        if self.data_id.len() <= index {
54            let delta = index + 1 - self.data_id.len();
55            self.data_id.reserve(delta);
56            self.data_id.set_len(index + 1);
57        }
58
59        self.data_id
60            .get_unchecked_mut(index)
61            .as_mut_ptr()
62            .write(self.data.len() as Index);
63        self.entity_id.push(index as Index);
64        self.data.push(v);
65    }
66
67    unsafe fn remove(&mut self, index: Index) -> T {
68        let index = self.data_id.get_unchecked(index as usize).assume_init();
69        let last = *self.entity_id.last().unwrap();
70        self.data_id
71            .get_unchecked_mut(last as usize)
72            .as_mut_ptr()
73            .write(index);
74        self.entity_id.swap_remove(index as usize);
75        self.data.swap_remove(index as usize)
76    }
77
78    unsafe fn clean<B>(&mut self, _has: B)
79    where
80        B: BitSetLike,
81    {
82        // No Op
83    }
84}
85
86impl<T> DistinctStorage for DenseVecStorage<T> {}