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