use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Not};
use hibitset::{BitSet, BitSetLike};
use crate::{
component::Component,
entity::{Entities, Entity, Index},
error::Error,
join::{Join, ParJoin},
resource::Ref,
storage::MaskedStorage,
};
use super::{AntiStorage, DistinctStorage, Drain, Storage};
pub struct StorageWrapper<'a, T, D> {
data: D,
entities: Ref<'a, Entities>,
phantom: PhantomData<T>,
}
impl<'a, T, D> StorageWrapper<'a, T, D> {
pub fn new(data: D, entities: Ref<'a, Entities>) -> Self {
Self {
data,
entities,
phantom: PhantomData,
}
}
}
impl<'a, T, D> StorageWrapper<'a, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
pub fn fetched_entities(&self) -> &Entities {
&self.entities
}
pub fn get(&self, e: Entity) -> Option<&T> {
let index = e.index();
if self.data.mask().contains(index) && self.entities.is_alive(e) {
Some(unsafe { self.data.storage().get(index) })
} else {
None
}
}
pub fn count(&self) -> usize {
self.mask().iter().count()
}
pub fn is_empty(&self) -> bool {
self.mask().is_empty()
}
pub fn contains(&self, e: Entity) -> bool {
let index = e.index();
self.data.mask().contains(index) && self.entities.is_alive(e)
}
pub fn mask(&self) -> &BitSet {
&self.data.mask()
}
pub fn not(&self) -> AntiStorage<'_> {
AntiStorage(&self.data.mask())
}
}
impl<'a, T, D> StorageWrapper<'a, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
pub fn get_mut(&mut self, e: Entity) -> Option<&mut T> {
let index = e.index();
if self.data.mask().contains(index) && self.entities.is_alive(e) {
Some(unsafe { self.data.storage_mut().get_mut(index) })
} else {
None
}
}
pub fn insert(&mut self, entity: Entity, component: T) -> Result<Option<T>, Error> {
if !self.entities.is_alive(entity) {
return Err(Error::EntityIsNotAlive(entity));
}
Ok(self.data.insert(entity, component))
}
pub fn remove(&mut self, e: Entity) -> Option<T> {
let index = e.index();
if self.entities.is_alive(e) {
self.data.remove(index)
} else {
None
}
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn drain(&mut self) -> Drain<T> {
Drain {
data: &mut self.data,
}
}
}
impl<'a, T: Component, D> DistinctStorage for StorageWrapper<'a, T, D> where
T::Storage: DistinctStorage
{
}
impl<'a, 'e, T, D> Not for &'a StorageWrapper<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
type Output = AntiStorage<'a>;
fn not(self) -> Self::Output {
AntiStorage(&self.data.mask())
}
}
impl<'a, 'e, T, D> Join for &'a StorageWrapper<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
type Mask = &'a BitSet;
type Type = &'a T;
type Value = &'a T::Storage;
unsafe fn open(self) -> (Self::Mask, Self::Value) {
(self.data.mask(), self.data.storage())
}
unsafe fn get(v: &mut Self::Value, i: Index) -> &'a T {
(**v).get(i)
}
}
impl<'a, 'e, T, D> Join for &'a mut StorageWrapper<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
type Mask = &'a BitSet;
type Type = &'a mut T;
type Value = &'a T::Storage;
unsafe fn open(self) -> (Self::Mask, Self::Value) {
(self.data.mask(), self.data.storage())
}
unsafe fn get(v: &mut Self::Value, i: Index) -> &'a mut T {
let value: *mut T::Storage = *v as *const T::Storage as *mut T::Storage;
(*value).get_mut(i)
}
}
impl<'a, 'e, T, D> ParJoin for &'a StorageWrapper<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
T::Storage: Sync,
{
}
impl<'a, 'e, T, D> ParJoin for &'a mut StorageWrapper<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
T::Storage: Sync + DistinctStorage,
{
}