use std::{collections::BTreeMap, mem::MaybeUninit};
use hashbrown::HashMap;
use hibitset::BitSetLike;
use crate::{
storage::{DistinctStorage, UnprotectedStorage},
world::Index,
};
pub trait SliceAccess<T> {
type Element;
fn as_slice(&self) -> &[Self::Element];
fn as_mut_slice(&mut self) -> &mut [Self::Element];
}
pub struct BTreeStorage<T>(BTreeMap<Index, T>);
impl<T> Default for BTreeStorage<T> {
fn default() -> Self {
Self(Default::default())
}
}
impl<T> UnprotectedStorage<T> for BTreeStorage<T> {
unsafe fn clean<B>(&mut self, _has: B)
where
B: BitSetLike,
{
}
unsafe fn get(&self, id: Index) -> &T {
&self.0[&id]
}
unsafe fn get_mut(&mut self, id: Index) -> &mut T {
self.0.get_mut(&id).unwrap()
}
unsafe fn insert(&mut self, id: Index, v: T) {
self.0.insert(id, v);
}
unsafe fn remove(&mut self, id: Index) -> T {
self.0.remove(&id).unwrap()
}
}
unsafe impl<T> DistinctStorage for BTreeStorage<T> {}
pub struct HashMapStorage<T>(HashMap<Index, T>);
impl<T> Default for HashMapStorage<T> {
fn default() -> Self {
Self(Default::default())
}
}
impl<T> UnprotectedStorage<T> for HashMapStorage<T> {
unsafe fn clean<B>(&mut self, _has: B)
where
B: BitSetLike,
{
}
unsafe fn get(&self, id: Index) -> &T {
&self.0[&id]
}
unsafe fn get_mut(&mut self, id: Index) -> &mut T {
self.0.get_mut(&id).unwrap()
}
unsafe fn insert(&mut self, id: Index, v: T) {
self.0.insert(id, v);
}
unsafe fn remove(&mut self, id: Index) -> T {
self.0.remove(&id).unwrap()
}
}
unsafe impl<T> DistinctStorage for HashMapStorage<T> {}
pub struct DenseVecStorage<T> {
data: Vec<T>,
entity_id: Vec<Index>,
data_id: Vec<MaybeUninit<Index>>,
}
impl<T> Default for DenseVecStorage<T> {
fn default() -> Self {
Self {
data: Default::default(),
entity_id: Default::default(),
data_id: Default::default(),
}
}
}
impl<T> SliceAccess<T> for DenseVecStorage<T> {
type Element = T;
#[inline]
fn as_slice(&self) -> &[Self::Element] {
self.data.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [Self::Element] {
self.data.as_mut_slice()
}
}
impl<T> UnprotectedStorage<T> for DenseVecStorage<T> {
unsafe fn clean<B>(&mut self, _has: B)
where
B: BitSetLike,
{
}
unsafe fn get(&self, id: Index) -> &T {
let did = self.data_id.get_unchecked(id as usize).assume_init();
self.data.get_unchecked(did as usize)
}
unsafe fn get_mut(&mut self, id: Index) -> &mut T {
let did = self.data_id.get_unchecked(id as usize).assume_init();
self.data.get_unchecked_mut(did as usize)
}
unsafe fn insert(&mut self, id: Index, v: T) {
let id = id as usize;
if self.data_id.len() <= id {
let delta = id + 1 - self.data_id.len();
self.data_id.reserve(delta);
self.data_id.set_len(id + 1);
}
self.data_id
.get_unchecked_mut(id)
.as_mut_ptr()
.write(self.data.len() as Index);
self.entity_id.push(id as Index);
self.data.push(v);
}
unsafe fn remove(&mut self, id: Index) -> T {
let did = self.data_id.get_unchecked(id as usize).assume_init();
let last = *self.entity_id.last().unwrap();
self.data_id
.get_unchecked_mut(last as usize)
.as_mut_ptr()
.write(did);
self.entity_id.swap_remove(did as usize);
self.data.swap_remove(did as usize)
}
}
unsafe impl<T> DistinctStorage for DenseVecStorage<T> {}
pub struct NullStorage<T>(T);
impl<T> UnprotectedStorage<T> for NullStorage<T>
where
T: Default,
{
unsafe fn clean<B>(&mut self, _has: B)
where
B: BitSetLike,
{
}
unsafe fn get(&self, _: Index) -> &T {
&self.0
}
unsafe fn get_mut(&mut self, _: Index) -> &mut T {
&mut self.0
}
unsafe fn insert(&mut self, _: Index, _: T) {}
unsafe fn remove(&mut self, _: Index) -> T {
Default::default()
}
}
impl<T> Default for NullStorage<T>
where
T: Default,
{
fn default() -> Self {
use std::mem::size_of;
assert_eq!(size_of::<T>(), 0, "NullStorage can only be used with ZST");
NullStorage(Default::default())
}
}
unsafe impl<T> DistinctStorage for NullStorage<T> {}
pub struct VecStorage<T>(Vec<MaybeUninit<T>>);
impl<T> Default for VecStorage<T> {
fn default() -> Self {
Self(Default::default())
}
}
impl<T> SliceAccess<T> for VecStorage<T> {
type Element = MaybeUninit<T>;
#[inline]
fn as_slice(&self) -> &[Self::Element] {
self.0.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [Self::Element] {
self.0.as_mut_slice()
}
}
impl<T> UnprotectedStorage<T> for VecStorage<T> {
unsafe fn clean<B>(&mut self, has: B)
where
B: BitSetLike,
{
use std::ptr;
for (i, v) in self.0.iter_mut().enumerate() {
if has.contains(i as u32) {
ptr::drop_in_place(&mut *v.as_mut_ptr());
}
}
self.0.set_len(0);
}
unsafe fn get(&self, id: Index) -> &T {
&*self.0.get_unchecked(id as usize).as_ptr()
}
unsafe fn get_mut(&mut self, id: Index) -> &mut T {
&mut *self.0.get_unchecked_mut(id as usize).as_mut_ptr()
}
unsafe fn insert(&mut self, id: Index, v: T) {
let id = id as usize;
if self.0.len() <= id {
let delta = id + 1 - self.0.len();
self.0.reserve(delta);
self.0.set_len(id + 1);
}
*self.0.get_unchecked_mut(id as usize) = MaybeUninit::new(v);
}
unsafe fn remove(&mut self, id: Index) -> T {
use std::ptr;
ptr::read(self.get(id))
}
}
unsafe impl<T> DistinctStorage for VecStorage<T> {}
pub struct DefaultVecStorage<T>(Vec<T>);
impl<T> Default for DefaultVecStorage<T> {
fn default() -> Self {
Self(Default::default())
}
}
impl<T> UnprotectedStorage<T> for DefaultVecStorage<T>
where
T: Default,
{
unsafe fn clean<B>(&mut self, _has: B)
where
B: BitSetLike,
{
self.0.clear();
}
unsafe fn get(&self, id: Index) -> &T {
self.0.get_unchecked(id as usize)
}
unsafe fn get_mut(&mut self, id: Index) -> &mut T {
self.0.get_unchecked_mut(id as usize)
}
unsafe fn insert(&mut self, id: Index, v: T) {
let id = id as usize;
if self.0.len() <= id {
self.0.resize_with(id, Default::default);
self.0.push(v)
} else {
self.0[id] = v;
}
}
unsafe fn remove(&mut self, id: Index) -> T {
let mut v = T::default();
std::ptr::swap(self.0.get_unchecked_mut(id as usize), &mut v);
v
}
}
unsafe impl<T> DistinctStorage for DefaultVecStorage<T> {}
impl<T> SliceAccess<T> for DefaultVecStorage<T> {
type Element = T;
#[inline]
fn as_slice(&self) -> &[Self::Element] {
self.0.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [Self::Element] {
self.0.as_mut_slice()
}
}