use crate::archetype::entities::{ArchetypeEntities, EntitiesIter};
use crate::entity::ArchEntityId;
use crate::private::ComponentInfo;
use std::borrow::Borrow;
use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
#[derive(Default)]
pub struct UnsafeVec(UnsafeCell<Vec<u8>>);
pub trait Component: Send + Sync + 'static {}
impl Deref for UnsafeVec {
type Target = UnsafeCell<Vec<u8>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for UnsafeVec {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> Component for T where T: Send + Sync + 'static {}
pub struct ComponentStorage<'a, C, D> {
pub(crate) entities: &'a ArchetypeEntities,
pub(crate) step: usize,
pub(crate) info: &'a ComponentInfo,
pub(crate) data: D,
pub(crate) _ty: PhantomData<C>,
}
pub type ComponentStorageRef<'a, C> = ComponentStorage<'a, C, &'a UnsafeVec>;
pub type ComponentStorageMut<'a, C> = ComponentStorage<'a, C, &'a mut UnsafeVec>;
impl<'a, C, D: Borrow<UnsafeVec> + Copy> Clone for ComponentStorage<'a, C, D> {
fn clone(&self) -> Self {
Self {
entities: &self.entities,
step: self.step,
info: self.info,
data: self.data,
_ty: Default::default(),
}
}
}
impl<'a, C, D: Borrow<UnsafeVec> + Copy> Copy for ComponentStorage<'a, C, D> {}
impl<'a, C: Component, D: Borrow<UnsafeVec>> ComponentStorage<'a, C, D> {
pub fn contains(&self, entity_id: ArchEntityId) -> bool {
self.entities.contains(entity_id)
}
pub(crate) unsafe fn get_mut_unsafe(&self, entity_id: ArchEntityId) -> &'a mut C {
let ptr = ((&*self.data.borrow().get()).as_ptr())
.add(self.step * entity_id as usize)
.add(self.info.range.start);
&mut *(ptr as *mut C)
}
pub unsafe fn get_unchecked(&self, entity_id: ArchEntityId) -> &'a C {
self.get_mut_unsafe(entity_id)
}
pub fn get(&self, entity_id: ArchEntityId) -> Option<&'a C> {
if !self.contains(entity_id) {
return None;
}
unsafe { Some(self.get_unchecked(entity_id)) }
}
}
impl<'a, C: Component> ComponentStorageRef<'a, C> {
pub fn iter(self) -> Iter<'a, C, Self> {
Iter {
entities_iter: self.entities.iter(),
data: self,
_ty: Default::default(),
}
}
}
impl<'a, C: Component + 'a> IntoIterator for ComponentStorageRef<'a, C> {
type Item = &'a C;
type IntoIter = Iter<'a, C, Self>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, C: Component> ComponentStorageMut<'a, C> {
pub unsafe fn get_unchecked_mut(&mut self, entity_id: ArchEntityId) -> &'a mut C {
self.get_mut_unsafe(entity_id)
}
pub fn get_mut(&mut self, entity_id: ArchEntityId) -> Option<&'a mut C> {
if !self.contains(entity_id) {
return None;
}
unsafe { Some(self.get_unchecked_mut(entity_id)) }
}
pub fn iter_mut(&'a mut self) -> IterMut<'a, C, &mut Self> {
IterMut {
entities_iter: self.entities.iter(),
data: self,
_ty: Default::default(),
}
}
}
impl<'a, C: Component + 'a> IntoIterator for ComponentStorageMut<'a, C> {
type Item = &'a mut C;
type IntoIter = IterMut<'a, C, ComponentStorageRef<'a, C>>;
fn into_iter(self) -> Self::IntoIter {
IterMut {
entities_iter: self.entities.iter(),
data: ComponentStorageRef {
entities: self.entities,
step: self.step,
info: self.info,
data: self.data,
_ty: Default::default(),
},
_ty: Default::default(),
}
}
}
#[derive(Clone)]
pub struct Iter<'a, C, D> {
pub(crate) entities_iter: EntitiesIter<'a>,
pub(crate) data: D,
pub(crate) _ty: PhantomData<C>,
}
impl<'a, C, D> Iterator for Iter<'a, C, D>
where
C: Component + 'a,
D: Borrow<ComponentStorageRef<'a, C>>,
{
type Item = &'a C;
fn next(&mut self) -> Option<Self::Item> {
self.entities_iter
.next()
.map(|entity_id| unsafe { self.data.borrow().get_unchecked(entity_id) })
}
}
pub struct IterMut<'a, C, D> {
pub(crate) entities_iter: EntitiesIter<'a>,
pub(crate) data: D,
pub(crate) _ty: PhantomData<C>,
}
impl<'a, C, D> Iterator for IterMut<'a, C, D>
where
C: Component + 'a,
D: Borrow<ComponentStorageRef<'a, C>>,
{
type Item = &'a mut C;
fn next(&mut self) -> Option<Self::Item> {
self.entities_iter
.next()
.map(|entity_id| unsafe { self.data.borrow().get_mut_unsafe(entity_id) })
}
}