async_ecs/storage/
vec_storage.rs

1use std::mem::MaybeUninit;
2use std::ptr::{drop_in_place, read};
3
4use hibitset::BitSetLike;
5
6use crate::entity::Index;
7
8use super::{DistinctStorage, Storage};
9
10/// Vector storage. Uses a simple `Vec`. Supposed to have maximum
11/// performance for the components mostly present in entities.
12///
13/// `as_slice()` and `as_mut_slice()` indices correspond to
14/// entity IDs. These can be compared to other `VecStorage`s, to
15/// other `DefaultVecStorage`s, and to `Entity::id()`s for live
16/// entities.
17pub struct VecStorage<T>(Vec<MaybeUninit<T>>);
18
19impl<T> Storage<T> for VecStorage<T> {
20    unsafe fn get(&self, index: Index) -> &T {
21        &*self.0.get_unchecked(index as usize).as_ptr()
22    }
23
24    unsafe fn get_mut(&mut self, index: Index) -> &mut T {
25        &mut *self.0.get_unchecked_mut(index as usize).as_mut_ptr()
26    }
27
28    unsafe fn insert(&mut self, index: Index, value: T) {
29        let index = index as usize;
30
31        if self.0.len() <= index {
32            let delta = index + 1 - self.0.len();
33
34            self.0.reserve(delta);
35
36            self.0.set_len(index + 1);
37        }
38
39        *self.0.get_unchecked_mut(index) = MaybeUninit::new(value);
40    }
41
42    unsafe fn remove(&mut self, index: Index) -> T {
43        read(self.get(index))
44    }
45
46    unsafe fn clean<B>(&mut self, has: B)
47    where
48        B: BitSetLike,
49    {
50        for (i, v) in self.0.iter_mut().enumerate() {
51            if has.contains(i as u32) {
52                // drop in place
53                drop_in_place(&mut *v.as_mut_ptr());
54            }
55        }
56
57        self.0.set_len(0);
58    }
59}
60
61impl<T> DistinctStorage for VecStorage<T> {}
62
63impl<T> Default for VecStorage<T> {
64    fn default() -> Self {
65        Self(Vec::new())
66    }
67}