use std::mem::swap;
use hibitset::BitSet;
use crate::{
component::Component,
entity::{Entity, Index},
storage::Storage,
};
pub struct MaskedStorage<T: Component> {
mask: BitSet,
inner: T::Storage,
}
impl<T: Component> MaskedStorage<T> {
pub fn new(inner: T::Storage) -> Self {
Self {
mask: BitSet::new(),
inner,
}
}
pub fn mask(&self) -> &BitSet {
&self.mask
}
pub fn storage(&self) -> &T::Storage {
&self.inner
}
pub fn storage_mut(&mut self) -> &mut T::Storage {
&mut self.inner
}
pub fn insert(&mut self, entity: Entity, mut component: T) -> Option<T> {
let index = entity.index();
if self.mask.contains(index) {
swap(&mut component, unsafe { self.inner.get_mut(index) });
Some(component)
} else {
self.mask.add(index);
unsafe { self.inner.insert(index, component) };
None
}
}
pub fn clear(&mut self) {
unsafe { self.inner.clean(&self.mask) };
self.mask.clear();
}
pub fn remove(&mut self, index: Index) -> Option<T> {
if self.mask.remove(index) {
Some(unsafe { self.inner.remove(index) })
} else {
None
}
}
pub fn drop(&mut self, index: Index) {
if self.mask.remove(index) {
unsafe { self.inner.drop(index) };
}
}
}