use crate::{ bitmask::Bitmask, component::{Component, ComponentSend}, entity::EntitiesStorage, storage::{
FastIndexExt, IntoSendStorage, ReadOnlyStorage, Storage, StorageRef, IntoIter,
ChangedStorageExt
}, sync::{ReadGuardRef}};
use std::{marker};
use std::mem;
use super::{ChangedData, DataAccesses, FromComponent, IterOptionWrapper, OptionStorage, SafeIter, UnorderedData};
#[cfg(feature="parallel_iter")]
use super::ParOptionStorage;
#[cfg(feature = "parallel_iter")]
use crate::storage::ParStorage;
use std::ops::Deref;
use std::borrow::Borrow;
use std::any::TypeId;
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 Read<'a, T: Component>
where for<'s> <T as Component>::Storage: Storage<'s, T>
{
component: Get<'a,T>,
}
impl<'a, T: Component> FromComponent<'a, Get<'a,T>> for Read<'a,T>
where for<'s> <T as Component>::Storage: Storage<'s, T>
{
fn from_component(component: Get<'a,T>) -> Read<'a,T>{
Read{
component
}
}
}
impl<'a, T: Component> Deref for Read<'a, T>
where
for<'s> T::Storage: Storage<'s, T>,
Get<'a,T>: Borrow<DerefTarget<'a,T>>
{
type Target = DerefTarget<'a,T>;
fn deref(&self) -> &DerefTarget<'a,T>{
self.component.borrow()
}
}
pub struct StorageRead<'a, T, BS>{
pub(crate) storage: BS,
pub(crate) _marker_t: marker::PhantomData<&'a T>,
}
impl<'a, T, BS> StorageRead<'a, T, BS>{
pub fn new(storage: BS) -> StorageRead<'a,T,BS>{
StorageRead{
storage,
_marker_t: marker::PhantomData,
}
}
}
unsafe impl<'a,T,BS> ReadOnlyStorage for StorageRead<'a, T, BS>{}
impl<'a, T, BS> FastIndexExt for StorageRead<'a, T, BS>
where
for<'s> T::Storage: Storage<'s, T>,
T: Component,
BS: Deref<Target=T::Storage>,
{
type FastIndex = usize;
type StaticTypeId = T;
fn fast_index(&self, guid: usize) -> usize {
self.storage.fast_index(guid)
}
}
impl<'a, 'r, T, BS> StorageRef<'r> for StorageRead<'a, T, BS>
where
for<'s> T::Storage: Storage<'s, T>,
T: Component,
BS: Deref<Target=T::Storage>,
{
type Data = Read<'a, T>;
type Component = <T::Storage as Storage<'r,T>>::Get;
unsafe fn get_fast_unchecked(&'r mut self, idx: usize) -> Self::Component {
self.storage.fast_get(idx)
}
unsafe fn get_unchecked(&'r mut self, guid: usize) -> Self::Component {
self.storage.get(guid)
}
fn contains(&self, guid: usize) -> bool{
self.storage.contains(guid)
}
}
impl<'a, 'r, T, BS> IntoSendStorage<'r> for StorageRead<'a, T, BS>
where
for<'s> T::Storage: Storage<'s, T>,
T: Component,
BS: Deref<Target=T::Storage>,
{
type SendStorage = StorageRead<'a, T, &'r T::Storage>;
fn into_send_storage(&'r mut self) -> Self::SendStorage {
StorageRead {
storage: &self.storage,
_marker_t: marker::PhantomData,
}
}
}
impl<'a, 'r, T, BS> OptionStorage<'r> for StorageRead<'a, T, BS>
where
for<'s> T::Storage: Storage<'s, T>,
T: Component,
BS: Deref<Target=T::Storage>,
{
type Iter = IterOptionWrapper<<T::Storage as Storage<'r, T>>::Iter>;
fn iter(this: Option<&'r Self>) -> Self::Iter {
IterOptionWrapper{ it: this.map(|s| s.storage.iter()) }
}
}
#[cfg(feature = "parallel_iter")]
impl<'a, 'r, T, BS> ParOptionStorage<'r> for StorageRead<'a, T, BS>
where
for<'s> T::Storage: Storage<'s, T>,
T::Storage: ParStorage<'r,T>,
T: Component,
BS: Deref<Target=T::Storage>,
{
type ParIter = IterOptionWrapper<<T::Storage as ParStorage<'r, T>>::ParIter>;
fn par_iter(this: Option<&'r Self>) -> Self::ParIter {
IterOptionWrapper{ it: this.map(|this| this.storage.par_iter() )}
}
}
unsafe impl<T: Component> SafeIter<'_> for Read<'_, T>
where
for<'s> <T as Component>::Storage: Storage<'s, T>,{}
impl<'a, T: Component> UnorderedData<'a> for Read<'a,T>
where
ReadGuardRef<'a, <T as Component>::Storage>: IntoIter,
for<'s> <T as Component>::Storage: Storage<'s, T>
{
type Iter = IterOptionWrapper<<ReadGuardRef<'a, <T as Component>::Storage> as IntoIter>::Iter>;
type IterMut = IterOptionWrapper<<ReadGuardRef<'a, <T as Component>::Storage> as IntoIter>::Iter>;
type Components = T;
type ComponentsRef = <<T as Component>::Storage as Storage<'a, T>>::Get;
type Storage = StorageRead<'a, T, ReadGuardRef<'a, <T as Component>::Storage>>;
fn query_mask<E: EntitiesStorage>(entities: &E) -> Bitmask{
Bitmask::has(entities.component_mask::<T>())
}
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter{
IterOptionWrapper {
it: entities.storage::<T>().map(|s| s.into_iter())
}
}
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>{
Some(StorageRead{
storage: entities.storage::<T>()?,
_marker_t: marker::PhantomData,
})
}
}
impl<'a, T: Component> DataAccesses for Read<'a, T>
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> ChangedData<'a> for Read<'a, T>
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,
}
}
}