use std::marker;
pub struct HasOr<T>{
_marker: marker::PhantomData<T>,
}
pub trait Bools {
type B;
}
impl<C> Bools for C {
type B = bool;
}
macro_rules! impl_or_iter {
($intoiter_or: ident, $iter_or: ident, $storage_or: ident, $($t: ident, $s: ident),*) => (
impl<$($t),*> FromComponent<'_, ($(<$t as super::Bools>::B),*)> for HasOr<($($t),*)> {
fn from_component(_: ($(<$t as super::Bools>::B),*)) -> HasOr<($($t),*)>{
HasOr{
_marker: marker::PhantomData
}
}
}
pub struct $intoiter_or<'a, $($t),*> {
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
storage: $storage_or<'a, $($t),*, LazyIndexGuard<'a>>,
}
impl<'a, $($t: 'static),*> Iterator for $intoiter_or<'a, $($t),*> {
type Item = ($(<$t as super::Bools>::B),*);
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);
Some(self.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<'a, $($t: 'static),*> ExactSizeIterator for $intoiter_or<'a, $($t),*> {
#[inline]
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
pub struct $iter_or<'a, 'r, $($t),*> {
ptr: *const HiddenFastIndex,
end: *const HiddenFastIndex,
storage: Option<$storage_or<'a, $($t),*, &'r [HiddenFastIndex]>>,
}
impl<'a, 's, $($t: 'static),*> Iterator for $iter_or<'a, 's, $($t),*> {
type Item = ($(<$t as super::Bools>::B),*);
fn next(&mut self) -> Option<Self::Item>{
unsafe {
if self.ptr == self.end {
None
} else {
let storage = self.storage.as_mut().unchecked_unwrap();
let ids = &*self.ptr;
let ids = ids.unchecked_downcast_ref();
self.ptr = self.ptr.offset(1);
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<'a, 's, $($t: 'static),*> ExactSizeIterator for $iter_or<'a, 's, $($t),*> {
#[inline]
fn len(&self) -> usize {
self.end as usize - self.ptr as usize
}
}
#[allow(non_snake_case, dead_code)]
pub struct $storage_or<'a, $($t),*, I> {
ids: I,
entities_masks: &'a [(Entity, MaskType)],
$(
$s: MaskType,
$t: marker::PhantomData<$t>,
)*
}
impl<'a, 'r, I, $($t: 'static),*> FastIndexExt for $storage_or<'a, $($t),*, I> {
type FastIndex = ($(<$t as super::Bools>::B),*);
type StaticTypeId = ($($t),*);
fn fast_index(&self, guid: usize) -> ($(<$t as super::Bools>::B),*) {
let entity_mask = self.entities_masks[guid].1.clone();
($(entity_mask.clone() & self.$s.clone() != MaskType::zero()),*)
}
}
unsafe impl<'a, 'r, I, $($t),*> ReadOnlyStorage for $storage_or<'a, $($t),*, I>{}
impl<'a, 'r, I, $($t: 'static),*> StorageRef<'r> for $storage_or<'a, $($t),*, I> {
type Data = HasOr<($($t),*)>;
type Component = ($(<$t as super::Bools>::B),*);
unsafe fn get_fast_unchecked(&'r mut self, idx: ($(<$t as super::Bools>::B),*)) -> ($(<$t as super::Bools>::B),*){
idx
}
#[allow(non_snake_case)]
unsafe fn get_unchecked(&'r mut self, guid: usize) -> ($(<$t as super::Bools>::B),*){
let entity_mask = self.entities_masks[guid].1.clone();
($(entity_mask.clone() & self.$s.clone() != MaskType::zero()),*)
}
fn contains(&self, guid: usize) -> bool{
let entity_mask = &self.entities_masks[guid].1;
$(entity_mask & &self.$s != MaskType::zero()) ||*
}
}
impl<'a, 'r, $($t: 'static,)* I> IntoSendStorage<'r> for $storage_or<'a, $($t),*, I>
where I: Indices
{
type SendStorage = $storage_or<'a, $($t),*, &'r [HiddenFastIndex]>;
fn into_send_storage(&'r mut self) -> Self::SendStorage {
$storage_or {
ids: self.ids.index(self),
entities_masks: self.entities_masks,
$(
$s: self.$s.clone(),
$t: marker::PhantomData,
)*
}
}
}
impl<'a, 'r, $($t: 'static,)* I> OptionStorage<'r> for $storage_or<'a, $($t),*, I>
where I: Indices
{
type Iter = $iter_or<'a, 'r, $($t),*>;
fn iter(this: Option<&'r Self>) -> Self::Iter {
let ptr_range = this
.map(|this| this.ids.as_ptr_range(this))
.unwrap_or(ptr::null() .. ptr::null());
$iter_or{
ptr: ptr_range.start,
end: ptr_range.end,
storage: this.map(|this| $storage_or {
ids: this.ids.index(this),
entities_masks: this.entities_masks,
$(
$s: this.$s.clone(),
$t: marker::PhantomData,
)*
})
}
}
}
unsafe impl<$($t),*> SafeIter<'_> for HasOr<($($t),*)> {}
impl<'a, $($t: 'static),*> UnorderedData<'a> for HasOr<($($t),*)> {
type Iter = $intoiter_or<'a, $($t),*>;
type IterMut = $intoiter_or<'a, $($t),*>;
type Components = ($($t,)*);
type ComponentsRef = ($(<$t as super::Bools>::B),*);
type Storage = $storage_or<'a, $($t),*, LazyIndexGuard<'a>>;
fn query_mask<E: EntitiesStorage>(entities: &E) -> Bitmask {
Bitmask::or($(entities.component_mask::<$t>()) | *)
}
fn into_iter<E: EntitiesStorage>(entities: &'a E) -> Self::Iter {
let storage = <Self as UnorderedData>::storage(entities).unwrap();
$intoiter_or{
ptr: storage.ids.index(&storage).as_ptr(),
end: unsafe{ storage.ids.index(&storage).as_ptr().add(storage.ids.index(&storage).len()) },
storage: storage,
}
}
fn into_iter_mut<E: EntitiesStorage>(entities: &'a E) -> Self::Iter {
Self::into_iter(entities)
}
#[allow(non_snake_case)]
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_masks = entities.entities_ref();
let ($($s),*) = ($(entities.component_mask::<$t>(),)*);
Some($storage_or {
ids,
entities_masks,
$(
$t: marker::PhantomData,
$s,
)*
})
}
}
impl<$($t),*> DataAccesses for HasOr<($($t),*)> {
fn reads() -> Vec<TypeId>{ vec![] }
fn writes() -> Vec<TypeId>{ vec![] }
}
)}
mod or_storage{
use std::marker;
use crate::storage::{StorageRef, FastIndexExt, IntoSendStorage, HiddenFastIndex, ReadOnlyStorage};
use crate::operators::{UnorderedData, DataAccesses, SafeIter, FromComponent, OptionStorage};
use crate::entity::{Entity, EntitiesStorage};
use crate::bitmask::{MaskType, Bitmask};
use super::HasOr;
use crate::sync::{LazyIndexGuard, Indices};
use unchecked_unwrap::UncheckedUnwrap;
use std::any::TypeId;
use std::ptr;
#[cfg(components_64)]
use num_traits::Zero;
#[cfg(any(feature="storage_macros_2", feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_or_iter!(IntoIter2, Iter2, StorageRef2, T1, S1, T2, S2);
#[cfg(any(feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_or_iter!(IntoIter3, Iter3, StorageRef3, T1, S1, T2, S2, T3, S3);
#[cfg(any(feature="storage_macros_4", feature="storage_macros_8", feature="storage_macros_16"))]
impl_or_iter!(IntoIter4, Iter4, StorageRef4, T1, S1, T2, S2, T3, S3, T4, S4);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_or_iter!(IntoIter5, Iter5, StorageRef5, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_or_iter!(IntoIter6, Iter6, StorageRef6, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_or_iter!(IntoIter7, Iter7, StorageRef7, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7);
#[cfg(any(feature="storage_macros_8", feature="storage_macros_16"))]
impl_or_iter!(IntoIter8, Iter8, StorageRef8, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8);
#[cfg(any(feature="storage_macros_16"))]
impl_or_iter!(IntoIter9, Iter9, StorageRef9, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8, T9, S9);
#[cfg(any(feature="storage_macros_16"))]
impl_or_iter!(IntoIter10, Iter10, StorageRef10, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8, T9, S9, T10, S10);
#[cfg(any(feature="storage_macros_16"))]
impl_or_iter!(IntoIter11, Iter11, StorageRef11, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8, T9, S9, T10, S10, T11, S11);
#[cfg(any(feature="storage_macros_16"))]
impl_or_iter!(IntoIter12, Iter12, StorageRef12, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8, T9, S9, T10, S10, T11, S11, T12, S12);
#[cfg(any(feature="storage_macros_16"))]
impl_or_iter!(IntoIter13, Iter13, StorageRef13, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8, T9, S9, T10, S10, T11, S11, T12, S12, T13, S13);
#[cfg(any(feature="storage_macros_16"))]
impl_or_iter!(IntoIter14, Iter14, StorageRef14, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8, T9, S9, T10, S10, T11, S11, T12, S12, T13, S13, T14, S14);
#[cfg(any(feature="storage_macros_16"))]
impl_or_iter!(IntoIter15, Iter15, StorageRef15, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8, T9, S9, T10, S10, T11, S11, T12, S12, T13, S13, T14, S14, T15, S15);
#[cfg(any(feature="storage_macros_16"))]
impl_or_iter!(IntoIter16, Iter16, StorageRef16, T1, S1, T2, S2, T3, S3, T4, S4, T5, S5, T6, S6, T7, S7, T8, S8, T9, S9, T10, S10, T11, S11, T12, S12, T13, S13, T14, S14, T15, S15, T16, S16);
}