use crate::{IntoSendStorage, entity::EntitiesStorage, storage::{FastIndexExt, ReadOnlyStorage}, sync::{Indices, LazyIndexGuard, ReadGuardRef}, utils::delete_lifetime_mut};
use std::{marker::PhantomData};
use crate::Component;
use crate::Bitmask;
use crate::OneToNComponent;
use crate::OneToNStorage;
use std::ops::{Deref, DerefMut};
use std::borrow::Borrow;
use super::{DataAccesses, FromComponent, OptionStorage, OptionStorageMut, ReadOnlyOp, SafeIter, SafeStreamingIter, UnorderedData};
use crate::storage::{Storage, StorageRef, HiddenFastIndex};
use crate::Entity;
use std::any::TypeId;
use std::ptr;
use streaming_iterator::{StreamingIterator, StreamingIteratorMut};
use unchecked_unwrap::*;
pub struct RefN<'a, T, R>
where R: UnorderedData<'a>
{
component: RefCollection<'a, T, R::ComponentsRef>,
}
impl<'a, T, R> FromComponent<'a, RefCollection<'a, T, R::ComponentsRef>> for RefN<'a, T, R>
where
R: UnorderedData<'a>
{
fn from_component(component: RefCollection<'a, T, R::ComponentsRef>) -> RefN<'a,T,R>{
RefN{
component,
}
}
}
impl<'a, T, R> Deref for RefN<'a, T, R>
where R: UnorderedData<'a>
{
type Target = RefCollection<'a, T, R::ComponentsRef>;
fn deref(&self) -> &RefCollection<'a, T, R::ComponentsRef>{
&self.component
}
}
impl<'a, T, R> DerefMut for RefN<'a, T, R>
where R: UnorderedData<'a>
{
fn deref_mut(&mut self) -> &mut RefCollection<'a, T, R::ComponentsRef>{
&mut self.component
}
}
trait RefStorage<T>{
fn get(&mut self, entity: &Entity) -> Option<T>;
}
impl<'r, S> RefStorage<S::Component> for &'r mut S
where S: StorageRef<'r> + 'r
{
fn get(&mut self, entity: &Entity) -> Option<S::Component> {
let storage = unsafe{ delete_lifetime_mut(*self) };
storage.get(entity)
}
}
pub struct RefCollection<'a, T, R> {
ptr: *const T,
end: *const T,
storage_ref: Box<dyn RefStorage<R> + 'a>,
}
pub struct RefCollectionIter<'r, T, R> {
ptr: *const T,
end: *const T,
storage_ref: &'r dyn RefStorage<R>,
}
pub struct RefCollectionIterOpt<'r, T, R> {
ptr: *const T,
end: *const T,
storage_ref: &'r dyn RefStorage<R>,
}
pub struct RefCollectionIterMut<'r, T, R> {
ptr: *const T,
end: *const T,
current: Option<R>,
storage_ref: &'r mut dyn RefStorage<R>,
}
impl<'a, 'r, T, R> RefCollection<'a, T, R> {
pub fn iter(&'r self) -> RefCollectionIter<'r, T, R> {
let storage_ref = &*self.storage_ref;
let ptr = self.ptr;
let end = self.end;
RefCollectionIter {
ptr,
end,
storage_ref,
}
}
pub fn iter_opt(&'r self) -> RefCollectionIterOpt<'r, T, R> {
let storage_ref = &*self.storage_ref;
let ptr = self.ptr;
let end = self.end;
RefCollectionIterOpt {
ptr,
end,
storage_ref,
}
}
pub fn iter_mut(&'r mut self) -> RefCollectionIterMut<'r, T, R> {
let storage_ref = &mut *self.storage_ref;
let ptr = self.ptr;
let end = self.end;
RefCollectionIterMut {
ptr,
end,
current: None,
storage_ref,
}
}
pub unsafe fn unsafe_iter_mut(&'r mut self) -> RefCollectionIter<'r, T, R> {
let storage_ref = &mut *self.storage_ref;
let ptr = self.ptr;
let end = self.end;
RefCollectionIter {
ptr,
end,
storage_ref,
}
}
pub unsafe fn unsafe_iter_opt_mut(&'r mut self) -> RefCollectionIterOpt<'r, T, R> {
let storage_ref = &mut *self.storage_ref;
let ptr = self.ptr;
let end = self.end;
RefCollectionIterOpt {
ptr,
end,
storage_ref,
}
}
}
impl<'r, T, R> Iterator for RefCollectionIter<'r, T, R>
where
T: Deref<Target = Entity>
{
type Item = R;
fn next(&mut self) -> Option<Self::Item> {
while self.ptr != self.end {
unsafe{
let entity = (*self.ptr).borrow();
self.ptr = self.ptr.offset(1);
let storage_ref = self.storage_ref as *const dyn RefStorage<R> as *mut dyn RefStorage<R>;
if let Some(c) = (*storage_ref).get(entity) {
return Some(c);
}
}
}
None
}
}
impl<'r, T, R> Iterator for RefCollectionIterOpt<'r, T, R>
where
T: Deref<Target = Entity>
{
type Item = Option<R>;
fn next(&mut self) -> Option<Self::Item> {
if self.ptr != self.end {
unsafe{
let entity = (*self.ptr).borrow();
self.ptr = self.ptr.offset(1);
let storage_ref = self.storage_ref as *const dyn RefStorage<R> as *mut dyn RefStorage<R>;
Some((*storage_ref).get(entity))
}
}else{
None
}
}
}
impl<'r, T, R> StreamingIterator for RefCollectionIterMut<'r, T, R>
where
T: Deref<Target = Entity>
{
type Item = R;
fn advance(&mut self) {
while self.ptr != self.end {
unsafe{
let entity = (*self.ptr).borrow();
self.ptr = self.ptr.offset(1);
if let Some(c) = self.storage_ref.get(entity){
self.current = Some(c);
return;
}
}
}
self.current = None;
}
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;
(0, Some(len))
}
}
impl<'r, T, R> StreamingIteratorMut for RefCollectionIterMut<'r, T, R>
where
T: Deref<Target = Entity>
{
fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.current.as_mut()
}
}
pub struct RefNStorage<'a, T, S, Ref, SRef, I>{
ids: I,
entities_storage: S,
entities_ref_storage: SRef,
marker_t: PhantomData<T>,
marker_a: PhantomData<&'a ()>,
marker_r: PhantomData<Ref>,
}
impl<'a, T, S, R, SR, I> FastIndexExt for RefNStorage<'a, T, S, R, SR, I>
where
T: 'static,
R: UnorderedData<'a>,
{
type FastIndex = usize;
type StaticTypeId = (T, <R as UnorderedData<'a>>::Components);
fn fast_index(&self, guid: usize) -> usize {
guid
}
}
impl<'a, 'r, T, S, R, SR, I> StorageRef<'r> for RefNStorage<'a, T, S, R, SR, I>
where
T: OneToNComponent + Deref<Target = Entity>,
R: UnorderedData<'a>,
SR: StorageRef<'r>,
S: Deref<Target = <T as Component>::Storage>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
type Data = RefN<'a, T, R>;
type Component = RefCollection<'r, T, SR::Component>;
unsafe fn get_fast_unchecked(&'r mut self, guid: usize) -> Self::Component {
self.get_unchecked(guid)
}
unsafe fn get_unchecked(&'r mut self, guid: usize) -> Self::Component {
let (ptr, end) = {
let entities = self.entities_storage.get_slice(guid);
(entities.as_ptr(), entities.as_ptr().add(entities.len()))
};
RefCollection{
ptr,
end,
storage_ref: Box::new(&mut self.entities_ref_storage),
}
}
fn contains(&self, guid: usize) -> bool{
self.entities_storage.contains(guid)
}
}
impl<'a, 'r, S, T, R, I> IntoSendStorage<'r> for RefNStorage<'a, T, S, R, R::Storage, I>
where
T: OneToNComponent + Deref<Target = Entity>,
S: Deref<Target = <T as Component>::Storage>,
R: UnorderedData<'a>,
R::Storage: IntoSendStorage<'r>,
for<'b> T::Storage: OneToNStorage<'b,T>,
I: Indices
{
type SendStorage = RefNStorage<'a, T, &'r T::Storage, R, <R::Storage as IntoSendStorage<'r>>::SendStorage, &'r [HiddenFastIndex]>;
fn into_send_storage(&'r mut self) -> Self::SendStorage {
let entities_ref_storage = unsafe{ delete_lifetime_mut(&mut self.entities_ref_storage) };
RefNStorage {
ids: self.ids.index(self),
entities_storage: &self.entities_storage,
entities_ref_storage: entities_ref_storage.into_send_storage(),
marker_a: PhantomData,
marker_t: PhantomData,
marker_r: PhantomData,
}
}
}
unsafe impl<'a, T, S, R, SR, I> ReadOnlyStorage for RefNStorage<'a, T, S, R, SR, I>
where
R: UnorderedData<'a>,
<R as UnorderedData<'a>>::Storage: ReadOnlyStorage,
{}
impl<'a, 'r, T, S, R, I> RefNStorage<'a, T, S, R, <R as UnorderedData<'a>>::Storage, I>
where
T: OneToNComponent + Deref<Target = Entity>,
S: Deref<Target = <T as Component>::Storage>,
R: UnorderedData<'a> + 'a,
R::Storage: IntoSendStorage<'r>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>,
I: Indices
{
pub fn iter_opt(&'r self) -> RefIterOpt<'a, 'r, T, R>
where R: ReadOnlyOp<'a>
{
let this = self as *const Self as *mut Self;
let storage = unsafe{ (*this).into_send_storage() };
RefIterOpt {
ptr: storage.ids.as_ptr(),
end: unsafe{ storage.ids.as_ptr().add(storage.ids.len()) },
storage,
}
}
pub unsafe fn unsafe_iter_mut(&'r mut self) -> RefIter<'a, 'r, T, R>{
let storage = self.into_send_storage();
RefIter {
ptr: storage.ids.as_ptr(),
end: storage.ids.as_ptr().add(storage.ids.len()),
storage: Some(storage),
}
}
pub unsafe fn unsafe_iter_opt_mut(&'r mut self) -> RefIterOpt<'a, 'r, T, R>{
let storage = self.into_send_storage();
RefIterOpt {
ptr: storage.ids.as_ptr(),
end: storage.ids.as_ptr().add(storage.ids.len()),
storage,
}
}
}
impl<'a, 'r, T, S, R, I> OptionStorage<'r> for RefNStorage<'a, T, S, R, <R as UnorderedData<'a>>::Storage, I>
where
T: OneToNComponent + Deref<Target = Entity>,
S: Deref<Target = <T as Component>::Storage>,
R: UnorderedData<'a> + 'r,
R::Storage: IntoSendStorage<'r> + ReadOnlyStorage,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>,
I: Indices,
{
type Iter = RefIter<'a, 'r, T, R>;
fn iter(this: Option<&'r Self>) -> Self::Iter {
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| {
let storage = storage as *const Self as *mut Self;
unsafe{ (*storage).into_send_storage() }
});
RefIter {
ptr: ptr_range.start,
end: ptr_range.end,
storage,
}
}
}
impl<'a, 'r, T, S, R, I> OptionStorageMut<'r> for RefNStorage<'a, T, S, R, <R as UnorderedData<'a>>::Storage, I>
where
T: OneToNComponent + Deref<Target = Entity>,
S: Deref<Target = <T as Component>::Storage>,
R: UnorderedData<'a> + 'r,
R::Storage: IntoSendStorage<'r>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>,
I: Indices,
{
type IterMut = RefIterMut<'a, 'r, T, R>;
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,
storage,
current: None,
}
}
}
pub struct RefIntoIterMut<'a, T, R>
where
R: UnorderedData<'a>,
R::Storage: StorageRef<'a>,
T: Component,
{
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
current: Option<RefCollection<'a, T, <R::Storage as StorageRef<'a>>::Component>>,
storage: Option<RefNStorage<'a, T, ReadGuardRef<'a, T::Storage>, R, R::Storage, LazyIndexGuard<'a>>>,
}
impl<'a, T, R> StreamingIterator for RefIntoIterMut<'a, T, R>
where
T: OneToNComponent + Deref<Target = Entity>,
R: UnorderedData<'a> + 'a,
R::Storage: StorageRef<'a>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
type Item = RefCollection<'a, T, <R::Storage as StorageRef<'a>>::Component>;
fn advance(&mut self) {
unsafe {
while self.ptr != self.end {
let guid = (*self.ptr).unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
let storage = delete_lifetime_mut(self.storage.as_mut().unchecked_unwrap());
if storage.contains(*guid) {
self.current = Some(storage.get_unchecked(*guid));
return;
}
}
self.current = None;
}
}
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;
(0, Some(len))
}
}
impl<'a, T, R> StreamingIteratorMut for RefIntoIterMut<'a, T, R>
where
T: OneToNComponent + Deref<Target = Entity>,
R: UnorderedData<'a> + 'a,
R::Storage: StorageRef<'a>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.current.as_mut()
}
}
pub struct RefIntoIter<'a, T, R>
where
R: UnorderedData<'a>,
T: Component,
{
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
storage: Option<RefNStorage<'a, T, ReadGuardRef<'a, T::Storage>, R, R::Storage, LazyIndexGuard<'a>>>,
}
impl<'a, T, R> Iterator for RefIntoIter<'a, T, R>
where
T: OneToNComponent + Deref<Target = Entity>,
R: UnorderedData<'a> + ReadOnlyOp<'a> + 'a,
R::Storage: StorageRef<'a>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
type Item = RefCollection<'a, T, <R::Storage as StorageRef<'a>>::Component>;
fn next(&mut self) -> Option<Self::Item>{
unsafe {
while self.ptr != self.end {
let guid = (*self.ptr).unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
let storage = delete_lifetime_mut(self.storage.as_mut().unchecked_unwrap());
if storage.contains(*guid) {
return Some(storage.get_unchecked(*guid));
}
}
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(0, Some(len))
}
}
pub struct RefIterMut<'a, 'r, T, R>
where
R: 'r + UnorderedData<'a>,
R::Storage: IntoSendStorage<'r>,
T: Component,
{
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
current: Option<RefCollection<'r, T, <<R::Storage as IntoSendStorage<'r>>::SendStorage as StorageRef<'r>>::Component>>,
storage: Option<RefNStorage<'a, T, &'r T::Storage, R, <R::Storage as IntoSendStorage<'r>>::SendStorage, &'r [HiddenFastIndex]>>,
}
impl<'a,'r,T,R> StreamingIterator for RefIterMut<'a,'r,T,R>
where
'a: 'r,
T: 'r + OneToNComponent + Deref<Target = Entity>,
R: UnorderedData<'a> + 'a,
R::Storage: IntoSendStorage<'r>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
type Item = RefCollection<'r, T, <<R::Storage as IntoSendStorage<'r>>::SendStorage as StorageRef<'r>>::Component>;
fn advance(&mut self) {
unsafe {
while self.ptr != self.end {
let guid = (*self.ptr).unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
let storage = self.storage.as_mut().unchecked_unwrap();
if storage.contains(*guid) {
let storage = delete_lifetime_mut(storage);
self.current = Some(storage.get_unchecked(*guid));
return;
}
}
self.current = None;
}
}
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;
(0, Some(len))
}
}
impl<'a,'r,T,R> StreamingIteratorMut for RefIterMut<'a,'r,T,R>
where
'a: 'r,
T: 'r + OneToNComponent + Deref<Target = Entity>,
R: UnorderedData<'a> + 'a,
R::Storage: IntoSendStorage<'r>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.current.as_mut()
}
}
pub struct RefIter<'a, 'r, T, Ref>
where
Ref: 'r + UnorderedData<'a>,
Ref::Storage: IntoSendStorage<'r>,
T: Component,
{
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
storage: Option<RefNStorage<'a, T, &'r T::Storage, Ref, <Ref::Storage as IntoSendStorage<'r>>::SendStorage, &'r [HiddenFastIndex]>>,
}
impl<'a,'r,T,Ref> Iterator for RefIter<'a,'r,T,Ref>
where
'a: 'r,
T: 'r + OneToNComponent + Deref<Target = Entity>,
Ref: UnorderedData<'a> + 'a,
Ref::Storage: IntoSendStorage<'r>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
type Item = RefCollection<'r, T, <<Ref::Storage as IntoSendStorage<'r>>::SendStorage as StorageRef<'r>>::Component>;
fn next(&mut self) -> Option<Self::Item>{
unsafe {
while self.ptr != self.end {
let guid = (*self.ptr).unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
let storage = self.storage.as_mut().unchecked_unwrap();
if storage.contains(*guid) {
let storage = delete_lifetime_mut(storage);
return Some(storage.get_unchecked(*guid));
}
}
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(0, Some(len))
}
}
pub struct RefIterOpt<'a, 'r, T, Ref>
where
Ref: 'r + UnorderedData<'a>,
Ref::Storage: IntoSendStorage<'r>,
T: Component,
{
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
storage: RefNStorage<'a, T, &'r T::Storage, Ref, <Ref::Storage as IntoSendStorage<'r>>::SendStorage, &'r [HiddenFastIndex]>,
}
impl<'a,'r,T,Ref> Iterator for RefIterOpt<'a,'r,T,Ref>
where
'a: 'r,
T: 'r + OneToNComponent + Deref<Target = Entity>,
Ref: UnorderedData<'a> + 'a,
Ref::Storage: IntoSendStorage<'r>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
type Item = Option<RefCollection<'r, T, <<Ref::Storage as IntoSendStorage<'r>>::SendStorage as StorageRef<'r>>::Component>>;
fn next(&mut self) -> Option<Self::Item>{
if self.ptr != self.end {
unsafe {
let guid = (*self.ptr).unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
if self.storage.contains(*guid) {
let storage = delete_lifetime_mut(&mut self.storage);
Some(Some(storage.get_unchecked(*guid)))
}else{
Some(None)
}
}
}else{
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(0, Some(len))
}
}
unsafe impl<'a, T, R> SafeIter<'a> for RefN<'a, T, R>
where
R: UnorderedData<'a> + ReadOnlyOp<'a>,
R::Storage: IntoSendStorage<'a>,
{}
unsafe impl<'a, T, R> SafeStreamingIter<'a> for RefN<'a, T, R>
where
R: UnorderedData<'a>,
R::Storage: IntoSendStorage<'a>,
{}
impl<'a, T, R> UnorderedData<'a> for RefN<'a,T,R>
where
T: OneToNComponent,
R: UnorderedData<'a> + 'a,
R::Storage: StorageRef<'a>,
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>
{
type Iter = RefIntoIter<'a, T, R>;
type IterMut = RefIntoIterMut<'a, T, R>;
type Components = <R as UnorderedData<'a>>::Components;
type ComponentsRef = RefCollection<'a, T, <R::Storage as StorageRef<'a>>::Component>;
type Storage = RefNStorage<'a, T, ReadGuardRef<'a, <T as Component>::Storage>, R, <R as UnorderedData<'a>>::Storage, LazyIndexGuard<'a>>;
fn query_mask<E: EntitiesStorage>(entities: &E) -> Bitmask {
Bitmask::has(entities.component_mask::<T>())
}
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter {
let storage = Self::storage(entities);
let (ptr, end) = storage.as_ref().map(|storage| {
let index = storage.ids.index(storage);
(index.as_ptr(), unsafe{ index.as_ptr().add(index.len()) })
}).unwrap_or((ptr::null(), ptr::null()));
RefIntoIter{
ptr,
end,
storage,
}
}
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 index = storage.ids.index(storage);
(index.as_ptr(), unsafe{ index.as_ptr().add(index.len()) })
}).unwrap_or((ptr::null(), ptr::null()));
RefIntoIterMut{
ptr,
end,
storage,
current: None,
}
}
fn storage<E: EntitiesStorage>(entities: &'a E) -> Option<Self::Storage>{
let ids = entities.lazy_entities_for_mask(
<Self as UnorderedData>::query_mask(entities),
);
let entities_ref_storage = R::storage(entities)?;
Some(RefNStorage{
ids,
entities_ref_storage,
entities_storage: entities.storage::<T>()?,
marker_a: PhantomData,
marker_t: PhantomData,
marker_r: PhantomData,
})
}
}
impl<'a, T: OneToNComponent, R> DataAccesses for RefN<'a,T,R>
where
for<'b> <T as Component>::Storage: OneToNStorage<'b,T>,
R: UnorderedData<'a> + DataAccesses,
R::Storage: IntoSendStorage<'a>,
{
fn reads() -> Vec<TypeId>{
let mut reads = R::reads();
reads.push(TypeId::of::<T>());
reads
}
fn writes() -> Vec<TypeId>{
R::writes()
}
}