Skip to content

Instantly share code, notes, and snippets.

@seivan
Created July 30, 2019 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seivan/03c0f5659ad1ab890337e1335da58ad6 to your computer and use it in GitHub Desktop.
Save seivan/03c0f5659ad1ab890337e1335da58ad6 to your computer and use it in GitHub Desktop.
Dense and Sparse vector for faster O(1) lookup, insert and removal (no order)
#[derive(Debug)]
pub struct DenseVecStorage<T>
where
T: Component,
{
components: Vec<T>,
entity_ids: Vec<usize>,
component_ids: Vec<usize>,
}
impl<T> DenseVecStorage<T>
where
T: Component,
{
fn new() -> Self {
DenseVecStorage {
components: Vec::new(),
entity_ids: Vec::new(),
component_ids: Vec::new(),
}
}
unsafe fn get(&self, id: &usize) -> &T {
let component_id = self.component_ids.get_unchecked(*id);
self.components.get_unchecked(*component_id)
}
unsafe fn get_mut(&mut self, id: &usize) -> &mut T {
let component_id = self.component_ids.get_unchecked(*id);
self.components.get_unchecked_mut(*component_id)
}
unsafe fn insert(&mut self, id: &usize, component: T) {
let id = *id;
if self.component_ids.len() <= id {
let delta = id + 1 - self.component_ids.len();
self.component_ids.reserve(delta);
self.component_ids.set_len(id + 1);
}
*self.component_ids.get_unchecked_mut(id) = self.components.len();
self.entity_ids.push(id);
self.components.push(component);
}
// . We swap the element to be removed with the element at the end of the list, then pop that element off the end:
unsafe fn remove(&mut self, id: &usize) -> T {
let id = *id;
let component_id = *self.component_ids.get_unchecked(id);
let last = *self.entity_ids.last().unwrap();
*self.component_ids.get_unchecked_mut(last) = component_id;
self.entity_ids.swap_remove(component_id);
self.components.swap_remove(component_id)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment