use crate::{
entity::EntitiesStorage,
storage::{FastIndexExt, IntoSendStorage},
sync::StorageWriteGuard,
};
use std::marker;
use crate::Component;
use crate::ComponentSend;
use crate::Bitmask;
use crate::entity::{Entities, Entity};
use super::{ChangesData, DataAccesses, FromComponent, IterOptionWrapper, OptionStorageMut, SafeIter, UnorderedData};
#[cfg(feature="parallel_iter")]
use super::ParOptionStorageMut;
use crate::storage::{Storage, StorageRef, IntoIterMut, IntoChangesIter};
#[cfg(feature = "parallel_iter")]
use crate::storage::ParStorage;
use std::ops::{Deref, DerefMut};
use std::borrow::{Borrow, BorrowMut};
use hashbrown::HashSet;
use streaming_iterator::{StreamingIterator, StreamingIteratorMut};
use std::any::TypeId;
type GetMut<'a, T> = <<T as Component>::Storage as Storage<'a, T>>::GetMut;
type DerefTarget<'a, T> = <<T as Component>::Storage as Storage<'a, T>>::DerefTarget;
pub struct Write<'a, T: Component>
where for<'s> <T as Component>::Storage: Storage<'s, T>
{
component: GetMut<'a,T>,
}
impl<'a, T: Component> FromComponent<'a, GetMut<'a,T>> for Write<'a,T>
where for<'s> <T as Component>::Storage: Storage<'s, T>
{
fn from_component(component: GetMut<'a,T>) -> Write<'a,T>{
Write{
component
}
}
}
impl<'a, T: Component> Deref for Write<'a, T>
where
GetMut<'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()
}
}
impl<'a, T: Component> DerefMut for Write<'a, T>
where
GetMut<'a,T>: BorrowMut<DerefTarget<'a,T>>,
for<'s> <T as Component>::Storage: Storage<'s, T>
{
fn deref_mut(&mut self) -> &mut DerefTarget<'a,T>{
self.component.borrow_mut()
}
}
pub struct StorageWrite<'a, S, T, BS: DerefMut<Target=S>>{
pub(crate) storage: BS,
pub(crate) _marker: marker::PhantomData<&'a T>,
}
impl<'a, S, T, BS> FastIndexExt for StorageWrite<'a, S, T, BS>
where
for<'b> <T as Component>::Storage: Storage<'b, T>,
S: for<'s> Storage<'s,T>,
BS: DerefMut<Target=S>,
T: Component
{
type FastIndex = usize;
type StaticTypeId = T;
fn fast_index(&self, guid: usize) -> usize {
self.storage.fast_index(guid)
}
}
impl<'a, 'r, S, T, BS> StorageRef<'r> for StorageWrite<'a, S, T, BS>
where
for<'b> <T as Component>::Storage: Storage<'b, T>,
S: for<'s> Storage<'s,T>,
BS: DerefMut<Target=S>,
T: Component,
{
type Data = Write<'a,T>;
type Component = <S as Storage<'r,T>>::GetMut;
unsafe fn get_fast_unchecked(&'r mut self, idx: usize) -> <S as Storage<'r,T>>::GetMut{
self.storage.fast_get_mut(idx)
}
unsafe fn get_unchecked(&'r mut self, guid: usize) -> <S as Storage<'r,T>>::GetMut{
self.storage.get_mut(guid)
}
fn contains(&self, guid: usize) -> bool {
self.storage.contains(guid)
}
}
impl<'a, 'r, S, T, BS> IntoSendStorage<'r> for StorageWrite<'a, S, T, BS>
where
for<'b> T::Storage: Storage<'b, T>,
S: for<'s> Storage<'s,T> + 'r,
BS: DerefMut<Target=S>,
T: Component,
{
type SendStorage = StorageWrite<'a, S, T, &'r mut S>;
fn into_send_storage(&'r mut self) -> Self::SendStorage {
StorageWrite {
storage: &mut self.storage,
_marker: marker::PhantomData,
}
}
}
impl<'a, 'r, S, T, BS> OptionStorageMut<'r> for StorageWrite<'a, S, T, BS>
where
for<'s> T::Storage: Storage<'s, T>,
S: for<'s> Storage<'s,T> + 'r,
BS: DerefMut<Target=S>,
T: Component,
{
type IterMut = IterOptionWrapper<<S as Storage<'r, T>>::IterMut>;
fn iter_mut(this: Option<&'r mut Self>) -> Self::IterMut {
IterOptionWrapper{ it: this.map(|s| s.storage.iter_mut()) }
}
}
pub struct EntitiesWriteIter<'r, S, T, E>
where S: Storage<'r, T>
{
storage: &'r mut S,
entities: E,
current: Option<<S as Storage<'r, T>>::GetMut>,
}
impl<'r, S, T, E> StreamingIterator for EntitiesWriteIter<'r, S, T, E>
where
S: Storage<'r, T>,
T: Component,
E: Iterator<Item = Entity>,
<S as Storage<'r, T>>::DerefTarget: Sized,
<S as Storage<'r, T>>::GetMut: DerefMut<Target = <S as Storage<'r, T>>::DerefTarget>
{
type Item = <S as Storage<'r, T>>::DerefTarget;
fn advance(&mut self) {
while let Some(e) = self.entities.next() {
if self.storage.contains(e.guid()){
self.current = Some(unsafe{ self.storage.get_mut(e.guid()) });
return;
}
}
self.current = None;
}
fn get(&self) -> Option<&Self::Item> {
self.current.as_deref()
}
}
impl<'r, S, T, E> StreamingIteratorMut for EntitiesWriteIter<'r, S, T, E>
where
S: Storage<'r, T>,
T: Component,
E: Iterator<Item = Entity>,
<S as Storage<'r, T>>::DerefTarget: Sized,
<S as Storage<'r, T>>::GetMut: DerefMut<Target = <S as Storage<'r, T>>::DerefTarget>
{
fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.current.as_deref_mut()
}
}
#[cfg(feature = "parallel_iter")]
impl<'a, 'r, T, S, BS> ParOptionStorageMut<'r> for StorageWrite<'a, S, T, BS>
where
for<'b> T::Storage: Storage<'b, T>,
S: for<'s> Storage<'s,T> + 'r,
BS: DerefMut<Target=S>,
S: ParStorage<'r,T>,
T: Component
{
type ParIterMut = IterOptionWrapper<<S as ParStorage<'r, T>>::ParIterMut>;
fn par_iter_mut(this: Option<&'r mut Self>) -> Self::ParIterMut {
IterOptionWrapper{ it: this.map(|this| this.storage.par_iter_mut()) }
}
}
unsafe impl<T: Component> SafeIter<'_> for Write<'_, T>
where for<'s> <T as Component>::Storage: Storage<'s, T>{}
impl<'a, T: Component> UnorderedData<'a> for Write<'a,T>
where
StorageWriteGuard<'a, T>: IntoIterMut,
for<'s> <T as Component>::Storage: Storage<'s, T>
{
type Iter = IterOptionWrapper<<StorageWriteGuard<'a, T> as IntoIterMut>::IterMut>;
type IterMut = IterOptionWrapper<<StorageWriteGuard<'a, T> as IntoIterMut>::IterMut>;
type Components = T;
type ComponentsRef = <<T as Component>::Storage as Storage<'a, T>>::GetMut;
type Storage = StorageWrite<'a,
<T as Component>::Storage,
Self::Components,
StorageWriteGuard<'a, T>
>;
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_mut::<T>()
.map(|s| s.into_iter_mut())
}
}
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(StorageWrite{
storage: entities.storage_mut::<T>()?,
_marker: marker::PhantomData,
})
}
}
impl<'a, T: Component> DataAccesses for Write<'a, T>
where for<'s> <T as Component>::Storage: Storage<'s, T>
{
fn reads() -> Vec<TypeId>{ vec![] }
fn writes() -> Vec<TypeId>{ vec![TypeId::of::<T>()] }
}
impl<'a, T: ComponentSend> ChangesData<'a> for Write<'a, T>
where
for<'b> <T as Component>::Storage: Storage<'b,T>,
for<'b> StorageWriteGuard<'b, T>: IntoIterMut,
StorageWriteGuard<'a, T>: IntoChangesIter<'a, T, ChangesItem = <<T as Component>::Storage as Storage<'a, T>>::GetMut>,
{
type SubStorage = StorageWrite<'a,
<StorageWriteGuard<'a, T> as IntoChangesIter<'a, T>>::RawSubStorage,
Self::Components,
<StorageWriteGuard<'a, T> as IntoChangesIter<'a, T>>::SubStorage
>;
fn extend_changes<F>(entities: &'a Entities, f: F)
where F: FnMut(Self::ComponentsRef) -> bool
{
if let Some(storage) = entities.storage_mut::<T>() {
storage.extend_changes(f)
}
}
unsafe fn storage_and_changes(entities: &'a Entities) -> Option<(Self::SubStorage, &'a mut HashSet<usize>)> {
let (storage, changes) = entities.storage_mut::<T>()?
.into_storage_and_changes();
let storage = StorageWrite{
storage,
_marker: marker::PhantomData,
};
Some((storage, changes))
}
}