use crate::{entity::EntitiesStorage, storage::{IntoSendStorage, FastIndexExt, ReadOnlyStorage}, sync::{Indices, LazyIndexGuard, ReadGuardRef}, utils::delete_lifetime_mut};
use std::marker::{self, PhantomData};
use crate::Component;
use crate::component::{NToOneComponent, OneToOneComponent};
use crate::Bitmask;
use std::ops::{Deref, DerefMut};
use std::borrow::Borrow;
use crate::entity::Entity;
use super::{DataAccesses, FromComponent, OptionStorage, OptionStorageMut, ReadOnlyOp, SafeIter, SafeStreamingIter, UnorderedData};
#[cfg(feature="parallel_iter")]
use super::{ParOptionStorage, ParOptionStorageMut};
use crate::storage::{Storage, StorageRef, HiddenFastIndex};
#[cfg(feature = "parallel_iter")]
use rayon::prelude::*;
#[cfg(feature = "parallel_iter")]
use rayon::iter::plumbing::UnindexedConsumer;
use streaming_iterator::{StreamingIterator, StreamingIteratorMut};
use std::any::TypeId;
use std::ptr;
use unchecked_unwrap::*;
pub struct Ref<'a, T: NToOneComponent<'a>, R>{
marker_t: marker::PhantomData<T>,
marker_a: marker::PhantomData<&'a ()>,
component: R,
}
impl<'a, T: NToOneComponent<'a>, R> FromComponent<'a, <R as UnorderedData<'a>>::ComponentsRef> for Ref<'a, T, R>
where
R: UnorderedData<'a> + FromComponent<'a, <R as UnorderedData<'a>>::ComponentsRef>
{
fn from_component(component: <R as UnorderedData<'a>>::ComponentsRef) -> Ref<'a,T,R>{
Ref{
component: R::from_component(component),
marker_t: marker::PhantomData,
marker_a: marker::PhantomData,
}
}
}
impl<'a, T: NToOneComponent<'a>, R: UnorderedData<'a>> Deref for Ref<'a, T, R>{
type Target = R;
fn deref(&self) -> &R{
&self.component
}
}
impl<'a, T: NToOneComponent<'a>, R: UnorderedData<'a>> DerefMut for Ref<'a, T, R>{
fn deref_mut(&mut self) -> &mut R{
&mut self.component
}
}
pub struct URef<'a, T: OneToOneComponent<'a>, R>{
marker_t: marker::PhantomData<T>,
marker_a: marker::PhantomData<&'a ()>,
component: R,
}
pub struct RefData;
pub struct URefData;
pub trait RefDataExt<'a, T, R> {
type Data;
}
impl<'a, T: NToOneComponent<'a>, R> RefDataExt<'a, T, R> for RefData{
type Data = Ref<'a, T, R>;
}
impl<'a, T: OneToOneComponent<'a>, R> RefDataExt<'a, T, R> for URefData{
type Data = URef<'a, T, R>;
}
impl<'a, T, R> FromComponent<'a, <R as UnorderedData<'a>>::ComponentsRef> for URef<'a, T, R>
where
T: OneToOneComponent<'a>,
R: UnorderedData<'a> + FromComponent<'a, <R as UnorderedData<'a>>::ComponentsRef>
{
fn from_component(component: <R as UnorderedData<'a>>::ComponentsRef) -> URef<'a,T,R>{
URef{
component: R::from_component(component),
marker_t: marker::PhantomData,
marker_a: marker::PhantomData,
}
}
}
impl<'a, T: OneToOneComponent<'a>, R: UnorderedData<'a>> Deref for URef<'a, T, R>{
type Target = R;
fn deref(&self) -> &R{
&self.component
}
}
impl<'a, T: OneToOneComponent<'a>, R: UnorderedData<'a>> DerefMut for URef<'a, T, R>{
fn deref_mut(&mut self) -> &mut R{
&mut self.component
}
}
pub struct RefStorage<'a, S, T, SR, R, RR, I> {
ids: I,
storage: S,
storage_ref: SR,
marker_a: marker::PhantomData<&'a ()>,
marker_t: marker::PhantomData<T>,
marker_r: marker::PhantomData<R>,
marker_rr: marker::PhantomData<RR>,
marker_non_sync: marker::PhantomData<*const ()>,
}
unsafe impl<'a, 'r, S, T, SR, R, RR> Send for RefStorage<'a, &'r S, T, SR, R, RR, &'r [HiddenFastIndex]>
where
S: Send,
T: Send,
SR: Send,
R: Send
{}
unsafe impl<'a, 'r, S, T, SR, R> Sync for RefStorage<'a, &'r S, T, SR, R, RefData, &'r [HiddenFastIndex]>
where
S: Sync,
T: Sync,
SR: Sync + ReadOnlyStorage,
R: Sync
{}
unsafe impl<'a, 'r, S, T, SR, R> Sync for RefStorage<'a, &'r S, T, SR, R, URefData, &'r [HiddenFastIndex]>
where
S: Sync,
T: Sync,
SR: Sync,
R: Sync
{}
impl<'a, S, T, SR, R, RR, I> FastIndexExt for RefStorage<'a, S, T, SR, R, RR, I>
where
T: Component,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
R: 'static
{
type FastIndex = usize;
type StaticTypeId = (T, R);
fn fast_index(&self, guid: usize) -> usize {
self.storage.fast_index(guid)
}
}
unsafe impl<'a, S, T, SR, R, RR, I> ReadOnlyStorage for RefStorage<'a, S, T, SR, R, RR, I>
where
SR: ReadOnlyStorage
{}
impl<'a, 'r, S, T, SR, R, RR, I> StorageRef<'r> for RefStorage<'a, S, T, SR, R, RR, I>
where
T: Component + Deref<Target = Entity> + 'static,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
<T::Storage as Storage<'a,T>>::Get: Borrow<T>,
SR: StorageRef<'r>,
R: 'static,
RR: RefDataExt<'r, T, SR::Data>,
{
type Data = RR::Data;
type Component = <SR as StorageRef<'r>>::Component;
unsafe fn get_fast_unchecked(&'r mut self, idx: usize) -> Self::Component {
let t = self.storage.fast_get(idx);
self.storage_ref.get_unchecked(t.borrow().guid())
}
fn get(&'r mut self, entity: &Entity) -> Option<Self::Component> {
if self.storage.contains(entity.guid()){
let t = unsafe{ self.storage.get(entity.guid()) };
self.storage_ref.get(t.borrow())
}else{
None
}
}
unsafe fn get_unchecked(&'r mut self, guid: usize) -> Self::Component {
let t = self.storage.get(guid);
self.storage_ref.get_unchecked(t.borrow().guid())
}
fn contains(&self, guid: usize) -> bool {
if self.storage.contains(guid) {
unsafe{
let t = self.storage.get(guid);
self.storage_ref.contains(t.borrow().guid())
}
}else{
false
}
}
}
impl<'a, 'r, T, S, SR, R, RR, I> IntoSendStorage<'r> for RefStorage<'a, S, T, SR, R, RR, I>
where
T: Deref<Target = Entity> + Component,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
SR: StorageRef<'r>,
SR: IntoSendStorage<'r>,
<T::Storage as Storage<'a,T>>::Get: Borrow<T>,
RR: RefDataExt<'r, T, SR::Data>,
RR: RefDataExt<'r, T, <SR::SendStorage as StorageRef<'r>>::Data>,
R: 'static,
I: Indices
{
type SendStorage = RefStorage<'a, &'r T::Storage, T, <SR as IntoSendStorage<'r>>::SendStorage, R, RR, &'r [HiddenFastIndex]>;
fn into_send_storage(&'r mut self) -> Self::SendStorage {
RefStorage {
ids: self.ids.index(self),
storage: &self.storage,
storage_ref: self.storage_ref.into_send_storage(),
marker_t: marker::PhantomData,
marker_r: marker::PhantomData,
marker_a: marker::PhantomData,
marker_rr: marker::PhantomData,
marker_non_sync: marker::PhantomData,
}
}
}
impl<'a, 'r, T, S, SR, R, RR, I> OptionStorage<'r> for RefStorage<'a, S, T, SR, R, RR, I>
where
T: Deref<Target = Entity> + Component,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
SR: StorageRef<'r>,
<T::Storage as Storage<'a,T>>::Get: Borrow<T>,
SR: IntoSendStorage<'r>,
SR::SendStorage: ReadOnlyStorage,
RR: RefDataExt<'r, T, SR::Data>,
RR: RefDataExt<'r, T, <SR::SendStorage as StorageRef<'r>>::Data>,
R: 'static,
I: Indices
{
type Iter = RefIter<'r, Self::SendStorage>;
fn iter(this: Option<&'r Self>) -> Self::Iter {
let ptr_range = this
.map(|s| s.ids.as_ptr_range(s))
.unwrap_or(ptr::null() .. ptr::null());
let storage = this.map(|storage| {
let storage = storage as *const Self as *mut Self;
unsafe{ (*storage).into_send_storage() }
});
RefIter{
ptr: ptr_range.start,
end: ptr_range.end,
storage,
marker: marker::PhantomData,
}
}
}
impl<'a, 'r, T, S, SR, R, I> OptionStorageMut<'r> for RefStorage<'a, S, T, SR, R, RefData, I>
where
T: NToOneComponent<'r>,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
SR: StorageRef<'r>,
<T::Storage as Storage<'a,T>>::Get: Borrow<T>,
SR: IntoSendStorage<'r>,
R: 'static,
I: Indices
{
type IterMut = RefIterMut<'r, <Self as IntoSendStorage<'r>>::SendStorage, <<Self as IntoSendStorage<'r>>::SendStorage as StorageRef<'r>>::Component>;
fn iter_mut(this: Option<&'r mut Self>) -> Self::IterMut {
let ptr_range = this
.as_ref()
.map(|s| s.ids.as_ptr_range(*s))
.unwrap_or(ptr::null() .. ptr::null());
let storage = this.map(|storage| storage.into_send_storage());
RefIterMut{
ptr: ptr_range.start,
end: ptr_range.end,
current: None,
storage,
marker: marker::PhantomData,
}
}
}
impl<'a, 'r, T, S, SR, R, I> OptionStorageMut<'r> for RefStorage<'a, S, T, SR, R, URefData, I>
where
T: OneToOneComponent<'r>,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
SR: StorageRef<'r>,
<T::Storage as Storage<'a,T>>::Get: Borrow<T>,
SR: IntoSendStorage<'r>,
R: 'static,
I: Indices,
{
type IterMut = RefIter<'r, Self::SendStorage>;
fn iter_mut(this: Option<&'r mut Self>) -> Self::IterMut {
let ptr_range = this
.as_ref()
.map(|s| s.ids.as_ptr_range(*s))
.unwrap_or(ptr::null() .. ptr::null());
let storage = this.map(|storage| storage.into_send_storage());
RefIter {
ptr: ptr_range.start,
end: ptr_range.end,
storage,
marker: marker::PhantomData,
}
}
}
#[cfg(feature = "parallel_iter")]
pub struct RefParIter<'r, S>{
entities_ids: &'r [HiddenFastIndex],
storage: Option<S>,
}
#[cfg(feature = "parallel_iter")]
impl<'r, S> RefParIter<'r, S>{
fn new(storage: Option<S>, entities_ids: &[HiddenFastIndex]) -> RefParIter<S>{
RefParIter{
entities_ids,
storage,
}
}
}
#[cfg(feature = "parallel_iter")]
impl<'r, S> ParallelIterator for RefParIter<'r, S>
where
S: StorageRef<'r> + Send + Sync + 'r,
<S as StorageRef<'r>>::Component: Send,
{
type Item = <S as StorageRef<'r>>::Component;
#[inline]
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where C: UnindexedConsumer<Self::Item>
{
let storage = self.storage;
self.entities_ids.par_iter().map(move |id| unsafe{
let id = id.unchecked_downcast_ref();
let storage = storage.as_ref().unchecked_unwrap();
let storage = storage as *const S as *mut S;
(*storage).get_fast_unchecked(*id)
}).drive_unindexed(consumer)
}
fn opt_len(&self) -> Option<usize> {
Some(self.entities_ids.len())
}
}
#[cfg(feature="parallel_iter")]
impl<'a, 'r, T, S, SR, R, RR, I> ParOptionStorage<'r> for RefStorage<'a, S, T, SR, R, RR, I>
where
T: Deref<Target = Entity> + Component,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
SR: StorageRef<'r> + IntoSendStorage<'r>,
SR::SendStorage: ReadOnlyStorage,
<T::Storage as Storage<'a,T>>::Get: Borrow<T>,
RR: RefDataExt<'r, T, SR::Data>,
RR: RefDataExt<'r, T, <SR::SendStorage as StorageRef<'r>>::Data>,
R: 'static,
I: Indices,
{
type ParIter = RefParIter<'r, <Self as IntoSendStorage<'r>>::SendStorage>;
fn par_iter(this: Option<&'r Self>) -> Self::ParIter {
let storage = this.map(|this| {
let this = this as *const Self as *mut Self;
unsafe{ (*this).into_send_storage() }
});
let ids = storage.as_ref()
.map(|storage| storage.ids)
.unwrap_or(&[]);
RefParIter::new(storage, ids)
}
}
#[cfg(feature="parallel_iter")]
impl<'a, 'r, T, S, SR, R, I> RefStorage<'a, S, T, SR, R, RefData, I>
where
T: NToOneComponent<'r>,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
SR: StorageRef<'r> + IntoSendStorage<'r>,
<T::Storage as Storage<'a,T>>::Get: Borrow<T>,
R: 'static,
I: Indices,
{
}
#[cfg(feature="parallel_iter")]
impl<'a, 'r, T, S, SR, R, I> ParOptionStorageMut<'r> for RefStorage<'a, S, T, SR, R, URefData, I>
where
T: OneToOneComponent<'r>,
T::Storage: Storage<'a,T>,
S: Deref<Target = T::Storage>,
SR: StorageRef<'r> + IntoSendStorage<'r>,
<T::Storage as Storage<'a,T>>::Get: Borrow<T>,
R: 'static,
I: Indices,
{
type ParIterMut = RefParIter<'r, <Self as IntoSendStorage<'r>>::SendStorage>;
fn par_iter_mut(this: Option<&'r mut Self>) -> Self::ParIterMut {
let storage = this.map(|this| this.into_send_storage());
let ids = storage.as_ref()
.map(|storage| storage.ids)
.unwrap_or(&[]);
RefParIter::new(storage, ids)
}
}
pub struct RefIter<'r, S>{
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
storage: Option<S>,
marker: PhantomData<&'r ()>
}
impl<'a, 'r, S> Iterator for RefIter<'r, S>
where
S: StorageRef<'r> + 'r
{
type Item = S::Component;
fn next(&mut self) -> Option<Self::Item>{
unsafe {
if self.ptr == self.end {
return None;
} else {
let fast_ids = (*self.ptr).unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
let storage = delete_lifetime_mut(self.storage.as_mut().unchecked_unwrap());
Some(storage.get_fast_unchecked(*fast_ids))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'a, 'r, S> ExactSizeIterator for RefIter<'r, S>
where
S: StorageRef<'r> + 'r
{
#[inline]
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
impl<'a, 'r, S> DoubleEndedIterator for RefIter<'r, S>
where
S: StorageRef<'r> + 'r
{
fn next_back(&mut self) -> std::option::Option<<Self as Iterator>::Item> {
unsafe {
if self.ptr == self.end {
return None;
} else {
self.end = self.end.offset(-1);
let fast_ids = (*self.end).unchecked_downcast_ref();
let storage = delete_lifetime_mut(self.storage.as_mut().unchecked_unwrap());
Some(storage.get_fast_unchecked(*fast_ids))
}
}
}
}
pub struct RefIterMut<'r, S, T>{
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
storage: Option<S>,
current: Option<T>,
marker: PhantomData<&'r ()>
}
impl<'r, S> StreamingIterator for RefIterMut<'r, S, <S as StorageRef<'r>>::Component>
where
S: StorageRef<'r> + 'r
{
type Item = S::Component;
fn advance(&mut self) {
unsafe {
if self.ptr == self.end {
return;
} else {
let fast_ids = (*self.ptr).unchecked_downcast_ref();
let storage = delete_lifetime_mut(self.storage.as_mut().unchecked_unwrap());
self.ptr = self.ptr.offset(1);
self.current = Some(storage.get_fast_unchecked(*fast_ids));
}
}
}
fn get(&self) -> Option<&Self::Item> {
self.current.as_ref()
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'r, S> StreamingIteratorMut for RefIterMut<'r, S, <S as StorageRef<'r>>::Component>
where
S: StorageRef<'r> + 'r
{
fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.current.as_mut()
}
}
unsafe impl<'a, T, R> SafeIter<'a> for Ref<'a, T, R>
where
T: NToOneComponent<'a>,
R: ReadOnlyOp<'a>
{}
unsafe impl<'a, T, R> SafeIter<'a> for URef<'a, T, R>
where
T: OneToOneComponent<'a>,
R: SafeIter<'a>,
{}
unsafe impl<'a, T: NToOneComponent<'a>, R> SafeStreamingIter<'a> for Ref<'a, T, R>
{}
unsafe impl<'a, T: OneToOneComponent<'a>, R> SafeStreamingIter<'a> for URef<'a, T, R>
{}
impl<'a, T, R> UnorderedData<'a> for Ref<'a,T,R>
where
for<'s> <T as Component>::Storage: Storage<'s, T>,
R: UnorderedData<'a>,
T: Deref<Target = Entity> + NToOneComponent<'a>,
<<T as Component>::Storage as Storage<'a, T>>::Get: Borrow<T>,
{
type Iter = RefIter<'a, Self::Storage>;
type IterMut = RefIterMut<'a, Self::Storage, Self::ComponentsRef>;
type Components = <R as UnorderedData<'a>>::Components;
type ComponentsRef = <R as UnorderedData<'a>>::ComponentsRef;
type Storage = RefStorage<'a,
ReadGuardRef<'a, <T as Component>::Storage>,
T,
<R as UnorderedData<'a>>::Storage,
<R as UnorderedData<'a>>::Components,
RefData,
LazyIndexGuard<'a>
>;
fn query_mask<E: EntitiesStorage>(entities: &E) -> Bitmask {
Bitmask::has(entities.component_mask::<T>())
| Bitmask::reference::<T>(<R as UnorderedData<'a>>::query_mask(entities))
}
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter{
let storage = Self::storage(entities);
let (ptr, end) = storage.as_ref()
.map(|storage| {
let ids = storage.ids.index(storage);
(ids.as_ptr(), unsafe{ ids.as_ptr().add(ids.len()) })
})
.unwrap_or((ptr::null(), ptr::null()));
RefIter{
ptr,
end,
storage,
marker: marker::PhantomData
}
}
fn into_iter_mut<E: EntitiesStorage>(entities: &'a E) -> Self::IterMut{
let storage = Self::storage(entities);
let (ptr, end) = storage.as_ref()
.map(|storage| {
let ids = storage.ids.index(storage);
(ids.as_ptr(), unsafe{ ids.as_ptr().add(ids.len()) })
})
.unwrap_or((ptr::null(), ptr::null()));
RefIterMut{
ptr,
end,
storage,
current: None,
marker: marker::PhantomData
}
}
fn storage<E: EntitiesStorage>(entities: &'a E) -> Option<Self::Storage>{
let ids = entities.lazy_entities_for_mask(
<Self as UnorderedData>::query_mask(entities),
);
Some(RefStorage{
ids,
storage: entities.storage::<T>()?,
storage_ref: R::storage(entities)?,
marker_t: marker::PhantomData,
marker_r: marker::PhantomData,
marker_a: marker::PhantomData,
marker_rr: marker::PhantomData,
marker_non_sync: marker::PhantomData,
})
}
}
impl<'a, T, R> UnorderedData<'a> for URef<'a,T,R>
where
for<'s> <T as Component>::Storage: Storage<'s, T>,
R: UnorderedData<'a>,
T: OneToOneComponent<'a> + Component,
<<T as Component>::Storage as Storage<'a, T>>::Get: Borrow<T>,
{
type Iter = RefIter<'a, Self::Storage>;
type IterMut = RefIter<'a, Self::Storage>;
type Components = <R as UnorderedData<'a>>::Components;
type ComponentsRef = <R as UnorderedData<'a>>::ComponentsRef;
type Storage = RefStorage<'a,
ReadGuardRef<'a, <T as Component>::Storage>,
T,
<R as UnorderedData<'a>>::Storage,
<R as UnorderedData<'a>>::Components,
URefData,
LazyIndexGuard<'a>
>;
fn query_mask<E: EntitiesStorage>(entities: &E) -> Bitmask {
Bitmask::has(entities.component_mask::<T>())
| Bitmask::reference::<T>(<R as UnorderedData<'a>>::query_mask(entities))
}
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter{
let storage = Self::storage(entities);
let (ptr, end) = storage.as_ref()
.map(|storage| {
let ids = storage.ids.index(storage);
(ids.as_ptr(), unsafe{ ids.as_ptr().add(ids.len()) })
})
.unwrap_or((ptr::null(), ptr::null()));
RefIter{
ptr,
end,
storage,
marker: marker::PhantomData
}
}
fn into_iter_mut<E: EntitiesStorage>(entities: &'a E) -> Self::IterMut{
let storage = Self::storage(entities);
let (ptr, end) = storage.as_ref()
.map(|storage| {
let ids = storage.ids.index(storage);
(ids.as_ptr(), unsafe{ ids.as_ptr().add(ids.len()) })
})
.unwrap_or((ptr::null(), ptr::null()));
RefIter{
ptr,
end,
storage,
marker: marker::PhantomData
}
}
fn storage<E: EntitiesStorage>(entities: &'a E) -> Option<Self::Storage>{
let ids = entities.lazy_entities_for_mask(
<Self as UnorderedData>::query_mask(entities),
);
Some(RefStorage{
ids,
storage: entities.storage::<T>()?,
storage_ref: R::storage(entities)?,
marker_t: marker::PhantomData,
marker_r: marker::PhantomData,
marker_a: marker::PhantomData,
marker_rr: marker::PhantomData,
marker_non_sync: marker::PhantomData,
})
}
}
impl<'a, T, R> DataAccesses for Ref<'a,T,R>
where
T: NToOneComponent<'a>,
R: DataAccesses
{
fn reads() -> Vec<TypeId>{
let mut reads = R::reads();
reads.push(TypeId::of::<T>());
reads
}
fn writes() -> Vec<TypeId>{
R::writes()
}
}
impl<'a, T, R> DataAccesses for URef<'a,T,R>
where
T: OneToOneComponent<'a>,
R: DataAccesses
{
fn reads() -> Vec<TypeId>{
let mut reads = R::reads();
reads.push(TypeId::of::<T>());
reads
}
fn writes() -> Vec<TypeId>{
R::writes()
}
}