use std::marker::PhantomData;
use crate::{
CreationSto,
IntoEntitiesIterator,
IntoSendStorage,
entity::{EntitiesStorage, Entities},
storage::{FastIndexExt, ReadOnlyStorage},
sync::{OrderedIndexGuard},
utils::{delete_lifetime_mut}
};
#[cfg(feature="parallel_iter")]
use crate::utils::IntoEntitiesParIterator;
use crate::Entity;
use crate::Bitmask;
use crate::storage::{StorageRef, HiddenFastIndex, StorageEntitiesExt};
use crate::component::{self, Component};
use hashbrown::HashSet;
#[cfg(feature = "parallel_iter")]
use rayon::iter::{IntoParallelIterator, ParallelIterator, plumbing::UnindexedConsumer, IndexedParallelIterator};
use std::any::TypeId;
use unchecked_unwrap::*;
use streaming_iterator::{StreamingIterator, StreamingIteratorMut};
pub use self::read::Read;
pub use self::write::Write;
pub use self::not::Not;
pub use self::has::Has;
pub use self::hasor::HasOr;
pub use self::readnot::ReadNot;
pub use self::has_option::HasOption;
pub use self::readoption::ReadOption;
pub use self::writeoption::WriteOption;
pub use self::reador::ReadOr;
pub use self::ref_op::{Ref, URef};
pub type ReadRef<'a,R,T> = Ref<'a, R, Read<'a, T>>;
pub use self::refn::RefN;
pub use self::read_and_parent::ReadAndParent;
pub use self::write_and_parent::WriteAndParent;
pub use self::read_and_parent_ref::ReadAndParentRef;
#[doc(hidden)]
pub use self::read_hierarchical::ReadHierarchical;
#[doc(hidden)]
pub use self::write_hierarchical::WriteHierarchical;
#[doc(hidden)]
pub use self::ref_op::{RefData, URefData};
pub(crate) mod read;
pub(crate) mod write;
mod entity;
mod not;
mod has;
mod hasor;
mod readnot;
mod has_option;
mod readoption;
mod writeoption;
mod reador;
mod ref_op;
mod refn;
mod read_and_parent;
mod write_and_parent;
mod read_and_parent_ref;
mod read_hierarchical;
mod write_hierarchical;
pub mod filter;
#[derive(Debug)]
pub enum OperatorId {
Read(component::Id),
Write(component::Id),
Several(Vec<OperatorId>),
None,
}
pub trait UnorderedData<'a> {
type Iter;
type IterMut;
type Components: 'static;
type ComponentsRef;
type Storage;
fn query_mask<E: EntitiesStorage>(entities: &E) -> Bitmask;
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter;
fn into_iter_mut<E: EntitiesStorage>(entities: &'a E) -> Self::IterMut;
fn storage<E: EntitiesStorage>(entities: &'a E) -> Option<Self::Storage>;
}
pub trait UnorderedDataSend<'a>: UnorderedData<'a>{}
impl<'a, U> UnorderedDataSend<'a> for U
where
U: UnorderedData<'a>,
<U as UnorderedData<'a>>::Components: Send
{}
pub struct IterOptionWrapper<I> {
pub(crate) it: Option<I>
}
impl<I> Iterator for IterOptionWrapper<I>
where I: Iterator
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
let it = self.it.as_mut()?;
it.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.as_ref().map(|it| it.size_hint()).unwrap_or((0, None))
}
}
impl<I: ExactSizeIterator> ExactSizeIterator for IterOptionWrapper<I> {
#[inline]
fn len(&self) -> usize {
self.it.as_ref().map(|it| it.len()).unwrap_or(0)
}
}
#[cfg(feature="parallel_iter")]
impl<I> ParallelIterator for IterOptionWrapper<I>
where I: ParallelIterator
{
type Item = I::Item;
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where C: UnindexedConsumer<Self::Item>
{
if let Some(it) = self.it {
it.drive_unindexed(consumer)
}else{
None.into_par_iter().drive_unindexed(consumer)
}
}
}
#[cfg(feature="parallel_iter")]
impl<I> IndexedParallelIterator for IterOptionWrapper<I>
where I: IndexedParallelIterator
{
fn len(&self) -> usize {
self.it.as_ref().map(|it| it.len()).unwrap_or(0)
}
fn drive<C: rayon::iter::plumbing::Consumer<Self::Item>>(self, consumer: C) -> C::Result {
if let Some(it) = self.it {
it.drive(consumer)
}else{
None.into_par_iter().drive(consumer)
}
}
fn with_producer<CB: rayon::iter::plumbing::ProducerCallback<Self::Item>>(self, callback: CB) -> CB::Output {
if let Some(it) = self.it {
it.with_producer(callback)
}else{
None.into_par_iter().with_producer(callback)
}
}
}
pub trait DataAccesses {
fn reads() -> Vec<TypeId>;
fn writes() -> Vec<TypeId>;
}
pub trait FromComponent<'a, T>{
fn from_component(component: T) -> Self;
}
pub struct Sto<'a, S: UnorderedData<'a>>(Option<S::Storage>, crate::Entities<'a>);
impl<'a, S: UnorderedData<'a>> Sto<'a, S> {
pub fn new(storage: Option<S::Storage>, entities: Entities<'a>) -> Self {
Sto(storage, entities)
}
fn into_storage_entities(self) -> (Option<S::Storage>, crate::Entities<'a>) {
(self.0, self.1)
}
pub fn unwrap(self) -> Self {
let storage = self.0.unwrap();
Sto(Some(storage), self.1)
}
}
pub struct SendSto<'r, S>(Option<S>, crate::Entities<'r>);
impl<'a, 'r, S> Sto<'a, S>
where
S: UnorderedData<'a>,
S::Storage: StorageRef<'r> + ReadOnlyStorage
{
pub fn get(&'r self, entity: &Entity) -> Option<<S::Storage as StorageRef<'r>>::Component> {
let storage = &self.0;
let storage = storage as *const Option<S::Storage> as *mut Option<S::Storage>;
unsafe{ (*storage).as_mut()?.get(entity) }
}
}
impl<'a, 'r, S> Sto<'a, S>
where
S: UnorderedData<'a>,
S::Storage: StorageRef<'r>
{
pub fn get_mut(&'r mut self, entity: &Entity) -> Option<<S::Storage as StorageRef<'r>>::Component> {
self.0.as_mut()?.get(entity)
}
}
impl<'a, 'r, S> Sto<'a, S>
where
S: UnorderedData<'a>,
S::Storage: OptionStorage<'r>,
S::Storage: IntoSendStorage<'r>,
<S::Storage as IntoSendStorage<'r>>::SendStorage: ReadOnlyStorage
{
pub fn iter(&'r self) -> <S::Storage as OptionStorage<'r>>::Iter {
OptionStorage::iter(self.0.as_ref())
}
pub fn iter_for_entities<E>(&'r self, entities_iter: E) -> E::IntoEntitiesIter
where
E: IntoEntitiesIterator<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
{
OptionStorage::iter_for_entities(self.0.as_ref(), entities_iter)
}
pub fn iter_for_entities_opt<E>(&'r self, entities_iter: E) -> E::IntoEntitiesOptIter
where
E: IntoEntitiesIterator<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
{
OptionStorage::iter_for_entities_opt(self.0.as_ref(), entities_iter)
}
pub fn as_send_storage(&'r self) -> SendSto<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
where S::Storage: 'r
{
SendSto(
self.0.as_ref().map(|storage| {
let storage = storage as *const S::Storage as *mut S::Storage;
unsafe{ (*storage).into_send_storage() }
}),
Entities {
storages: self.1.storages.clone()
}
)
}
}
impl<'a, 'r, S> Sto<'a, S>
where
S: UnorderedData<'a>,
S::Storage: OptionStorageMut<'r>,
S::Storage: IntoSendStorage<'r>,
{
pub fn iter_mut(&'r mut self) -> <S::Storage as OptionStorageMut<'r>>::IterMut {
OptionStorageMut::iter_mut(self.0.as_mut())
}
pub fn iter_for_entities_mut<E>(&'r mut self, entities_iter: E) -> E::IntoEntitiesIterMut
where
E: IntoEntitiesIterator<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
{
OptionStorageMut::iter_for_entities_mut(self.0.as_mut(), entities_iter)
}
pub fn iter_for_entities_opt_mut<E>(&'r mut self, entities_iter: E) -> E::IntoEntitiesOptIterMut
where
E: IntoEntitiesIterator<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
{
OptionStorageMut::iter_for_entities_opt_mut(self.0.as_mut(), entities_iter)
}
pub fn as_send_storage_mut(&'r mut self) -> SendSto<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
where S::Storage: 'r
{
SendSto(
self.0.as_mut().map(|storage| storage.into_send_storage() ),
Entities {
storages: self.1.storages.clone()
}
)
}
}
#[cfg(feature="parallel_iter")]
impl<'a, 'r, S> Sto<'a, S>
where
S: UnorderedData<'a>,
S::Storage: ParOptionStorage<'r>,
S::Storage: IntoSendStorage<'r>,
<S::Storage as IntoSendStorage<'r>>::SendStorage: ReadOnlyStorage
{
pub fn par_iter(&'r self) -> <S::Storage as ParOptionStorage<'r>>::ParIter {
ParOptionStorage::par_iter(self.0.as_ref())
}
pub fn par_iter_for_entities<E>(&'r self, entities_iter: E) -> E::IntoEntitiesParIter
where
E: IntoEntitiesParIterator<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
{
ParOptionStorage::par_iter_for_entities(self.0.as_ref(), entities_iter)
}
pub fn par_iter_for_entities_opt<E>(&'r self, entities_iter: E) -> E::IntoEntitiesOptParIter
where
E: IntoEntitiesParIterator<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
{
ParOptionStorage::par_iter_for_entities_opt(self.0.as_ref(), entities_iter)
}
}
#[cfg(feature="parallel_iter")]
impl<'a, 'r, S> Sto<'a, S>
where
S: UnorderedData<'a>,
S::Storage: ParOptionStorageMut<'r>,
S::Storage: IntoSendStorage<'r>,
{
pub fn par_iter_mut(&'r mut self) -> <S::Storage as ParOptionStorageMut<'r>>::ParIterMut {
ParOptionStorageMut::par_iter_mut(self.0.as_mut())
}
pub fn par_iter_for_entities_mut<E>(&'r mut self, entities_iter: E) -> E::IntoEntitiesParIterMut
where
E: IntoEntitiesParIterator<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
{
ParOptionStorageMut::par_iter_for_entities_mut(self.0.as_mut(), entities_iter)
}
pub fn par_iter_for_entities_opt_mut<E>(&'r mut self, entities_iter: E) -> E::IntoEntitiesOptParIterMut
where
E: IntoEntitiesParIterator<'r, <S::Storage as IntoSendStorage<'r>>::SendStorage>
{
ParOptionStorageMut::par_iter_for_entities_opt_mut(self.0.as_mut(), entities_iter)
}
}
impl<'a, 'r, S> SendSto<'a, S>
where
S: StorageRef<'r> + ReadOnlyStorage
{
pub fn get(&'r self, entity: &Entity) -> Option<S::Component> {
let storage = &self.0;
let storage = storage as *const Option<S> as *mut Option<S>;
unsafe{ (*storage).as_mut()?.get(entity) }
}
}
impl<'a, 'r, S> SendSto<'a, S>
where
S: StorageRef<'r>
{
pub fn get_mut(&'r mut self, entity: &Entity) -> Option<S::Component> {
self.0.as_mut()?.get(entity)
}
}
impl<'a, 'r, S> SendSto<'a, S>
where
S: OptionStorage<'r> + StorageRef<'r> + IntoSendStorage<'r>,
S::SendStorage: ReadOnlyStorage
{
pub fn iter(&'r self) -> S::Iter {
OptionStorage::iter(self.0.as_ref())
}
pub fn iter_for_entities<E>(&'r self, entities_iter: E) -> E::IntoEntitiesIter
where
E: IntoEntitiesIterator<'r, S::SendStorage>
{
OptionStorage::iter_for_entities(self.0.as_ref(), entities_iter)
}
pub fn iter_for_entities_opt<E>(&'r self, entities_iter: E) -> E::IntoEntitiesOptIter
where
E: IntoEntitiesIterator<'r, S::SendStorage>
{
OptionStorage::iter_for_entities_opt(self.0.as_ref(), entities_iter)
}
}
impl<'a, 'r, S> SendSto<'a, S>
where
S: OptionStorageMut<'r> + StorageRef<'r> + IntoSendStorage<'r>,
{
pub fn iter_mut(&'r mut self) -> S::IterMut {
OptionStorageMut::iter_mut(self.0.as_mut())
}
pub fn iter_for_entities_mut<E>(&'r mut self, entities_iter: E) -> E::IntoEntitiesIterMut
where
E: IntoEntitiesIterator<'r, S::SendStorage>
{
OptionStorageMut::iter_for_entities_mut(self.0.as_mut(), entities_iter)
}
pub fn iter_for_entities_opt_mut<E>(&'r mut self, entities_iter: E) -> E::IntoEntitiesOptIterMut
where
E: IntoEntitiesIterator<'r, S::SendStorage>
{
OptionStorageMut::iter_for_entities_opt_mut(self.0.as_mut(), entities_iter)
}
}
#[cfg(feature="parallel_iter")]
impl<'a, 'r, S> SendSto<'a, S>
where
S: ParOptionStorage<'r> + StorageRef<'r> + IntoSendStorage<'r>,
S::SendStorage: ReadOnlyStorage
{
pub fn par_iter(&'r self) -> S::ParIter {
ParOptionStorage::par_iter(self.0.as_ref())
}
pub fn par_iter_for_entities<E>(&'r self, entities_iter: E) -> E::IntoEntitiesParIter
where
E: IntoEntitiesParIterator<'r, S::SendStorage>
{
ParOptionStorage::par_iter_for_entities(self.0.as_ref(), entities_iter)
}
pub fn par_iter_for_entities_opt<E>(&'r self, entities_iter: E) -> E::IntoEntitiesOptParIter
where
E: IntoEntitiesParIterator<'r, S::SendStorage>
{
ParOptionStorage::par_iter_for_entities_opt(self.0.as_ref(), entities_iter)
}
}
#[cfg(feature="parallel_iter")]
impl<'a, 'r, S> SendSto<'a, S>
where
S: ParOptionStorageMut<'r> + StorageRef<'r> + IntoSendStorage<'r>,
{
pub fn par_iter_mut(&'r mut self) -> S::ParIterMut {
ParOptionStorageMut::par_iter_mut(self.0.as_mut())
}
pub fn par_iter_for_entities_mut<E>(&'r mut self, entities_iter: E) -> E::IntoEntitiesParIterMut
where
E: IntoEntitiesParIterator<'r, S::SendStorage>
{
ParOptionStorageMut::par_iter_for_entities_mut(self.0.as_mut(), entities_iter)
}
pub fn par_iter_for_entities_opt_mut<E>(&'r mut self, entities_iter: E) -> E::IntoEntitiesOptParIterMut
where
E: IntoEntitiesParIterator<'r, S::SendStorage>
{
ParOptionStorageMut::par_iter_for_entities_opt_mut(self.0.as_mut(), entities_iter)
}
}
impl<'r, 'a, S> StorageEntitiesExt<'a, S> for &'r mut Sto<'a, S>
where
S: UnorderedData<'a>,
S::Storage: StorageRef<'r> + IntoSendStorage<'r>,
{
type Component = <S::Storage as StorageRef<'r>>::Component;
type IntoStorage = <S::Storage as IntoSendStorage<'r>>::SendStorage;
fn into_storage(self) -> Option<Self::IntoStorage> {
self.0.as_mut().map(|s| s.into_send_storage())
}
fn entities(&self) -> &Entities<'a> {
&self.1
}
fn get(self, entity: &Entity) -> Option<Self::Component>{
self.0.as_mut().and_then(|s| s.get(entity))
}
}
impl<'a, 'r, S> StorageEntitiesExt<'a, S> for &'r Sto<'a, S>
where
S: UnorderedData<'a>,
S::Storage: StorageRef<'r> + IntoSendStorage<'r> + ReadOnlyStorage + 'r,
{
type Component = <S::Storage as StorageRef<'r>>::Component;
type IntoStorage = <S::Storage as IntoSendStorage<'r>>::SendStorage;
fn into_storage(self) -> Option<Self::IntoStorage> {
self.0.as_ref().map(|s| {
let storage: *mut S::Storage = s as *const S::Storage as *mut S::Storage;
unsafe{ (*storage).into_send_storage() }
})
}
fn entities(&self) -> &Entities<'a> {
&self.1
}
fn get(self, entity: &Entity) -> Option<Self::Component>{
self.0.as_ref().and_then(|s| {
let storage: *mut S::Storage = s as *const S::Storage as *mut S::Storage;
unsafe{ (*storage).get(entity) }
})
}
}
pub trait StorageWrapper{
type Storage;
type Data;
}
impl<'a,S> StorageWrapper for Sto<'a, S>
where S: UnorderedData<'a>
{
type Storage = <S as UnorderedData<'a>>::Storage;
type Data = S;
}
impl<'a, C> StorageWrapper for CreationSto<'a, C>
where C: Component
{
type Storage = C::Storage;
type Data = C;
}
pub trait TupleStorageEntities<'a, 'r, U>{
type Storage: StorageRef<'r>;
fn iter(self) -> StorageIter<'r, Self::Storage>
where U: ReadOnlyOp<'a>;
fn iter_mut(self) -> StorageIterMut<'r, Self::Storage, <Self::Storage as StorageRef<'r>>::Component>;
fn iter_for_entities<E>(self, entities_iter: E) -> E::IntoEntitiesIter
where
E: IntoEntitiesIterator<'r, Self::Storage>,
Self::Storage: ReadOnlyStorage;
fn iter_for_entities_mut<E>(self, entities_iter: E) -> E::IntoEntitiesIterMut
where
E: IntoEntitiesIterator<'r, Self::Storage>;
fn iter_for_entities_opt<E>(self, entities_iter: E) -> E::IntoEntitiesOptIter
where
E: IntoEntitiesIterator<'r, Self::Storage>,
Self::Storage: ReadOnlyStorage;
fn iter_for_entities_opt_mut<E>(self, entities_iter: E) -> E::IntoEntitiesOptIterMut
where
E: IntoEntitiesIterator<'r, Self::Storage>;
#[cfg(feature="parallel_iter")]
fn par_iter(self) -> ParStorageIter<'r, Self::Storage>;
#[cfg(feature="parallel_iter")]
fn par_iter_for_entities<E>(self, entities_iter: E) -> E::IntoEntitiesParIter
where
E: IntoEntitiesParIterator<'r, Self::Storage>,
Self::Storage: ReadOnlyStorage;
#[cfg(feature="parallel_iter")]
fn par_iter_for_entities_mut<E>(self, entities_iter: E) -> E::IntoEntitiesParIterMut
where
E: IntoEntitiesParIterator<'r, Self::Storage>;
#[cfg(feature="parallel_iter")]
fn par_iter_for_entities_opt<E>(self, entities_iter: E) -> E::IntoEntitiesOptParIter
where
E: IntoEntitiesParIterator<'r, Self::Storage>,
Self::Storage: ReadOnlyStorage;
#[cfg(feature="parallel_iter")]
fn par_iter_for_entities_opt_mut<E>(self, entities_iter: E) -> E::IntoEntitiesOptParIterMut
where
E: IntoEntitiesParIterator<'r, Self::Storage>;
}
pub trait OptionStorage<'r>: IntoSendStorage<'r>
where Self::SendStorage: ReadOnlyStorage
{
type Iter;
fn iter(this: Option<&'r Self>) -> Self::Iter;
fn iter_for_entities<E>(this: Option<&'r Self>, entities_iter: E) -> E::IntoEntitiesIter
where
E: IntoEntitiesIterator<'r, Self::SendStorage>
{
entities_iter.storage_entities_iter(this.map(|storage| {
let storage = storage as *const Self as *mut Self;
unsafe{ (*storage).into_send_storage() }
}))
}
fn iter_for_entities_opt<E>(this: Option<&'r Self>, entities_iter: E) -> E::IntoEntitiesOptIter
where
E: IntoEntitiesIterator<'r, Self::SendStorage>
{
entities_iter.storage_entities_opt_iter(this.map(|storage| {
let storage = storage as *const Self as *mut Self;
unsafe{ (*storage).into_send_storage() }
}))
}
}
pub trait OptionStorageMut<'r>: IntoSendStorage<'r> {
type IterMut;
fn iter_mut(this: Option<&'r mut Self>) -> Self::IterMut;
fn iter_for_entities_mut<E>(this: Option<&'r mut Self>, entities_iter: E) -> E::IntoEntitiesIterMut
where
E: IntoEntitiesIterator<'r, Self::SendStorage>
{
entities_iter.storage_entities_iter_mut(this.map(|s| s.into_send_storage()))
}
fn iter_for_entities_opt_mut<E>(this: Option<&'r mut Self>, entities_iter: E) -> E::IntoEntitiesOptIterMut
where
E: IntoEntitiesIterator<'r, Self::SendStorage>
{
entities_iter.storage_entities_opt_iter_mut(this.map(|s| s.into_send_storage()))
}
}
#[cfg(feature="parallel_iter")]
pub trait ParOptionStorage<'r>: IntoSendStorage<'r>
where Self::SendStorage: ReadOnlyStorage
{
type ParIter;
fn par_iter(this: Option<&'r Self>) -> Self::ParIter;
fn par_iter_for_entities<E>(this: Option<&'r Self>, entities_iter: E) -> E::IntoEntitiesParIter
where
E: IntoEntitiesParIterator<'r, Self::SendStorage>
{
entities_iter.storage_entities_par_iter(this.map(|storage| {
let storage = storage as *const Self as *mut Self;
unsafe{ (*storage).into_send_storage() }
}))
}
fn par_iter_for_entities_opt<E>(this: Option<&'r Self>, entities_iter: E) -> E::IntoEntitiesOptParIter
where
E: IntoEntitiesParIterator<'r, Self::SendStorage>
{
entities_iter.storage_entities_opt_par_iter(this.map(|storage| {
let storage = storage as *const Self as *mut Self;
unsafe{ (*storage).into_send_storage() }
}))
}
}
#[cfg(feature="parallel_iter")]
pub trait ParOptionStorageMut<'r>: IntoSendStorage<'r> {
type ParIterMut;
fn par_iter_mut(this: Option<&'r mut Self>) -> Self::ParIterMut;
fn par_iter_for_entities_mut<E>(this: Option<&'r mut Self>, entities_iter: E) -> E::IntoEntitiesParIterMut
where
E: IntoEntitiesParIterator<'r, Self::SendStorage>
{
entities_iter.storage_entities_par_iter_mut(this.map(|s| s.into_send_storage()))
}
fn par_iter_for_entities_opt_mut<E>(this: Option<&'r mut Self>, entities_iter: E) -> E::IntoEntitiesOptParIterMut
where
E: IntoEntitiesParIterator<'r, Self::SendStorage>
{
entities_iter.storage_entities_opt_par_iter_mut(this.map(|s| s.into_send_storage()))
}
}
pub trait ReadOnlyOp<'a> {}
impl<'a, U> ReadOnlyOp<'a> for U
where
U: UnorderedData<'a>,
<U as UnorderedData<'a>>::Storage: ReadOnlyStorage
{}
#[doc(hidden)]
pub struct StorageIter<'r, S> {
storage: Option<S>,
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
marker: PhantomData<&'r ()>
}
impl<'r, S> StorageIter<'r, S> {
pub fn by_ref(&mut self) -> &mut Self{
self
}
}
impl<'r, S> Iterator for StorageIter<'r, S>
where
S: StorageRef<'r> + 'r,
{
type Item = <S as StorageRef<'r>>::Component;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
if self.ptr == self.end {
None
} else {
let ids = &*self.ptr;
let ids = ids.unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
let storage: *mut S = self.storage.as_mut().unchecked_unwrap() as *mut S;
Some((*storage).get_fast_unchecked(*ids))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'r, S> ExactSizeIterator for StorageIter<'r, S>
where
S: StorageRef<'r> + 'r,
{
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
#[doc(hidden)]
pub struct StorageIterMut<'r, S, T> {
storage: Option<S>,
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
current: Option<T>,
marker: PhantomData<&'r ()>
}
impl<'r, S, T> StorageIterMut<'r, S, T> {
pub fn by_ref(&mut self) -> &mut Self{
self
}
}
impl<'r, S> Iterator for StorageIterMut<'r, S, <S as StorageRef<'r>>::Component>
where
S: StorageRef<'r> + 'r,
<S as StorageRef<'r>>::Data: SafeIter<'r>,
{
type Item = <S as StorageRef<'r>>::Component;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
if self.ptr == self.end {
None
} else {
let ids = &*self.ptr;
let ids = ids.unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
let storage: *mut S = self.storage.as_mut().unchecked_unwrap() as *mut S;
Some((*storage).get_fast_unchecked(*ids))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'r, S> ExactSizeIterator for StorageIterMut<'r, S, <S as StorageRef<'r>>::Component>
where
S: StorageRef<'r> + 'r,
<S as StorageRef<'r>>::Data: SafeIter<'r>,
{
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
impl<'r, S> StreamingIterator for StorageIterMut<'r, S, <S as StorageRef<'r>>::Component>
where
S: StorageRef<'r> + 'r,
<S as StorageRef<'r>>::Data: SafeStreamingIter<'r>,
{
type Item = <S as StorageRef<'r>>::Component;
fn advance(&mut self) {
unsafe {
if self.ptr == self.end {
self.current = None;
} else {
let ids = &*self.ptr;
let ids = ids.unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
let storage: *mut S = self.storage.as_mut().unchecked_unwrap() as *mut S;
self.current = Some((*storage).get_fast_unchecked(*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 StorageIterMut<'r, S, <S as StorageRef<'r>>::Component>
where
S: StorageRef<'r> + 'r,
<S as StorageRef<'r>>::Data: SafeStreamingIter<'r>,
{
fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.current.as_mut()
}
}
#[cfg(feature = "parallel_iter")]
pub struct ParStorageIter<'r, S>{
ids: &'r [HiddenFastIndex],
storage: Option<S>,
}
#[cfg(feature = "parallel_iter")]
impl<'a,'r,S> ::rayon::iter::ParallelIterator for ParStorageIter<'r, S>
where
S: Send + Sync + StorageRef<'r> + 'r,
S::Component: Send
{
type Item = <S as StorageRef<'r>>::Component;
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where C: ::rayon::iter::plumbing::UnindexedConsumer<Self::Item>
{
use rayon::iter::{IntoParallelRefIterator};
let storage = self.storage;
self.ids.par_iter().map(move |fast_ids| unsafe {
let fast_ids = fast_ids.unchecked_downcast_ref();
let storage = storage.as_ref().unchecked_unwrap();
let storage = storage as *const S as *mut S;
(*storage).get_fast_unchecked(*fast_ids)
}).drive_unindexed(consumer)
}
}
pub unsafe trait SafeIter<'a>{}
pub unsafe trait SafeStreamingIter<'a>{}
macro_rules! impl_combined_unordered_iter {
($storage_ref: ident, $partial_storage_ref: ident, $($s: ident, $u: ident),*) => (
pub struct $partial_storage_ref<$($s),*>{
$(
pub $s: $s,
)*
}
impl<'a, $($s,)*> FastIndexExt for $partial_storage_ref<$($s),*>
where $($s: FastIndexExt,)*
{
type FastIndex = ($($s::FastIndex,)*);
type StaticTypeId = ($($s::StaticTypeId,)*);
fn fast_index(&self, guid: usize) -> Self::FastIndex {
($( self.$s.fast_index(guid), )*)
}
}
pub struct $storage_ref<'a, $($s),*>{
ids: crate::IndexGuard<'a>,
$(
$s: $s,
)*
}
impl<'a, $($s,)*> FastIndexExt for $storage_ref<'a, $($s),*>
where $($s: FastIndexExt,)*
{
type FastIndex = ($($s::FastIndex,)*);
type StaticTypeId = ($($s::StaticTypeId,)*);
fn fast_index(&self, guid: usize) -> Self::FastIndex {
($( self.$s.fast_index(guid), )*)
}
}
impl<'a, 'r, $($s,)*> StorageRef<'r> for $storage_ref<'a, $($s),*>
where $($s: StorageRef<'r>,)*
{
type Data = ($(<$s as StorageRef<'r>>::Data,)*);
type Component = ($(<$s as StorageRef<'r>>::Component,)*);
unsafe fn get_fast_unchecked(&'r mut self, idx: Self::FastIndex) -> Self::Component {
let ($($u,)*) = idx;
($( self.$s.get_fast_unchecked($u) ),*)
}
unsafe fn get_unchecked(&'r mut self, guid: usize) -> Self::Component {
($( self.$s.get_unchecked(guid) ),*)
}
fn contains(&self, guid: usize) -> bool{
($( self.$s.contains(guid) ) && *)
}
}
impl<'a, 'r, $($s,)*> IntoSendStorage<'r> for $storage_ref<'a, $($s),*>
where $($s: IntoSendStorage<'r>,)*
{
type SendStorage = $storage_ref<'a, $($s::SendStorage),*>;
fn into_send_storage(&'r mut self) -> <Self as IntoSendStorage<'r>>::SendStorage {
$storage_ref{
ids: self.ids.clone(),
$(
$s: self.$s.into_send_storage(),
)*
}
}
}
#[cfg(feature = "parallel_iter")]
impl<'a, 'r, $($s),*> super::ParOptionStorage<'r> for $storage_ref<'a, $($s),*>
where
$($s: StorageRef<'r> + 'r,)*
$($s: IntoSendStorage<'r>,)*
$($s::SendStorage: ReadOnlyStorage),*
{
type ParIter = super::ParStorageIter<'r, <Self as IntoSendStorage<'r>>::SendStorage>;
fn par_iter(this: Option<&'r Self>) -> Self::ParIter {
let ids = this.map(|this| &*this.ids).unwrap_or(&[]);
let storage = this.map(|this| unsafe {
let this = this as *const Self as *mut Self;
(*this).into_send_storage()
});
super::ParStorageIter{
ids,
storage,
}
}
}
#[cfg(feature = "parallel_iter")]
impl<'a, 'r, $($s),*> super::ParOptionStorageMut<'r> for $storage_ref<'a, $($s),*>
where
$($s: StorageRef<'r> + 'r,)*
$($s: IntoSendStorage<'r>,)*
{
type ParIterMut = super::ParStorageIter<'r, <Self as IntoSendStorage<'r>>::SendStorage>;
fn par_iter_mut(this: Option<&'r mut Self>) -> Self::ParIterMut {
let ids = this.as_ref().map(|this| unsafe{ crate::utils::delete_lifetime(&*this.ids) }).unwrap_or(&[]);
let storage = this.map(|this| this.into_send_storage());
super::ParStorageIter{
ids,
storage,
}
}
}
unsafe impl<'a, $($s),* > ReadOnlyStorage for $storage_ref<'a, $($s),*>
where $(
$s: ReadOnlyStorage,
)*
{}
impl<'a, 'b, $($s),*> super::OptionStorage<'b> for $storage_ref<'a, $($s),*>
where
$(
$s: StorageRef<'b> + IntoSendStorage<'b> + ReadOnlyStorage,
$s::SendStorage: ReadOnlyStorage,
)*
{
type Iter = StorageIter<'b, $storage_ref<'b, $(<$s as IntoSendStorage<'b>>::SendStorage),*>>;
fn iter(this: Option<&'b Self>) -> Self::Iter {
let storage = this.map(|storage| {
let storage = storage as *const Self as *mut Self;
unsafe{ (*storage).into_send_storage() }
});
let ptr_range = storage.as_ref()
.map(|s| s.ids.as_ptr_range())
.unwrap_or(ptr::null() .. ptr::null());
StorageIter{
storage,
ptr: ptr_range.start,
end: ptr_range.end,
marker: marker::PhantomData,
}
}
}
impl<'a, 'b, $($s),*> super::OptionStorageMut<'b> for $storage_ref<'a, $($s),*>
where
$(
$s: StorageRef<'b> + IntoSendStorage<'b>,
)*
{
type IterMut = StorageIterMut<'b, $storage_ref<'b, $(<$s as IntoSendStorage<'b>>::SendStorage),*>, <$storage_ref<'b, $(<$s as IntoSendStorage<'b>>::SendStorage),*> as StorageRef<'b>>::Component>;
fn iter_mut(this: Option<&'b mut Self>) -> Self::IterMut {
let storage = this.map(|storage| storage.into_send_storage() );
let ptr_range = storage.as_ref()
.map(|s| s.ids.as_ptr_range())
.unwrap_or(ptr::null() .. ptr::null());
StorageIterMut{
storage,
ptr: ptr_range.start,
end: ptr_range.end,
current: None,
marker: marker::PhantomData,
}
}
}
impl<'a, $($u),* > IntoStorages for Sto<'a, ($($u),*)>
where
$($u: UnorderedData<'a>, )*
$($u::Storage: FastIndexExt + StorageRef<'a>, )*
{
type Storages = ($(Sto<'a, $u>),*);
fn into_storages(self) -> Self::Storages {
let (storage, entities) = self.into_storage_entities();
let ($($s,)*) = if let Some(storage) = storage {
($(Some(storage.$s),)*)
}else{
($({let $s = None; $s},)*)
};
($(Sto::new($s, crate::Entities{
storages: entities.storages.clone(),
})),*)
}
}
impl<'a, $($s,)*> FastIndexExt for ($($s),*)
where $($s: FastIndexExt,)*
{
type FastIndex = ($($s::FastIndex,)*);
type StaticTypeId = ($($s::StaticTypeId,)*);
fn fast_index(&self, guid: usize) -> Self::FastIndex {
let ($($s),*) = self;
($( $s.fast_index(guid), )*)
}
}
impl<'a, 'r, $($s,)*> StorageRef<'r> for ($($s),*)
where $($s: StorageRef<'r>,)*
{
type Data = ($(<$s as StorageRef<'r>>::Data,)*);
type Component = ($(<$s as StorageRef<'r>>::Component,)*);
unsafe fn get_fast_unchecked(&'r mut self, idx: Self::FastIndex) -> Self::Component {
let ($($u,)*) = idx;
let ($($s),*) = self;
($( $s.get_fast_unchecked($u) ),*)
}
unsafe fn get_unchecked(&'r mut self, guid: usize) -> Self::Component {
let ($($s),*) = self;
($( $s.get_unchecked(guid) ),*)
}
fn contains(&self, guid: usize) -> bool{
let ($($s),*) = self;
($( $s.contains(guid) ) && *)
}
}
impl<'a, 'r, $($s,)*> IntoSendStorage<'r> for ($($s),*)
where $($s: IntoSendStorage<'r>,)*
{
type SendStorage = ($($s::SendStorage),*);
fn into_send_storage(&'r mut self) -> Self::SendStorage {
let ($($s),*) = self;
($($s.into_send_storage()),*)
}
}
unsafe impl<'a, $($u),* > ReadOnlyStorage for ($($u),*)
where $(
$u: ReadOnlyStorage,
)*
{}
impl<'a, $($u),* > UnorderedData<'a> for ($($u),*)
where $(
$u: UnorderedData<'a>,
<$u as UnorderedData<'a>>::Storage: FastIndexExt,
)*
{
type Iter = StorageIter<'a, Self::Storage>;
type IterMut = StorageIterMut<'a, Self::Storage, Self::ComponentsRef>;
type Components = ($(
<$u as UnorderedData<'a>>::Components
),*);
type ComponentsRef = ($(
<$u as UnorderedData<'a>>::ComponentsRef
),*);
type Storage = $storage_ref<'a, $(
<$u as UnorderedData<'a>>::Storage
),*>;
fn query_mask<E: EntitiesStorage>(entities: &E) -> crate::bitmask::Bitmask {
$($u::query_mask(entities)) | *
}
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter{
let storage = Self::storage(entities);
let ptr_range = storage.as_ref()
.map(|s| s.ids.as_ptr_range())
.unwrap_or(ptr::null() .. ptr::null());
StorageIter{
storage,
ptr: ptr_range.start,
end: ptr_range.end,
marker: marker::PhantomData,
}
}
fn into_iter_mut<E: EntitiesStorage>(entities: &'a E) -> Self::IterMut {
let storage = Self::storage(entities);
let ptr_range = storage.as_ref()
.map(|s| s.ids.as_ptr_range())
.unwrap_or(ptr::null() .. ptr::null());
StorageIterMut{
storage,
ptr: ptr_range.start,
end: ptr_range.end,
current: None,
marker: marker::PhantomData,
}
}
fn storage<E: EntitiesStorage>(entities: &'a E) -> Option<Self::Storage>{
let partial = $partial_storage_ref{
$(
$s: $u::storage(entities)?,
)*
};
let ids = entities.entities_for_mask(
Self::query_mask(entities),
&partial
);
Some($storage_ref{
ids,
$(
$s: partial.$s,
)*
})
}
}
unsafe impl<'a, $($u),* > SafeIter<'a> for ($($u),*)
where $(
$u: SafeIter<'a>,
)* {}
impl<'a, $($u),* > DataAccesses for ($($u),*)
where $($u: DataAccesses),*
{
fn reads() -> Vec<TypeId>{
let mut reads = vec![];
$(
reads.extend_from_slice(&$u::reads());
)*
reads
}
fn writes() -> Vec<TypeId>{
let mut writes = vec![];
$(
writes.extend_from_slice(&$u::writes());
)*
writes
}
}
impl<'a, $($u, $s),*> StorageEntitiesExt<'a, ($($u),*)> for ($($s),*)
where
$(
$u: UnorderedData<'a>,
<$u as UnorderedData<'a>>::Storage: FastIndexExt,
$s: StorageEntitiesExt<'a, $u>,
<$s as StorageEntitiesExt<'a, $u>>::IntoStorage: FastIndexExt,
)*
{
type Component = ($($s::Component),*);
type IntoStorage = $storage_ref<'a, $(<$s as StorageEntitiesExt<'a, $u>>::IntoStorage),*>;
fn into_storage(self) -> Option<Self::IntoStorage> {
let entities = crate::Entities {
storages: self.entities().storages.clone()
};
let ($($s),*) = self;
let ($($s),*) = ($($s.into_storage()?),*);
let partial = $partial_storage_ref{ $($s),* };
let ids = entities.entities_for_mask(
<($($u,)*)>::query_mask(&entities),
&partial
);
let ids = unsafe{ std::mem::transmute(ids) };
Some($storage_ref{
ids,
$(
$s: partial.$s,
)*
})
}
fn entities(&self) -> &crate::Entities<'a> {
self.0.entities()
}
fn get(self, entity: &crate::Entity) -> Option<Self::Component> {
let ($($s,)*) = self;
Some(($($s.get(entity)?),*))
}
}
impl<'a, 'r, $($s, $u),*> super::TupleStorageEntities<'a, 'r, ($($u),*)> for ($($s),*)
where
'a: 'r,
$($u: UnorderedData<'a> + 'r,)*
$(<$u as UnorderedData<'a>>::Storage: FastIndexExt,)*
$($s: StorageEntitiesExt<'a, $u> + 'r,)*
$(<$s as StorageEntitiesExt<'a, $u>>::IntoStorage: StorageRef<'r>,)*
{
type Storage = $storage_ref<'a, $(<$s as StorageEntitiesExt<'a, $u>>::IntoStorage),*>;
fn iter(self) -> StorageIter<'r, Self::Storage> {
let storage = self.into_storage();
let ptr_range = storage.as_ref()
.map(|s| s.ids.as_ptr_range())
.unwrap_or(ptr::null() .. ptr::null());
StorageIter {
storage,
ptr: ptr_range.start,
end: ptr_range.end,
marker: marker::PhantomData,
}
}
fn iter_mut(self) -> StorageIterMut<'r, Self::Storage, <Self::Storage as StorageRef<'r>>::Component> {
let storage = self.into_storage();
let ptr_range = storage.as_ref()
.map(|s| s.ids.as_ptr_range())
.unwrap_or(ptr::null() .. ptr::null());
StorageIterMut {
storage,
ptr: ptr_range.start,
end: ptr_range.end,
current: None,
marker: marker::PhantomData,
}
}
fn iter_for_entities<E>(self, entities_iter: E) -> E::IntoEntitiesIter
where
E: IntoEntitiesIterator<'r, Self::Storage>,
Self::Storage: ReadOnlyStorage
{
entities_iter.storage_entities_iter(self.into_storage())
}
fn iter_for_entities_mut<E>(self, entities_iter: E) -> E::IntoEntitiesIterMut
where
E: IntoEntitiesIterator<'r, Self::Storage>,
{
entities_iter.storage_entities_iter_mut(self.into_storage())
}
fn iter_for_entities_opt<E>(self, entities_iter: E) -> E::IntoEntitiesOptIter
where
E: IntoEntitiesIterator<'r, Self::Storage>,
Self::Storage: ReadOnlyStorage
{
entities_iter.storage_entities_opt_iter(self.into_storage())
}
fn iter_for_entities_opt_mut<E>(self, entities_iter: E) -> E::IntoEntitiesOptIterMut
where
E: IntoEntitiesIterator<'r, Self::Storage>,
{
entities_iter.storage_entities_opt_iter_mut(self.into_storage())
}
#[cfg(feature="parallel_iter")]
fn par_iter(self) -> ParStorageIter<'r, Self::Storage> {
let storage = self.into_storage();
let ids = storage.as_ref()
.map(|storage| unsafe{ crate::utils::delete_lifetime(&*storage.ids) })
.unwrap_or(&[]);
super::ParStorageIter {
ids,
storage,
}
}
#[cfg(feature="parallel_iter")]
fn par_iter_for_entities<E>(self, entities_iter: E) -> E::IntoEntitiesParIter
where
E: IntoEntitiesParIterator<'r, Self::Storage>,
Self::Storage: ReadOnlyStorage
{
entities_iter.storage_entities_par_iter(self.into_storage())
}
#[cfg(feature="parallel_iter")]
fn par_iter_for_entities_mut<E>(self, entities_iter: E) -> E::IntoEntitiesParIterMut
where
E: IntoEntitiesParIterator<'r, Self::Storage>,
{
entities_iter.storage_entities_par_iter_mut(self.into_storage())
}
#[cfg(feature="parallel_iter")]
fn par_iter_for_entities_opt<E>(self, entities_iter: E) -> E::IntoEntitiesOptParIter
where
E: IntoEntitiesParIterator<'r, Self::Storage>,
Self::Storage: ReadOnlyStorage
{
entities_iter.storage_entities_opt_par_iter(self.into_storage())
}
#[cfg(feature="parallel_iter")]
fn par_iter_for_entities_opt_mut<E>(self, entities_iter: E) -> E::IntoEntitiesOptParIterMut
where
E: IntoEntitiesParIterator<'r, Self::Storage>,
{
entities_iter.storage_entities_opt_par_iter_mut(self.into_storage())
}
}
)
}
#[allow(non_snake_case)]
pub mod combined_unordered{
use std::marker;
use crate::operators::{UnorderedData, DataAccesses};
use crate::storage::{
ReadOnlyStorage, StorageRef, StorageEntitiesExt,
FastIndexExt, IntoSendStorage, IntoStorages,
};
use crate::utils::IntoEntitiesIterator;
#[cfg(feature="parallel_iter")]
use crate::utils::IntoEntitiesParIterator;
use crate::entity::EntitiesStorage;
use std::any::TypeId;
use std::ptr;
use super::{StorageIter, SafeIter, StorageIterMut, Sto};
#[cfg(feature="parallel_iter")]
use super::ParStorageIter;
#[cfg(any(feature="storage_macros_2", feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef2, PartialStorageRef2, S1, U1, S2, U2);
#[cfg(any(feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef3, PartialStorageRef3, S1, U1, S2, U2, S3, U3);
#[cfg(any(feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef4, PartialStorageRef4, S1, U1, S2, U2, S3, U3, S4, U4);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef5, PartialStorageRef5, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef6, PartialStorageRef6, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef7, PartialStorageRef7, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef8, PartialStorageRef8, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef9, PartialStorageRef9, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8, S9, U9);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef10, PartialStorageRef10, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8, S9, U9, S10, U10);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef11, PartialStorageRef11, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8, S9, U9, S10, U10, S11, U11);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef12, PartialStorageRef12, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8, S9, U9, S10, U10, S11, U11, S12, U12);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef13, PartialStorageRef13, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8, S9, U9, S10, U10, S11, U11, S12, U12, S13, U13);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef14, PartialStorageRef14, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8, S9, U9, S10, U10, S11, U11, S12, U12, S13, U13, S14, U14);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef15, PartialStorageRef15, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8, S9, U9, S10, U10, S11, U11, S12, U12, S13, U13, S14, U14, S15, U15);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_unordered_iter!(StorageRef16, PartialStorageRef16, S1, U1, S2, U2, S3, U3, S4, U4, S5, U5, S6, U6, S7, U7, S8, U8, S9, U9, S10, U10, S11, U11, S12, U12, S13, U13, S14, U14, S15, U15, S16, U16);
}
pub trait OrderedData<'a> {
type Iter;
type Components;
type ComponentsRef;
type Storage;
fn query_mask<E: EntitiesStorage>(entities: &E) -> Bitmask;
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter;
fn storage<E: EntitiesStorage>(entities: &'a E) -> Option<Self::Storage>;
fn ordered_ids<S: FastIndexExt, E: EntitiesStorage>(entities: &'a E, query_mask: Bitmask, unordered_storage: &S) -> OrderedIndexGuard<'a>;
}
pub trait OrderedDataSend<'a>: OrderedData<'a>{}
impl<'a, U> OrderedDataSend<'a> for U
where
U: OrderedData<'a>,
<U as OrderedData<'a>>::Components: Send
{}
pub trait ReadOnlyOrderedOp<'a> {}
impl<'a, U> ReadOnlyOrderedOp<'a> for U
where
U: OrderedData<'a>,
<U as OrderedData<'a>>::Storage: ReadOnlyStorage
{}
macro_rules! impl_combined_ordered_iter {
($intoiter: ident, $iter: ident, $idediter: ident, $ordered_idediter: ident, $storage_ref: ident, $partial_storage_ref: ident, $to:ident, $so:ident, $uo:ident, $($t: ident, $s: ident, $u: ident),*) => (
#[allow(dead_code)]
pub struct $intoiter<'a, $so, SU, $($s),*>{
ids: Option<crate::OrderedIndexGuard<'a>>,
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
$so: Option<$so>,
su: Option<SU>,
$(
$s: marker::PhantomData<$s>
),*
}
#[allow(unused_parens)]
impl<'a, $so, SU, $($s),*> Iterator for $intoiter<'a, $so, SU, $($s),*>
where
$so: StorageRef<'a> + 'a,
SU: StorageRef<'a, Component = ($(<$s as StorageRef<'a>>::Component),*)>
+ FastIndexExt<FastIndex = ($(<$s as FastIndexExt>::FastIndex),*)>
+ 'a,
$( $s: StorageRef<'a> + 'a, )*
{
type Item = ($so::Component, $($s::Component),*);
fn next(&mut self) -> Option<Self::Item>{
unsafe {
if self.ptr == self.end {
None
} else {
let fast_ids = (*self.ptr).unchecked_downcast_ref();
let ($uo, ($($u),*)) = fast_ids;
let $uo: crate::storage::OrderedId<<$so as FastIndexExt>::FastIndex> = *$uo;
self.ptr = self.ptr.offset(1);
let $so: *mut $so = delete_lifetime_mut(self.$so.as_mut().unchecked_unwrap());
let su = delete_lifetime_mut(self.su.as_mut().unchecked_unwrap());
let ($($u),*) = su.get_fast_unchecked(($(*$u),*));
Some(((*$so).get_fast_unchecked($uo.fast), $($u),*))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
#[allow(unused_parens)]
impl<'a, $so, SU, $($s),*> ExactSizeIterator for $intoiter<'a, $so, SU, $($s),*>
where
$so: StorageRef<'a> + 'a,
SU: StorageRef<'a, Component = ($(<$s as StorageRef<'a>>::Component),*)>
+ FastIndexExt<FastIndex = ($(<$s as FastIndexExt>::FastIndex),*)>
+ 'a,
$( $s: StorageRef<'a> + 'a, )*
{
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
#[allow(dead_code)]
pub struct $idediter<'r,I,$so,$($s,)*>{
ids: I,
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
$so: $so,
$(
$s: $s,
)*
marker: marker::PhantomData<&'r ()>
}
impl<'r, I, $so, $($s,)*> Iterator for $idediter<'r, I, $so, $($s,)*>
where
$so: StorageRef<'r> + 'r,
$($s: StorageRef<'r> + 'r,)*
{
type Item = (usize, ($so::Component, $($s::Component),*));
fn next(&mut self) -> Option<Self::Item>{
unsafe {
if self.ptr == self.end {
None
} else {
let fast_ids = (*self.ptr).unchecked_downcast_ref();
let (guid, $uo, $($u),*) = fast_ids;
self.ptr = self.ptr.offset(1);
let $so: *mut $so = delete_lifetime_mut(&mut self.$so);
let ($($s,)*): ($(*mut $s,)*) = ($(delete_lifetime_mut(&mut self.$s),)*);
Some((*guid, ((*$so).get_fast_unchecked(*$uo), $((*$s).get_fast_unchecked(*$u)),*)))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'r, I, $so, $($s,)*> ExactSizeIterator for $idediter<'r, I, $so, $($s,)*>
where
$so: StorageRef<'r> + 'r,
$($s: StorageRef<'r> + 'r,)*
{
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
#[allow(dead_code)]
pub struct $ordered_idediter<'r, I,$so,$($s,)*>{
_ids: I,
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
$so: $so,
$(
$s: $s,
)*
marker: marker::PhantomData<&'r ()>
}
impl<'r, I, $so, $($s,)*> Iterator for $ordered_idediter<'r, I, $so, $($s,)*>
where
$so: StorageRef<'r> + 'r,
$($s: StorageRef<'r> + 'r,)*
{
type Item = (usize, ($so::Component, $($s::Component),*));
fn next(&mut self) -> Option<Self::Item>{
unsafe {
if self.ptr == self.end {
None
} else {
let fast_ids = (*self.ptr).unchecked_downcast_ref();
let ($uo, $($u),*) = fast_ids;
let $uo: crate::storage::OrderedId<<$so as FastIndexExt>::FastIndex> = *$uo;
self.ptr = self.ptr.offset(1);
let $so: *mut $so = delete_lifetime_mut(&mut self.$so);
let ($($s,)*): ($(*mut $s,)*) = ($(delete_lifetime_mut(&mut self.$s),)*);
Some(($uo.guid, ((*$so).get_fast_unchecked($uo.fast), $((*$s).get_fast_unchecked(*$u)),*)))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'r, I, $so, $($s,)*> ExactSizeIterator for $ordered_idediter<'r, I, $so, $($s,)*>
where
$so: StorageRef<'r> + 'r,
$($s: StorageRef<'r> + 'r,)*
{
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
#[allow(dead_code)]
pub struct $iter<'r, $so, $($s,)*>{
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
storage: $storage_ref<'r, $so, $($s),*>,
}
impl<'r, $so, $($s: StorageRef<'r>,)*> Iterator for $iter<'r, $so, $($s,)*>
where
$so: StorageRef<'r> + 'r,
$($s: StorageRef<'r> + 'r,)*
{
type Item = ($so::Component,$($s::Component),*);
fn next(&mut self) -> Option<Self::Item>{
unsafe {
if self.ptr == self.end {
None
} else {
let fast_ids = (*self.ptr).unchecked_downcast_ref();
let (_guid, $uo, $($u),*) = fast_ids;
let _guid: usize = *_guid;
self.ptr = self.ptr.offset(1);
let $so: *mut $so = delete_lifetime_mut(&mut self.storage.$so);
let ($($s,)*): ($(*mut $s,)*) = ($(delete_lifetime_mut(&mut self.storage.$s),)*);
Some(((*$so).get_fast_unchecked(*$uo), $((*$s).get_fast_unchecked(*$u)),*))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end as usize - self.ptr as usize;
(len, Some(len))
}
}
impl<'r, $so, $($s: StorageRef<'r>,)*> ExactSizeIterator for $iter<'r, $so, $($s,)*>
where
$so: StorageRef<'r> + 'r,
$($s: StorageRef<'r> + 'r,)*
{
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
pub struct $partial_storage_ref<$so, $($s),*>{
$so: $so,
$(
$s: $s,
)*
}
impl<$so, $($s,)*> FastIndexExt for $partial_storage_ref<$so, $($s),*>
where
$so: FastIndexExt,
$($s: FastIndexExt,)*
{
type FastIndex = (usize, <$so as FastIndexExt>::FastIndex, $(<$s as FastIndexExt>::FastIndex,)*);
type StaticTypeId = (<$so as FastIndexExt>::StaticTypeId, $(<$s as FastIndexExt>::StaticTypeId,)*);
fn fast_index(&self, guid: usize) -> Self::FastIndex {
(guid, self.$so.fast_index(guid), $( self.$s.fast_index(guid), )*)
}
}
pub struct $storage_ref<'a, $so, $($s),*>{
ids: crate::IndexGuard<'a>,
$so: $so,
$(
$s: $s,
)*
}
impl<'a, 'r, $so, $($s,)*> $storage_ref<'a, $so, $($s),*>
where
$so: IntoSendStorage<'r>,
$($s: IntoSendStorage<'r>,)*
{
pub fn iter(&'r mut self) -> $iter<'r, <$so as IntoSendStorage<'r>>::SendStorage, $(<$s as IntoSendStorage<'r>>::SendStorage),*>{
let ptr_range = self.ids.as_ptr_range();
$iter{
ptr: ptr_range.start,
end: ptr_range.end,
storage: self.into_send_storage(),
}
}
}
impl<'a, $so, $($s,)*> FastIndexExt for $storage_ref<'a, $so, $($s),*>
where
$so: FastIndexExt,
$($s: FastIndexExt,)*
{
type FastIndex = (<$so as FastIndexExt>::FastIndex, $(<$s as FastIndexExt>::FastIndex,)*);
type StaticTypeId = (<$so as FastIndexExt>::StaticTypeId, $(<$s as FastIndexExt>::StaticTypeId,)*);
fn fast_index(&self, guid: usize) -> Self::FastIndex {
(self.$so.fast_index(guid), $( self.$s.fast_index(guid), )*)
}
}
impl<'a, 'r, $so, $($s,)*> StorageRef<'r> for $storage_ref<'a, $so, $($s),*>
where
$so: StorageRef<'r>,
$($s: StorageRef<'r>,)*
{
type Data = (<$so as StorageRef<'r>>::Data, $(<$s as StorageRef<'r>>::Data,)*);
type Component = (<$so as StorageRef<'r>>::Component, $(<$s as StorageRef<'r>>::Component,)*);
unsafe fn get_fast_unchecked(&'r mut self, idx: Self::FastIndex) -> Self::Component {
let ($uo, $($u,)*) = idx;
(self.$so.get_fast_unchecked($uo), $( self.$s.get_fast_unchecked($u) ),*)
}
unsafe fn get_unchecked(&'r mut self, guid: usize) -> Self::Component {
(self.$so.get_unchecked(guid), $( self.$s.get_unchecked(guid) ),*)
}
fn contains(&self, guid: usize) -> bool{
self.$so.contains(guid) && $( self.$s.contains(guid) )&*
}
}
impl<'a, 'r, $so, $($s,)*> IntoSendStorage<'r> for $storage_ref<'a, $so, $($s),*>
where
$so: IntoSendStorage<'r>,
$($s: IntoSendStorage<'r>,)*
{
type SendStorage = $storage_ref<'r, <$so as IntoSendStorage<'r>>::SendStorage, $(<$s as IntoSendStorage<'r>>::SendStorage),*>;
fn into_send_storage(&'r mut self) -> Self::SendStorage {
$storage_ref{
ids: self.ids.clone(),
$so: self.$so.into_send_storage(),
$(
$s: self.$s.into_send_storage()
),*
}
}
}
unsafe impl<'a, $so, $($s,)*> ReadOnlyStorage for $storage_ref<'a, $so, $($s),*>
where
$so: ReadOnlyStorage,
$($s: ReadOnlyStorage),*
{}
impl<'a, $uo: crate::ChangedData<'a>, $($u),* > crate::ChangedData<'a> for ($uo, $($u),*)
where
$uo: UnorderedData<'a>,
<$uo as UnorderedData<'a>>::Storage: FastIndexExt,
$(
$u: UnorderedData<'a>,
<$u as UnorderedData<'a>>::Storage: StorageRef<'a> + FastIndexExt,
)*
{
type ChangedIter = <$uo as crate::ChangedData<'a>>::ChangedIter;
fn changed_iter<E: EntitiesStorage>(entities: &'a E) -> Self::ChangedIter{
$uo::changed_iter(entities)
}
}
impl<'a, $uo, $($u),*> crate::ChangesData<'a> for ($uo, $($u),*)
where
$uo: 'a + crate::ChangesData<'a> + UnorderedData<'a>,
<$uo as UnorderedData<'a>>::Storage: FastIndexExt,
$(
$u: 'a + UnorderedData<'a>,
<$u as UnorderedData<'a>>::Storage: StorageRef<'a, Component = $u::ComponentsRef>,
)*
<$uo as crate::ChangesData<'a>>::SubStorage: StorageRef<'a, Component = $uo::ComponentsRef>,
{
type SubStorage = $storage_ref<'a,
<$uo as crate::ChangesData<'a>>::SubStorage,
$(
<$u as UnorderedData<'a>>::Storage
),*>;
fn extend_changes<F>(entities: &'a crate::Entities, mut has_changed: F)
where F: FnMut(Self::ComponentsRef) -> bool
{
use UnorderedData;
let ($so, changes) = unwrap_or_return!(unsafe{ $uo::storage_and_changes(entities) });
let partial = $partial_storage_ref{
$so,
$(
$s: unwrap_or_return!($u::storage(entities)),
)*
};
let ids = entities.entities_for_mask(
Self::query_mask(entities),
&partial
);
let ptr_range = ids.as_ptr_range();
let iter = $idediter{
ptr: ptr_range.start,
end: ptr_range.end,
ids,
$so: partial.$so,
$(
$s: partial.$s,
)*
marker: marker::PhantomData,
};
changes.extend(iter.filter_map(|(id, t)| if has_changed(t){
Some(id)
}else{
None
}));
}
unsafe fn storage_and_changes(entities: &'a crate::Entities) -> Option<(Self::SubStorage, &'a mut hashbrown::HashSet<usize>)> {
let ($so, changes) = $uo::storage_and_changes(entities)?;
let partial = $partial_storage_ref{
$so,
$(
$s: $u::storage(entities)?,
)*
};
let ids = entities.entities_for_mask(
$uo::query_mask(entities),
&partial
);
let storage = $storage_ref{
ids,
$so: partial.$so,
$(
$s: partial.$s,
)*
};
Some((storage, changes))
}
}
impl<'a, $uo, $($u),*> crate::ChangesOrderedData<'a> for ($uo, $($u),*)
where
$uo: 'a + crate::ChangesOrderedData<'a>,
<$uo as OrderedData<'a>>::Storage: FastIndexExt,
$(
<$u as UnorderedData<'a>>::Storage: StorageRef<'a, Component = $u::ComponentsRef>,
$u: 'a + UnorderedData<'a>,
)*
<$uo as crate::ChangesOrderedData<'a>>::SubStorage: StorageRef<'a, Component = $uo::ComponentsRef>,
{
type SubStorage = $storage_ref<'a,
<$uo as crate::ChangesOrderedData<'a>>::SubStorage,
$(
<$u as UnorderedData<'a>>::Storage
),
*>;
#[allow(unused_parens)]
fn extend_changes<F, E: EntitiesStorage>(entities: &'a E, mut has_changed: F)
where F: FnMut(Self::ComponentsRef) -> bool
{
use OrderedData;
let unordered_storage = unwrap_or_return!(<($($u),*) as UnorderedData<'a>>::storage(entities));
let ids = $uo::ordered_ids(
entities,
Self::query_mask(entities),
&unordered_storage
);
let ($so, changes) = unwrap_or_return!(unsafe{ $uo::storage_and_changes(entities) });
let ptr_range = ids.as_ptr_range();
let iter = $ordered_idediter{
ptr: ptr_range.start,
end: ptr_range.end,
_ids: ids,
$so,
$(
$s: unwrap_or_return!($u::storage(entities)),
)*
marker: marker::PhantomData,
};
changes.extend(iter.filter_map(|(id, t)| if has_changed(t){
Some(id)
}else{
None
}));
}
unsafe fn storage_and_changes<E: EntitiesStorage>(entities: &'a E) -> Option<(Self::SubStorage, &'a mut hashbrown::HashSet<usize>)> {
let ($so, changes) = $uo::storage_and_changes(entities)?;
let partial = $partial_storage_ref{
$so,
$(
$s: $u::storage(entities)?,
)*
};
let ids = entities.entities_for_mask(
<$uo as OrderedData>::query_mask(entities),
&partial
);
let storage = $storage_ref{
ids,
$so: partial.$so,
$(
$s: partial.$s,
)*
};
Some((storage, changes))
}
}
#[allow(unused_parens)]
impl<'a, $uo, $($u),* > OrderedData<'a> for ($uo, $($u),*)
where
$uo: OrderedData<'a> + 'a,
<$uo as OrderedData<'a>>::Storage: FastIndexExt,
$(
$u: UnorderedData<'a> + 'a,
<$u as UnorderedData<'a>>::Storage: FastIndexExt + StorageRef<'a>,
)*
{
type Iter = $intoiter<'a,
<$uo as OrderedData<'a>>::Storage,
<($($u),*) as UnorderedData<'a>>::Storage,
$(<$u as UnorderedData<'a>>::Storage),*
>;
type Components =
(<$uo as OrderedData<'a>>::Components,
$(
<$u as UnorderedData<'a>>::Components
),*);
type ComponentsRef =
(<$uo as OrderedData<'a>>::ComponentsRef,
$(
<$u as UnorderedData<'a>>::ComponentsRef
),*);
type Storage = $storage_ref<'a,
<$uo as OrderedData<'a>>::Storage,
$(
<$u as UnorderedData<'a>>::Storage
),*>;
fn query_mask<E: EntitiesStorage>(entities: &E) -> crate::bitmask::Bitmask {
<$uo as OrderedData>::query_mask(entities) | $($u::query_mask(entities)) | *
}
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter{
let unordered_storage = <($($u),*) as UnorderedData<'a>>::storage(entities);
let ids = unordered_storage.as_ref().map(|unordered_storage| $uo::ordered_ids(
entities,
Self::query_mask(entities),
unordered_storage
));
let ptr_range = ids.as_ref()
.map(|ids| ids.as_ptr_range())
.unwrap_or(ptr::null() .. ptr::null());
$intoiter{
ptr: ptr_range.start,
end: ptr_range.end,
ids,
$so: <$uo as OrderedData>::storage(entities),
su: unordered_storage,
$(
$s: marker::PhantomData,
)*
}
}
fn storage<E: EntitiesStorage>(entities: &'a E) -> Option<Self::Storage>{
let partial = $partial_storage_ref{
$so: <$uo as OrderedData>::storage(entities)?,
$(
$s: $u::storage(entities)?,
)*
};
let ids = entities.entities_for_mask(
Self::query_mask(entities),
&partial
);
Some($storage_ref{
ids,
$so: partial.$so,
$(
$s: partial.$s,
)*
})
}
fn ordered_ids<S: FastIndexExt, E: EntitiesStorage>(entities: &'a E, query_mask: crate::Bitmask, unordered_storage: &S) -> crate::OrderedIndexGuard<'a> {
$uo::ordered_ids(entities, query_mask, unordered_storage)
}
}
unsafe impl<'a, $uo, $($u),* > SafeStreamingIter<'a> for ($uo, $($u),*)
where
$uo: SafeStreamingIter<'a>,
{}
)
}
#[allow(non_snake_case)]
mod combined_ordered{
use std::marker;
use crate::storage::{HiddenFastIndex, FastIndexExt, IntoSendStorage, StorageRef, ReadOnlyStorage, };
use std::ptr;
use crate::unwrap_or_return;
use unchecked_unwrap::*;
use super::{UnorderedData, OrderedData, SafeStreamingIter};
use crate::entity::EntitiesStorage;
use crate::utils::delete_lifetime_mut;
#[cfg(any(feature="storage_macros_2", feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer2, Iter2, IdedIter2, OrderedIdedIter2, StorageRef2, PartialStorageRef2, TO, SO, UO, T1, S1, U1);
#[cfg(any(feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer3, Iter3, IdedIter3, OrderedIdedIter3, StorageRef3, PartialStorageRef3, TO, SO, UO, T1, S1, U1, T2, S2, U2);
#[cfg(any(feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer4, Iter4, IdedIter4, OrderedIdedIter4, StorageRef4, PartialStorageRef4, TO, SO, UO, T1, S1, U1, T2, S2, U2, T3, S3, U3);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer5, Iter5, IdedIter5, OrderedIdedIter5, StorageRef5, PartialStorageRef5, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer6, Iter6, IdedIter6, OrderedIdedIter6, StorageRef6, PartialStorageRef6, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer7, Iter7, IdedIter7, OrderedIdedIter7, StorageRef7, PartialStorageRef7, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer8, Iter8, IdedIter8, OrderedIdedIter8, StorageRef8, PartialStorageRef8, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer9, Iter9, IdedIter9, OrderedIdedIter9, StorageRef9, PartialStorageRef9, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8, T9, S9, U9);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer10, Iter10, IdedIter10, OrderedIdedIter10, StorageRef10, PartialStorageRef10, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8, T9, S9, U9, T10, S10, U10);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer11, Iter11, IdedIter11, OrderedIdedIter11, StorageRef11, PartialStorageRef11, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8, T9, S9, U9, T10, S10, U10, T11, S11, U11);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer12, Iter12, IdedIter12, OrderedIdedIter12, StorageRef12, PartialStorageRef12, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8, T9, S9, U9, T10, S10, U10, T11, S11, U11, T12, S12, U12);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer13, Iter13, IdedIter13, OrderedIdedIter13, StorageRef13, PartialStorageRef13, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8, T9, S9, U9, T10, S10, U10, T11, S11, U11, T12, S12, U12, T13, S13, U13);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer14, Iter14, IdedIter14, OrderedIdedIter14, StorageRef14, PartialStorageRef14, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8, T9, S9, U9, T10, S10, U10, T11, S11, U11, T12, S12, U12, T13, S13, U13, T14, S14, U14);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer15, Iter15, IdedIter15, OrderedIdedIter15, StorageRef15, PartialStorageRef15, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8, T9, S9, U9, T10, S10, U10, T11, S11, U11, T12, S12, U12, T13, S13, U13, T14, S14, U14, T15, S15, U15);
#[cfg(any(feature="storage_macros_16"))]
impl_combined_ordered_iter!(IntoITer16, Iter16, IdedIter16, OrderedIdedIter16, StorageRef16, PartialStorageRef16, T1, S1, U1, T2, S2, U2, T3, S3, U3, T4, S4, U4, T5, S5, U5, T6, S6, U6, T7, S7, U7, T8, S8, U8, T9, S9, U9, T10, S10, U10, T11, S11, U11, T12, S12, U12, T13, S13, U13, T14, S14, U14, T15, S15, U15, T16, S16, U16);
}
#[cfg(feature = "parallel_iter")]
#[doc(hidden)]
pub trait EntitiesDataParallel<'a, E>{
type ParIter;
fn into_entities_par_iter(entities: &Entities<'a>, entities_iter: E) -> Self::ParIter;
}
#[doc(hidden)]
pub struct EntitiesComponentIter<'s, E, S>
where
S: StorageRef<'s> + 's
{
pub(crate) entities: E,
pub(crate) storage: Option<S>,
pub(crate) marker: PhantomData<&'s ()>,
}
impl<'s, E, S> Iterator for EntitiesComponentIter<'s, E, S>
where
E: Iterator<Item = crate::Entity>,
S: StorageRef<'s> + 's,
{
type Item = <S as StorageRef<'s>>::Component;
fn next(&mut self) -> Option<Self::Item> {
if let Some(storage) = self.storage.as_mut() {
let storage = unsafe{ delete_lifetime_mut(storage) };
while let Some(e) = self.entities.next(){
let guid = e.guid();
if storage.contains(guid){
return Some(unsafe{ storage.get_unchecked(guid) });
}
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.entities.size_hint().1)
}
}
#[doc(hidden)]
pub struct EntitiesComponentOptIter<'s, E, S>
where
S: StorageRef<'s> + 's
{
pub(crate) entities: E,
pub(crate) storage: Option<S>,
pub(crate) marker: PhantomData<&'s ()>,
}
impl<'s, E, S> Iterator for EntitiesComponentOptIter<'s, E, S>
where
E: Iterator<Item = crate::Entity>,
S: StorageRef<'s> + 's,
{
type Item = Option<<S as StorageRef<'s>>::Component>;
fn next(&mut self) -> Option<Self::Item> {
let storage= self.storage.as_mut()?;
let storage = unsafe{ delete_lifetime_mut(storage) };
let e = self.entities.next()?;
Some(storage.get(&e))
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.entities.size_hint().1)
}
}
#[doc(hidden)]
pub struct EntitiesComponentIterMut<'s, E, S>
where
S: StorageRef<'s> + 's
{
pub(crate) entities: E,
pub(crate) storage: Option<S>,
pub(crate) current: Option<<S as StorageRef<'s>>::Component>,
pub(crate) marker: PhantomData<&'s ()>,
}
impl<'s, E, S> StreamingIterator for EntitiesComponentIterMut<'s, E, S>
where
E: Iterator<Item = crate::Entity>,
S: StorageRef<'s> + 's,
{
type Item = <S as StorageRef<'s>>::Component;
fn advance(&mut self) {
if let Some(storage) = self.storage.as_mut() {
let storage = unsafe{ delete_lifetime_mut(storage) };
while let Some(e) = self.entities.next(){
let guid = e.guid();
if storage.contains(guid){
self.current = Some(unsafe{ 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>) {
(0, self.entities.size_hint().1)
}
}
impl<'s, E, S> StreamingIteratorMut for EntitiesComponentIterMut<'s, E, S>
where
E: Iterator<Item = crate::Entity>,
S: StorageRef<'s> + 's
{
fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.current.as_mut()
}
}
#[doc(hidden)]
pub struct EntitiesComponentOptIterMut<'s, E, S>
where
S: StorageRef<'s> + 's
{
pub(crate) entities: E,
pub(crate) storage: Option<S>,
pub(crate) current: Option<Option<<S as StorageRef<'s>>::Component>>,
pub(crate) marker: PhantomData<&'s ()>,
}
impl<'s, E, S> StreamingIterator for EntitiesComponentOptIterMut<'s, E, S>
where
E: Iterator<Item = crate::Entity>,
S: StorageRef<'s> + 's,
{
type Item = Option<<S as StorageRef<'s>>::Component>;
fn advance(&mut self) {
if let Some(storage) = self.storage.as_mut() {
let storage = unsafe{ delete_lifetime_mut(storage) };
self.current = self.entities.next().map(move |e| {
storage.get(&e)
});
}
}
fn get(&self) -> Option<&Self::Item> {
self.current.as_ref()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.entities.size_hint().1)
}
}
impl<'s, E, S> StreamingIteratorMut for EntitiesComponentOptIterMut<'s, E, S>
where
E: Iterator<Item = crate::Entity>,
S: StorageRef<'s> + 's
{
fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.current.as_mut()
}
}
#[cfg(feature="parallel_iter")]
#[doc(hidden)]
pub struct ParEntitiesComponentIter<'s, E, S>
where
S: StorageRef<'s> + 's
{
pub(crate) entities: E,
pub(crate) storage: Option<S>,
pub(crate) marker: PhantomData<&'s ()>,
}
#[cfg(feature="parallel_iter")]
impl<'s, E, S> ParallelIterator for ParEntitiesComponentIter<'s, E, S>
where
E: ParallelIterator<Item = crate::Entity>,
S: StorageRef<'s> + Send + Sync + 's,
S::Component: Send,
{
type Item = S::Component;
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>
{
if let Some(storage) = self.storage {
self.entities.into_par_iter()
.filter_map(|e| {
if storage.contains(e.guid()){
let storage = &storage as *const S as *mut S;
Some(unsafe{ (*storage).get_unchecked(e.guid()) })
}else{
None
}
})
.drive_unindexed(consumer)
}else{
None.into_par_iter().drive_unindexed(consumer)
}
}
}
#[cfg(feature="parallel_iter")]
#[doc(hidden)]
pub struct ParEntitiesComponentOptIter<'s, E, S>
where
S: StorageRef<'s> + 's
{
pub(crate) entities: E,
pub(crate) storage: Option<S>,
pub(crate) marker: PhantomData<&'s ()>,
}
#[cfg(feature="parallel_iter")]
impl<'s, E, S> ParallelIterator for ParEntitiesComponentOptIter<'s, E, S>
where
E: ParallelIterator<Item = crate::Entity>,
S: StorageRef<'s> + Send + Sync + 's,
S::Component: Send,
{
type Item = Option<S::Component>;
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>
{
if let Some(storage) = self.storage {
self.entities.into_par_iter()
.map(|e| {
if storage.contains(e.guid()){
let storage = &storage as *const S as *mut S;
Some(unsafe{ (*storage).get_unchecked(e.guid()) })
}else{
None
}
})
.drive_unindexed(consumer)
}else{
None.into_par_iter().drive_unindexed(consumer)
}
}
}
#[doc(hidden)]
pub trait EntitiesData {
fn into_entities_iter<'a, E, I>(entities: &'a E, entities_iter: I) -> EntitiesComponentIter<'a, I, <Self as UnorderedData<'a>>::Storage>
where
<Self as UnorderedData<'a>>::Storage: StorageRef<'a>,
E: EntitiesStorage,
I: Iterator<Item = Entity>,
Self: UnorderedData<'a>;
}
impl<U> EntitiesData for U {
fn into_entities_iter<'a, E, I>(entities: &'a E, entities_iter: I) -> EntitiesComponentIter<'a, I, <Self as UnorderedData<'a>>::Storage>
where
<Self as UnorderedData<'a>>::Storage: StorageRef<'a>,
E: EntitiesStorage,
I: Iterator<Item = Entity>,
U: UnorderedData<'a>,
{
EntitiesComponentIter{
entities: entities_iter,
storage: U::storage(entities),
marker: PhantomData,
}
}
}
pub trait ChangesData<'a>: UnorderedData<'a>{
type SubStorage;
fn extend_changes<F>(entities: &'a Entities, f: F)
where F: FnMut(Self::ComponentsRef) -> bool;
unsafe fn storage_and_changes(entities: &'a Entities) -> Option<(Self::SubStorage, &'a mut HashSet<usize>)>;
}
pub trait ChangesDataSend<'a>: ChangesData<'a>{}
impl<'a, U> ChangesDataSend<'a> for U
where
U: ChangesData<'a>,
<U as UnorderedData<'a>>::Components: Send
{}
pub trait ChangesOrderedData<'a>: OrderedData<'a>{
type SubStorage: StorageRef<'a>;
fn extend_changes<F, E: EntitiesStorage>(entities: &'a E, f: F)
where F: FnMut(Self::ComponentsRef) -> bool;
unsafe fn storage_and_changes<E: EntitiesStorage>(entities: &'a E) -> Option<(Self::SubStorage, &'a mut HashSet<usize>)>;
}
pub trait ChangesOrderedDataSend<'a>: ChangesOrderedData<'a>{}
impl<'a, U> ChangesOrderedDataSend<'a> for U
where
U: ChangesOrderedData<'a>,
<U as OrderedData<'a>>::Components: Send
{}
pub trait ChangedData<'a>: UnorderedData<'a>{
type ChangedIter: Iterator<Item = Entity>;
fn changed_iter<E: EntitiesStorage>(entities: &'a E) -> Self::ChangedIter;
}
pub trait ChangedDataSend<'a>: ChangedData<'a>{}
impl<'a, U> ChangedDataSend<'a> for U
where
U: ChangedData<'a>,
<U as UnorderedData<'a>>::Components: Send
{}
pub trait ChangedOrderedData<'a>: OrderedData<'a>{
type ChangedOrderedIter: Iterator<Item = Entity>;
fn changed_ordered_iter<E: EntitiesStorage>(entities: &'a E) -> Self::ChangedOrderedIter;
}
pub trait ChangedOrderedDataSend<'a>: ChangedOrderedData<'a>{}
impl<'a, U> ChangedOrderedDataSend<'a> for U
where
U: ChangedOrderedData<'a>,
<U as OrderedData<'a>>::Components: Send
{}
#[doc(hidden)]
pub struct ChangedIter<'a,G>{
_guard: Option<G>,
iter: Option<hashbrown::hash_set::Iter<'a, usize>>,
}
impl<'a, G> Iterator for ChangedIter<'a, G>{
type Item = Entity;
fn next(&mut self) -> Option<Entity>{
let iter = self.iter.as_mut()?;
iter.next().map(|id| Entity{guid: *id})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.as_ref().map(|it| it.size_hint()).unwrap_or((0, None))
}
}