rustbatch/entities/
storage.rs1pub struct ComponentArray<T> {
6 inner: Vec<Option<T>>,
7 ids: Vec<usize>,
8 len: usize,
9 id: usize,
10}
11
12impl<T> ComponentArray<T> {
13 #[inline]
14 pub fn new() -> Self {
15 Self {
16 inner: vec![None],
17 ids: vec![],
18 len: 0,
19 id: 0,
20 }
21 }
22
23 #[inline]
25 pub fn insert(&mut self, component: T) -> usize {
26 self.len = self.inner.len();
27 if self.ids.is_empty() {
28 self.inner.push(Some(component));
29 return self.len
30 }
31 self.len = self.ids.len() - 1;
32 self.id = self.ids[self.len];
33 self.inner[self.id] = Some(component);
34 self.ids.truncate(self.len);
35
36 self.id
37 }
38
39 #[inline]
40 pub fn len(&self) -> usize {
41 self.inner.len()
42 }
43
44 #[inline]
46 pub fn remove(&mut self, id: usize) -> T {
47 if let None = self.inner[id] {
48 panic!("value with given id is already none, call put_back and then remove, calling \
49 just get instead of remove produces memory leak because space is still considered occupied.");
50 }
51 self.ids.push(id);
52 unsafe { self.get(id).unwrap() }
53 }
54
55 #[inline]
56 pub fn remove_if_present(&mut self, id: usize) -> Option<T> {
57 if let None = self.inner[id] {
58 return None
59 }
60 self.ids.push(id);
61 unsafe { self.get(id) }
62 }
63
64 #[inline]
68 pub unsafe fn get(&mut self, id: usize) -> Option<T> {
69 std::mem::replace(&mut self.inner[id], None)
70 }
71
72 #[inline]
75 pub unsafe fn put_back(&mut self, id: usize, component: T) {
76 self.inner[id] = Some(component);
77 }
78
79 #[inline]
81 pub fn get_ref(&self, id: usize) -> &Option<T> {
82 &self.inner[id]
83 }
84
85 #[inline]
87 pub fn get_mut(&mut self, id: usize) -> &mut Option<T> {
88 &mut self.inner[id]
89 }
90}
91
92