use std::marker;
use crate::{Component, entity::EntitiesStorage, storage::{IntoSendStorage, FastIndexExt, ReadOnlyStorage}, sync::Indices};
use crate::ComponentSend;
use crate::bitmask::{MaskType, Bitmask};
use crate::entity::Entity;
use super::{ChangedData, DataAccesses, FromComponent, OptionStorage, SafeIter, UnorderedData};
#[cfg(feature="parallel_iter")]
use super::ParOptionStorage;
use crate::storage::{Storage, StorageRef, IntoIter, ChangedStorageExt, HiddenFastIndex};
use std::ops::{Deref};
use std::borrow::Borrow;
use std::mem;
use crate::sync::{ReadGuardRef, LazyIndexGuard};
use std::usize;
#[cfg(feature = "parallel_iter")]
use rayon::prelude::*;
#[cfg(feature = "parallel_iter")]
use rayon::iter::plumbing::UnindexedConsumer;
#[cfg(components_64)]
use num_traits::Zero;
use std::any::TypeId;
use std::ptr;
use unchecked_unwrap::*;
type Get<'a, T> = <<T as Component>::Storage as Storage<'a, T>>::Get;
type DerefTarget<'a, T> = <<T as Component>::Storage as Storage<'a, T>>::DerefTarget;
pub struct ReadNot<'a, T: Component, Not: 'static>
where for<'s> <T as Component>::Storage: Storage<'s, T>
{
component: Get<'a,T>,
_marker: marker::PhantomData<&'a Not>,
}
impl<'a, T: Component, Not: 'static> FromComponent<'a, Get<'a,T>> for ReadNot<'a, T, Not>
where for<'s> <T as Component>::Storage: Storage<'s, T>
{
fn from_component(component: Get<'a,T>) -> ReadNot<'a,T,Not>{
ReadNot{
component,
_marker: marker::PhantomData
}
}
}
impl<'a, T: Component, Not: 'static> Deref for ReadNot<'a, T, Not>
where
Get<'a,T>: Borrow<DerefTarget<'a,T>>,
for<'s> <T as Component>::Storage: Storage<'s, T>
{
type Target = DerefTarget<'a,T>;
fn deref(&self) -> &DerefTarget<'a,T>{
self.component.borrow()
}
}
pub struct Iter<'a, T, N, BS, I>{
storage: Option<StorageReadNot<'a, T, BS, N, I>>,
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
}
impl<'a, 'r, T, N, I> Iterator for Iter<'a, T, N, &'r T::Storage, I>
where
for<'s> T::Storage: Storage<'s, T>,
T: Component,
N: 'static,
{
type Item = <T::Storage as Storage<'r, T>>::Get;
fn next(&mut self) -> Option<Self::Item>{
unsafe {
if self.ptr != self.end {
let fast_index = (*self.ptr).unchecked_downcast_ref();
self.ptr = self.ptr.add(1);
Some(self.storage.as_ref().unchecked_unwrap().storage.fast_get(*fast_index))
}else{
None
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'a, 'r, T, N> ExactSizeIterator for Iter<'a, T, N, &'r T::Storage, &'r LazyIndexGuard<'a>>
where
for<'s> T::Storage: Storage<'s, T>,
T: Component,
N: 'static,
{
#[inline]
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
impl<'a, T, N> Iterator for Iter<'a, T, N, ReadGuardRef<'a, T::Storage>, LazyIndexGuard<'a>>
where
for<'s> T::Storage: Storage<'s, T>,
T: Component,
N: 'static,
{
type Item = <T::Storage as Storage<'a, T>>::Get;
fn next(&mut self) -> Option<Self::Item>{
unsafe {
if self.ptr != self.end {
let fast_index = (*self.ptr).unchecked_downcast_ref();
self.ptr = self.ptr.add(1);
Some(self.storage.as_ref().unchecked_unwrap().storage.fast_get(*fast_index))
}else{
None
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'a, 'r, T, N> ExactSizeIterator for Iter<'a, T, N, ReadGuardRef<'a, T::Storage>, LazyIndexGuard<'a>>
where
for<'s> T::Storage: Storage<'s, T>,
T: Component,
N: 'static,
{
#[inline]
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
pub struct StorageReadNot<'a, T, BS, N, I>{
storage: BS,
entities_masks: &'a [(Entity, MaskType)],
not_component_mask: MaskType,
s_ids: I,
_marker_t: marker::PhantomData<&'a T>,
_marker_n: marker::PhantomData<N>,
}
impl<'a, T, BS, N> StorageReadNot<'a, T, BS, N, LazyIndexGuard<'a>>{
pub fn new(
storage: BS,
entities_masks: &'a [(Entity, MaskType)],
not_component_mask: MaskType,
s_ids: LazyIndexGuard<'a>) -> StorageReadNot<'a,T,BS, N, LazyIndexGuard<'a>>
{
StorageReadNot{
storage,
entities_masks,
not_component_mask,
s_ids,
_marker_t: marker::PhantomData,
_marker_n: marker::PhantomData,
}
}
}
impl<'a, T, BS, N, I> FastIndexExt for StorageReadNot<'a, T, BS, N, I>
where
for<'s> <T as Component>::Storage: Storage<'s, T>,
T: Component,
BS: Deref<Target=T::Storage>,
N: 'static,
{
type FastIndex = usize;
type StaticTypeId = ReadNot<'static, T, N>;
fn fast_index(&self, guid: usize) -> usize {
self.storage.fast_index(guid)
}
}
impl<'a, 'r, BS, T, N, I> StorageRef<'r> for StorageReadNot<'a, T, BS, N, I>
where
for<'s> <T as Component>::Storage: Storage<'s, T>,
BS: Deref<Target = T::Storage>,
T: Component,
N: 'static,
{
type Component = <T::Storage as Storage<'r,T>>::Get;
type Data = ReadNot<'a, T, N>;
unsafe fn get_fast_unchecked(&mut self, idx: usize) -> Self::Component {
self.storage.fast_get(idx)
}
unsafe fn get_unchecked(&mut self, guid: usize) -> Self::Component {
self.storage.get(guid)
}
fn contains(&self, guid: usize) -> bool{
self.storage.contains(guid)
&& (self.entities_masks[guid].1.clone() & self.not_component_mask.clone() == MaskType::zero())
}
}
impl<'a, 'r, BS, T, N, I> IntoSendStorage<'r> for StorageReadNot<'a, T, BS, N, I>
where
for<'s> <T as Component>::Storage: Storage<'s, T>,
BS: Deref<Target = T::Storage>,
T: Component,
N: 'static,
I: Indices
{
type SendStorage = StorageReadNot<'a, T, &'r T::Storage, N, &'r [HiddenFastIndex]>;
fn into_send_storage(&'r mut self) -> Self::SendStorage {
StorageReadNot{
s_ids: self.s_ids.index(self),
storage: &self.storage,
entities_masks: self.entities_masks,
not_component_mask: self.not_component_mask.clone(),
_marker_t: marker::PhantomData,
_marker_n: marker::PhantomData,
}
}
}
unsafe impl<'a, T, BS, N, I> ReadOnlyStorage for StorageReadNot<'a, T, BS, N, I>{}
impl<'a, 'r, BS, T, N, I> OptionStorage<'r> for StorageReadNot<'a, T, BS, N, I>
where
for<'b> <T as Component>::Storage: Storage<'b, T>,
BS: Deref<Target = T::Storage>,
T: Component,
N: 'static,
I: Indices
{
type Iter = Iter<'a, T, N, &'r T::Storage, &'r [HiddenFastIndex]>;
fn iter(this: Option<&'r Self>) -> Self::Iter {
let ptr_range = this
.map(|s| s.s_ids.as_ptr_range(s))
.unwrap_or(ptr::null() .. ptr::null());
Iter{
ptr: ptr_range.start,
end: ptr_range.end,
storage: this.map(|storage| StorageReadNot{
s_ids: storage.s_ids.index(storage),
storage: &*storage.storage,
entities_masks: storage.entities_masks,
not_component_mask: storage.not_component_mask.clone(),
_marker_t: marker::PhantomData,
_marker_n: marker::PhantomData,
}),
}
}
}
#[cfg(feature = "parallel_iter")]
pub struct ParIter<'a, 's, T, N>
where T: Component
{
storage: Option<&'a T::Storage>,
ids: &'a [HiddenFastIndex],
marker_t: marker::PhantomData<&'s T>,
marker_n: marker::PhantomData<&'s N>,
}
#[cfg(feature = "parallel_iter")]
impl<'a, 's, T, N> ParallelIterator for ParIter<'a, 's, T, N>
where
for<'b> <T as Component>::Storage: Storage<'b, T> + Send + Sync,
T: Component + Send + Sync,
N: 'static + Send + Sync,
<T::Storage as Storage<'s, T>>::Get: Send
{
type Item = <T::Storage as Storage<'s, T>>::Get;
#[inline]
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where C: UnindexedConsumer<Self::Item>
{
let storage = self.storage;
self.ids.par_iter().map(move |fast_index| unsafe{
let fast_index = fast_index.unchecked_downcast_ref();
let storage = storage.unchecked_unwrap();
storage.fast_get(*fast_index)
}).drive_unindexed(consumer)
}
}
#[cfg(feature = "parallel_iter")]
impl<'a, 'r, BS, T, N, I> ParOptionStorage<'r> for StorageReadNot<'a, T, BS, N, I>
where
for<'b> <T as Component>::Storage: Storage<'b, T>,
BS: Deref<Target = T::Storage>,
T: Component,
N: 'static,
I: Indices
{
type ParIter = ParIter<'r, 'a, T, N>;
fn par_iter(this: Option<&'r Self>) -> Self::ParIter {
ParIter{
ids: this.map(|this| this.s_ids.index(this)).unwrap_or(&[]),
storage: this.map(|this| &*this.storage),
marker_t: marker::PhantomData,
marker_n: marker::PhantomData,
}
}
}
unsafe impl<T: Component, Not> SafeIter<'_> for ReadNot<'_, T, Not>
where for<'s> <T as Component>::Storage: Storage<'s, T>,{}
impl<'a, T: Component, Not: 'static> UnorderedData<'a> for ReadNot<'a,T,Not>
where for<'s> <T as Component>::Storage: Storage<'s, T>,
{
type Iter = Iter<'a, T, Not, ReadGuardRef<'a, <T as Component>::Storage>, LazyIndexGuard<'a>>;
type IterMut = Iter<'a, T, Not, ReadGuardRef<'a, <T as Component>::Storage>, LazyIndexGuard<'a>>;
type Components = T;
type ComponentsRef = <<T as Component>::Storage as Storage<'a, T>>::Get;
type Storage = StorageReadNot<'a,
T,
ReadGuardRef<'a, <T as Component>::Storage>,
Not,
LazyIndexGuard<'a>,
>;
fn query_mask<E: EntitiesStorage>(entities: &E) -> Bitmask {
Bitmask::has_not(entities.component_mask::<T>(), entities.component_mask::<Not>())
}
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter {
let storage = <Self as UnorderedData>::storage(entities);
let ids = storage.as_ref().map(|storage| {
entities.entities_for_mask(
<Self as UnorderedData>::query_mask(entities),
storage
)
});
let (ptr, end) = ids.as_ref()
.map(|ids| (ids.as_ptr(), unsafe{ ids.as_ptr().add(ids.len()) }))
.unwrap_or((ptr::null(), ptr::null()));
Iter{
ptr,
end,
storage,
}
}
fn into_iter_mut<E: EntitiesStorage>(entities: &'a E) -> Self::Iter {
Self::into_iter(entities)
}
fn storage<E: EntitiesStorage>(entities: &'a E) -> Option<Self::Storage> {
let storage_t = entities.storage::<T>()?;
let entities_masks = entities.entities_ref();
let not_component_mask = entities.component_mask::<Not>();
let ids = entities
.lazy_entities_for_mask(
<Self as UnorderedData>::query_mask(entities),
);
Some(StorageReadNot::new(storage_t, entities_masks, not_component_mask, ids))
}
}
impl<'a, T: Component, Not: 'static> DataAccesses for ReadNot<'a, T, Not>
where
for<'s> <T as Component>::Storage: Storage<'s, T>,
{
fn reads() -> Vec<TypeId>{ vec![TypeId::of::<T>()] }
fn writes() -> Vec<TypeId>{ vec![] }
}
impl<'a, T: ComponentSend, Not: 'static> ChangedData<'a> for ReadNot<'a, T, Not>
where
for<'s> <T as Component>::Storage: Storage<'s, T>,
for<'b> ReadGuardRef<'b, <T as Component>::Storage>: IntoIter,
<T as Component>::Storage: ChangedStorageExt<'a>
{
type ChangedIter = super::ChangedIter<'a, ReadGuardRef<'a, <T as Component>::Storage>>;
fn changed_iter<E: EntitiesStorage>(entities: &'a E) -> Self::ChangedIter{
let mut _guard = entities.storage::<T>();
let iter = _guard.as_ref().map(|guard| unsafe{ mem::transmute::<
hashbrown::hash_set::Iter<usize>,
hashbrown::hash_set::Iter<usize>>(guard.changed_entities())
});
super::ChangedIter{
_guard: _guard,
iter,
}
}
}