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]
}
}