use crate::ecs::ent::{
component::{Component, ComponentKey, Components},
entity::{ContainEntity, Entity, EntityIndex, EntityName, EntityTag},
storage::EntityContainerRef,
};
use my_utils::{
ds::{
ATypeId, Borrowed, FlatIter, FlatIterMut, Getter, GetterMut, ManagedConstPtr, NonNullExt,
ParFlatIter, ParFlatIterMut, RawGetter, SendSyncPtr,
},
TakeRecur,
};
use rayon::iter::{plumbing::Producer, IntoParallelIterator};
use std::{
any, fmt, iter,
marker::PhantomData,
ops::{Deref, DerefMut},
ptr::NonNull,
sync::Arc,
};
pub trait StoreSelectInfo: StoreFilterInfo {
fn contains(&self, key: &SelectKey) -> bool;
fn get(&self, key: &SelectKey) -> Option<&Arc<SelectInfo>>;
fn insert(&mut self, key: SelectKey, info: Arc<SelectInfo>);
}
pub trait StoreFilterInfo {
fn contains(&self, key: &FilterKey) -> bool;
fn get(&self, key: &FilterKey) -> Option<&Arc<FilterInfo>>;
fn insert(&mut self, key: FilterKey, info: Arc<FilterInfo>);
}
pub trait Select: 'static {
type Target: Component;
type Filter: Filter;
#[doc(hidden)]
fn key() -> SelectKey {
SelectKey::of::<Self>()
}
#[doc(hidden)]
fn get_info_from<S>(stor: &mut S) -> &Arc<SelectInfo>
where
S: StoreSelectInfo + StoreFilterInfo + ?Sized,
{
let key = Self::key();
if !StoreSelectInfo::contains(stor, &key) {
let sinfo = Arc::new(Self::info_from(stor));
StoreSelectInfo::insert(stor, key, sinfo);
}
unsafe { StoreSelectInfo::get(stor, &key).unwrap_unchecked() }
}
#[doc(hidden)]
fn info_from<S>(stor: &mut S) -> SelectInfo
where
S: StoreFilterInfo + ?Sized,
{
let target = ComponentKey::of::<Self::Target>();
let finfo = Arc::clone(Self::Filter::get_info_from(stor));
let name = any::type_name::<Self>();
SelectInfo::new(target, finfo, name)
}
}
pub trait Filter: 'static {
type All: Components;
type Any: Components;
type None: Components;
type Exact: Components;
#[doc(hidden)]
fn key() -> FilterKey {
FilterKey::of::<Self>()
}
#[doc(hidden)]
fn all_any_none() -> [Box<[ComponentKey]>; 3] {
let all: Box<[ComponentKey]> = Self::All::keys().as_ref().into();
let any: Box<[ComponentKey]> = Self::Any::keys().as_ref().into();
let none: Box<[ComponentKey]> = Self::None::keys().as_ref().into();
[all, any, none]
}
#[doc(hidden)]
fn get_info_from<S>(stor: &mut S) -> &Arc<FilterInfo>
where
S: StoreFilterInfo + ?Sized,
{
let key = Self::key();
if !stor.contains(&key) {
let sinfo = Arc::new(Self::info());
stor.insert(key, sinfo);
}
unsafe { stor.get(&key).unwrap_unchecked() }
}
#[doc(hidden)]
fn info() -> FilterInfo {
let [all, any, none] = Self::all_any_none();
let exact = Self::Exact::keys().as_ref().into();
let name = any::type_name::<Self>();
FilterInfo::new(all, any, none, exact, name)
}
}
impl<T: Entity> Filter for T {
type All = ();
type Any = ();
type None = ();
type Exact = T;
}
pub type SelectKey = ATypeId<SelectKey_>;
pub struct SelectKey_;
pub type FilterKey = ATypeId<FilterKey_>;
pub struct FilterKey_;
#[derive(Clone)]
pub struct SelectInfo {
target: ComponentKey,
finfo: Arc<FilterInfo>,
name: &'static str,
}
impl fmt::Debug for SelectInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SelectInfo")
.field("name", &self.name())
.field("target", &self.target())
.field("finfo", &self.filter_info())
.finish()
}
}
impl SelectInfo {
const fn new(target: ComponentKey, finfo: Arc<FilterInfo>, name: &'static str) -> Self {
Self {
target,
finfo,
name,
}
}
pub(crate) const fn target(&self) -> &ComponentKey {
&self.target
}
pub(crate) const fn filter_info(&self) -> &Arc<FilterInfo> {
&self.finfo
}
pub(crate) const fn name(&self) -> &'static str {
self.name
}
pub(crate) fn filter<F>(&self, contains: F, num_columns: usize) -> bool
where
F: Fn(&ComponentKey) -> bool,
{
contains(self.target()) && self.finfo.filter(contains, num_columns)
}
pub(crate) fn is_disjoint(&self, rhs: &Self) -> bool {
(self.target != rhs.target) || self.finfo.is_disjoint(&rhs.finfo)
}
pub(crate) fn is_disjoint2(&self, rhs: &FilterInfo) -> bool {
self.finfo.is_disjoint(rhs)
}
}
#[derive(Clone)]
pub struct FilterInfo {
all: Box<[ComponentKey]>,
any: Box<[ComponentKey]>,
none: Box<[ComponentKey]>,
exact: Box<[ComponentKey]>,
name: &'static str,
}
impl fmt::Debug for FilterInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FilterInfo")
.field("name", &self.name())
.field("all", &self.all())
.field("any", &self.any())
.field("none", &self.none())
.field("exact", &self.exact())
.finish()
}
}
impl FilterInfo {
const fn new(
all: Box<[ComponentKey]>,
any: Box<[ComponentKey]>,
none: Box<[ComponentKey]>,
exact: Box<[ComponentKey]>,
name: &'static str,
) -> Self {
Self {
all,
any,
none,
exact,
name,
}
}
pub(crate) const fn all(&self) -> &[ComponentKey] {
&self.all
}
pub(crate) const fn any(&self) -> &[ComponentKey] {
&self.any
}
pub(crate) const fn none(&self) -> &[ComponentKey] {
&self.none
}
pub(crate) const fn exact(&self) -> &[ComponentKey] {
&self.exact
}
pub(crate) const fn name(&self) -> &'static str {
self.name
}
pub(crate) fn filter<F>(&self, contains: F, num_columns: usize) -> bool
where
F: Fn(&ComponentKey) -> bool,
{
if !self.exact.is_empty() {
self.exact.len() == num_columns && self.exact.iter().all(&contains)
} else {
self.all.iter().all(&contains)
&& !self.none.iter().any(&contains)
&& if self.any.is_empty() {
true
} else {
self.any.iter().any(contains)
}
}
}
pub(crate) fn is_disjoint(&self, rhs: &Self) -> bool {
let is_self_general = self.exact.is_empty();
let is_rhs_general = rhs.exact.is_empty();
match (is_self_general, is_rhs_general) {
(false, false) => self.is_disjoint_exact_exact(rhs),
(false, true) => rhs.is_disjoint_general_exact(self),
(true, false) => self.is_disjoint_general_exact(rhs),
(true, true) => self.is_disjoint_general_general(rhs),
}
}
fn is_disjoint_general_general(&self, rhs: &Self) -> bool {
let (a_all, a_any, a_none) = (&self.all, &self.any, &self.none);
let (b_all, b_any, b_none) = (&rhs.all, &rhs.any, &rhs.none);
if a_all.iter().any(|a| b_none.contains(a)) {
return true;
}
if a_none.iter().any(|a| b_all.contains(a)) {
return true;
}
if !b_any.is_empty() && b_any.iter().all(|b| a_none.contains(b)) {
return true;
}
if !a_any.is_empty() && a_any.iter().all(|a| b_none.contains(a)) {
return true;
}
false
}
fn is_disjoint_exact_exact(&self, rhs: &Self) -> bool {
if self.exact.len() != rhs.exact.len() {
return false;
}
self.exact.iter().any(|l| !rhs.exact.contains(l))
}
fn is_disjoint_general_exact(&self, rhs: &Self) -> bool {
let (a_all, a_any, a_none) = (&self.all, &self.any, &self.none);
let b_exact = &rhs.exact;
if b_exact.iter().any(|b| !a_all.contains(b)) {
return true;
}
if b_exact.iter().any(|b| a_none.contains(b)) {
return true;
}
if a_any.iter().all(|a| !b_exact.contains(a)) {
return true;
}
false
}
}
#[derive(Debug)]
pub struct Selected<'cont, Comp: 'cont> {
raw: &'cont mut SelectedRaw,
_marker: PhantomData<Comp>,
}
impl<'cont, Comp: 'cont> Selected<'cont, Comp> {
pub(crate) fn new(raw: &'cont mut SelectedRaw) -> Self {
Self {
raw,
_marker: PhantomData,
}
}
pub fn iter(&self) -> SelectedIter<'cont, Comp> {
SelectedIter::new(self)
}
pub fn par_iter(&self) -> ParSelectedIter<'cont, Comp> {
ParSelectedIter(self.iter())
}
pub(crate) fn as_raw(&self) -> &SelectedRaw {
self.raw
}
}
#[derive(Debug)]
#[repr(transparent)]
pub struct SelectedMut<'cont, Comp>(Selected<'cont, Comp>);
impl<'cont, Comp: 'cont> SelectedMut<'cont, Comp> {
pub(crate) fn new(filtered: &'cont mut SelectedRaw) -> Self {
Self(Selected::new(filtered))
}
pub fn iter(&self) -> SelectedIter<'cont, Comp> {
self.0.iter()
}
pub fn iter_mut(&mut self) -> SelectedIterMut<'cont, Comp> {
SelectedIterMut(self.iter())
}
pub fn par_iter(&self) -> ParSelectedIter<'cont, Comp> {
self.0.par_iter()
}
pub fn par_iter_mut(&mut self) -> ParSelectedIterMut<'cont, Comp> {
ParSelectedIterMut(self.iter_mut())
}
}
#[derive(Debug)]
pub struct FilteredMut<'stor, T: 'stor> {
raw: &'stor mut FilteredRaw,
_marker: PhantomData<T>,
}
impl<'stor, T: 'stor> FilteredMut<'stor, T> {
pub(crate) fn new(raw: &'stor mut FilteredRaw) -> Self {
Self {
raw,
_marker: PhantomData,
}
}
pub fn iter_mut(&mut self) -> FilteredIterMut<'stor, T> {
FilteredIterMut::new(self)
}
pub(crate) fn as_mut_raw(&mut self) -> &mut FilteredRaw {
self.raw
}
}
impl<'stor, T: Entity + 'stor> TakeRecur for FilteredMut<'stor, T> {
type Inner = EntityContainerRef<'stor, T>;
fn take_recur(mut self) -> Self::Inner {
if let Some(cont) = self.iter_mut().next() {
cont
} else {
panic!("have you registered `{}`?", any::type_name::<T>());
}
}
}
#[derive(Debug)]
pub struct SelectedRaw {
etags: Vec<Arc<EntityTag>>,
col_idxs: Vec<usize>,
query_res: Vec<Borrowed<RawGetter>>,
}
impl SelectedRaw {
pub(crate) const fn new(etags: Vec<Arc<EntityTag>>, col_idxs: Vec<usize>) -> Self {
Self {
etags,
col_idxs,
query_res: Vec::new(),
}
}
pub(crate) fn take(
&mut self,
) -> (
&Vec<Arc<EntityTag>>,
&Vec<usize>,
&mut Vec<Borrowed<RawGetter>>,
) {
(&self.etags, &self.col_idxs, &mut self.query_res)
}
pub(crate) fn add(&mut self, etag: Arc<EntityTag>, ci: usize) {
self.etags.push(etag);
self.col_idxs.push(ci);
}
pub(crate) fn remove(&mut self, ei: EntityIndex, ci: usize) -> Option<Arc<EntityTag>> {
let ei_iter = self.etags.iter().map(|etag| etag.index());
let ei_ci_iter = ei_iter.zip(&self.col_idxs);
if let Some((i, _)) = ei_ci_iter
.enumerate()
.find(|(_, (item_ei, item_ci))| *item_ei == ei && **item_ci == ci)
{
let old = self.etags.swap_remove(i);
self.col_idxs.swap_remove(i);
Some(old)
} else {
None
}
}
pub(crate) fn iter_index_pair<'a>(
etags: &'a [Arc<EntityTag>],
col_idxs: &'a [usize],
) -> impl Iterator<Item = (EntityIndex, usize)> + 'a {
etags
.iter()
.map(|etag| etag.index())
.zip(col_idxs.iter().cloned())
}
pub(crate) fn clear(&mut self) {
self.query_res.clear();
}
pub(crate) const fn query_res(&self) -> &Vec<Borrowed<RawGetter>> {
&self.query_res
}
const fn entity_tags(&self) -> &Vec<Arc<EntityTag>> {
&self.etags
}
}
#[derive(Debug)]
pub struct FilteredRaw {
pub(crate) etags: Vec<Arc<EntityTag>>,
pub(crate) query_res: Vec<Borrowed<NonNull<dyn ContainEntity>>>,
}
impl FilteredRaw {
pub(crate) const fn new(etags: Vec<Arc<EntityTag>>) -> Self {
Self {
etags,
query_res: Vec::new(),
}
}
#[allow(clippy::type_complexity)]
pub(crate) fn take(
&mut self,
) -> (
&Vec<Arc<EntityTag>>,
&mut Vec<Borrowed<NonNull<dyn ContainEntity>>>,
) {
(&self.etags, &mut self.query_res)
}
pub(crate) fn add(&mut self, etag: Arc<EntityTag>) {
self.etags.push(etag);
}
pub(crate) fn remove(&mut self, ei: &EntityIndex) -> Option<Arc<EntityTag>> {
if let Some((i, _)) = self
.etags
.iter()
.enumerate()
.find(|(_, x)| &x.index() == ei)
{
let old = self.etags.swap_remove(i);
Some(old)
} else {
None
}
}
pub(crate) fn clear(&mut self) {
self.query_res.clear();
}
}
#[derive(Debug, Clone)]
pub struct SelectedIter<'cont, Comp: 'cont> {
getter_left: SendSyncPtr<Borrowed<RawGetter>>,
getter_right: SendSyncPtr<Borrowed<RawGetter>>,
etag_left: SendSyncPtr<Arc<EntityTag>>,
etag_right: SendSyncPtr<Arc<EntityTag>>,
_marker: PhantomData<&'cont Comp>,
}
impl<'cont, Comp: 'cont> SelectedIter<'cont, Comp> {
fn new(raw: &Selected<'cont, Comp>) -> Self {
unsafe {
let getter_range = raw.as_raw().query_res().as_ptr_range();
let getter_left = NonNull::new_unchecked(getter_range.start.cast_mut());
let getter_right = NonNull::new_unchecked(getter_range.end.cast_mut());
let etag_range = raw.as_raw().entity_tags().as_ptr_range();
let etag_left = NonNull::new_unchecked(etag_range.start.cast_mut());
let etag_right = NonNull::new_unchecked(etag_range.end.cast_mut());
Self {
getter_left: SendSyncPtr::new(getter_left),
getter_right: SendSyncPtr::new(getter_right),
etag_left: SendSyncPtr::new(etag_left),
etag_right: SendSyncPtr::new(etag_right),
_marker: PhantomData,
}
}
}
#[inline]
pub const fn len(&self) -> usize {
let left = self.getter_left.as_ptr();
let right = self.getter_right.as_ptr();
unsafe { right.offset_from(left) as usize }
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
fn split_at(self, index: usize) -> (Self, Self) {
let l_getter_left = self.getter_left;
let l_getter_right = unsafe { self.getter_left.add(index) };
let r_getter_left = l_getter_right;
let r_getter_right = self.getter_right;
let l_etag_left = self.etag_left;
let l_etag_right = unsafe { self.etag_left.add(index) };
let r_etag_left = l_etag_right;
let r_etag_right = self.etag_right;
let l = SelectedIter {
getter_left: l_getter_left,
getter_right: l_getter_right,
etag_left: l_etag_left,
etag_right: l_etag_right,
_marker: PhantomData,
};
let r = SelectedIter {
getter_left: r_getter_left,
getter_right: r_getter_right,
etag_left: r_etag_left,
etag_right: r_etag_right,
_marker: PhantomData,
};
(l, r)
}
unsafe fn create_item(
getter: SendSyncPtr<Borrowed<RawGetter>>,
etag: SendSyncPtr<Arc<EntityTag>>,
) -> TaggedGetter<'cont, Comp> {
let getter = unsafe {
let raw = **getter.as_ref();
Getter::from_raw(raw)
};
let etag = unsafe {
let etag = Arc::as_ptr(etag.as_ref()).cast_mut();
let etag = NonNullExt::new(etag).unwrap_unchecked();
ManagedConstPtr::new(etag)
};
TaggedGetter { getter, etag }
}
}
impl<'cont, Comp: 'cont> Iterator for SelectedIter<'cont, Comp> {
type Item = TaggedGetter<'cont, Comp>;
fn next(&mut self) -> Option<Self::Item> {
if self.getter_left < self.getter_right {
let getter = self.getter_left;
let etag = self.etag_left;
unsafe {
self.getter_left = self.getter_left.add(1);
self.etag_left = self.etag_left.add(1);
Some(Self::create_item(getter, etag))
}
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = Self::len(self);
(len, Some(len))
}
}
impl<'cont, Comp: 'cont> iter::FusedIterator for SelectedIter<'cont, Comp> {}
impl<'cont, Comp: 'cont> ExactSizeIterator for SelectedIter<'cont, Comp> {
fn len(&self) -> usize {
Self::len(self)
}
}
impl<'cont, Comp: 'cont> DoubleEndedIterator for SelectedIter<'cont, Comp> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.getter_left < self.getter_right {
unsafe {
self.getter_right = self.getter_right.sub(1);
self.etag_right = self.etag_right.sub(1);
Some(Self::create_item(self.getter_right, self.etag_right))
}
} else {
None
}
}
}
#[derive(Debug, Clone)]
#[repr(transparent)]
pub struct ParSelectedIter<'cont, Comp>(pub SelectedIter<'cont, Comp>);
impl<'cont, Comp: 'cont> ParSelectedIter<'cont, Comp> {
#[inline]
pub const fn into_seq(self) -> SelectedIter<'cont, Comp> {
self.0
}
#[inline]
pub const fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl<'cont, Comp: Send + Sync + 'cont> Producer for ParSelectedIter<'cont, Comp> {
type Item = TaggedGetter<'cont, Comp>;
type IntoIter = SelectedIter<'cont, Comp>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.into_seq()
}
#[inline]
fn split_at(self, index: usize) -> (Self, Self) {
let (l, r) = SelectedIter::split_at(self.0, index);
(ParSelectedIter(l), ParSelectedIter(r))
}
}
my_utils::impl_into_iterator_for_parallel!(
"lifetimes" = 'cont; "bounds" = Comp: {'cont};
"for" = ParSelectedIter; "to" = SelectedIter<'cont, Comp>;
"item" = TaggedGetter<'cont, Comp>;
);
my_utils::impl_parallel_iterator!(
"lifetimes" = 'cont; "bounds" = Comp: {Send + Sync + 'cont};
"for" = ParSelectedIter; "item" = TaggedGetter<'cont, Comp>;
);
my_utils::impl_unindexed_producer!(
"lifetimes" = 'cont; "bounds" = Comp: {Send + Sync + 'cont};
"for" = ParSelectedIter; "item" = TaggedGetter<'cont, Comp>;
);
#[derive(Debug)]
#[repr(transparent)]
pub struct SelectedIterMut<'cont, Comp>(pub SelectedIter<'cont, Comp>);
impl<'cont, Comp: 'cont> SelectedIterMut<'cont, Comp> {
#[inline]
pub const fn into_seq(self) -> SelectedIter<'cont, Comp> {
self.0
}
#[inline]
pub const fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
fn split_at(self, index: usize) -> (Self, Self) {
let (l, r) = SelectedIter::split_at(self.0, index);
(Self(l), Self(r))
}
}
impl<'cont, Comp> Iterator for SelectedIterMut<'cont, Comp> {
type Item = TaggedGetterMut<'cont, Comp>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|TaggedGetter { getter, etag }| {
TaggedGetterMut {
getter: unsafe { GetterMut::from_raw(getter.into_raw()) },
etag,
}
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl<'cont, Comp: 'cont> iter::FusedIterator for SelectedIterMut<'cont, Comp> {}
impl<'cont, Comp: 'cont> ExactSizeIterator for SelectedIterMut<'cont, Comp> {
fn len(&self) -> usize {
Self::len(self)
}
}
impl<'cont, Comp: 'cont> DoubleEndedIterator for SelectedIterMut<'cont, Comp> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|TaggedGetter { getter, etag }| {
TaggedGetterMut {
getter: unsafe { GetterMut::from_raw(getter.into_raw()) },
etag,
}
})
}
}
#[derive(Debug)]
#[repr(transparent)]
pub struct ParSelectedIterMut<'cont, Comp>(pub SelectedIterMut<'cont, Comp>);
impl<'cont, Comp: 'cont> ParSelectedIterMut<'cont, Comp> {
#[inline]
pub const fn into_seq(self) -> SelectedIterMut<'cont, Comp> {
self.0
}
#[inline]
pub const fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl<'cont, Comp: Send + Sync> Producer for ParSelectedIterMut<'cont, Comp> {
type Item = TaggedGetterMut<'cont, Comp>;
type IntoIter = SelectedIterMut<'cont, Comp>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.into_seq()
}
#[inline]
fn split_at(self, index: usize) -> (Self, Self) {
let (l, r) = SelectedIterMut::split_at(self.0, index);
(ParSelectedIterMut(l), ParSelectedIterMut(r))
}
}
my_utils::impl_into_iterator_for_parallel!(
"lifetimes" = 'cont; "bounds" = Comp: {'cont};
"for" = ParSelectedIterMut; "to" = SelectedIterMut<'cont, Comp>;
"item" = TaggedGetterMut<'cont, Comp>;
);
my_utils::impl_parallel_iterator!(
"lifetimes" = 'cont; "bounds" = Comp: {Send + Sync + 'cont};
"for" = ParSelectedIterMut; "item" = TaggedGetterMut<'cont, Comp>;
);
my_utils::impl_unindexed_producer!(
"lifetimes" = 'cont; "bounds" = Comp: {Send + Sync + 'cont};
"for" = ParSelectedIterMut; "item" = TaggedGetterMut<'cont, Comp>;
);
#[derive(Debug)]
pub struct FilteredIterMut<'stor, T: 'stor> {
cont_left: NonNull<Borrowed<NonNull<dyn ContainEntity>>>,
cont_right: NonNull<Borrowed<NonNull<dyn ContainEntity>>>,
etag_left: NonNull<Arc<EntityTag>>,
etag_right: NonNull<Arc<EntityTag>>,
_marker: PhantomData<&'stor mut T>,
}
impl<'stor, T: 'stor> FilteredIterMut<'stor, T> {
fn new(raw: &mut FilteredMut<'stor, T>) -> Self {
unsafe {
let cont_range = raw.as_mut_raw().query_res.as_mut_ptr_range();
let cont_left = NonNull::new_unchecked(cont_range.start);
let cont_right = NonNull::new_unchecked(cont_range.end);
let etag_range = raw.as_mut_raw().etags.as_mut_ptr_range();
let etag_left = NonNull::new_unchecked(etag_range.start);
let etag_right = NonNull::new_unchecked(etag_range.end);
Self {
cont_left,
cont_right,
etag_left,
etag_right,
_marker: PhantomData,
}
}
}
#[inline]
pub const fn len(&self) -> usize {
let left = self.cont_left.as_ptr();
let right = self.cont_right.as_ptr();
unsafe { right.offset_from(left) as usize }
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
unsafe fn create_item(
mut cont: NonNull<Borrowed<NonNull<dyn ContainEntity>>>,
etag: NonNull<Arc<EntityTag>>,
) -> EntityContainerRef<'stor, T> {
let etag = unsafe { etag.as_ref() };
let etag = &**etag;
let cont = unsafe { cont.as_mut().as_mut() };
EntityContainerRef::new(etag, cont)
}
}
impl<'stor, T: 'stor> Iterator for FilteredIterMut<'stor, T> {
type Item = EntityContainerRef<'stor, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.cont_left < self.cont_right {
let getter = self.cont_left;
let etag = self.etag_left;
unsafe {
let ptr = self.cont_left.as_ptr().add(1);
self.cont_left = NonNull::new_unchecked(ptr);
let ptr = self.etag_left.as_ptr().add(1);
self.etag_left = NonNull::new_unchecked(ptr);
Some(Self::create_item(getter, etag))
}
} else {
None
}
}
}
impl<'stor, T: 'stor> iter::FusedIterator for FilteredIterMut<'stor, T> {}
impl<'stor, T: 'stor> ExactSizeIterator for FilteredIterMut<'stor, T> {
fn len(&self) -> usize {
Self::len(self)
}
}
impl<'stor, T: 'stor> DoubleEndedIterator for FilteredIterMut<'stor, T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.cont_left < self.cont_right {
unsafe {
let ptr = self.cont_right.as_ptr().sub(1);
self.cont_right = NonNull::new_unchecked(ptr);
let ptr = self.etag_right.as_ptr().sub(1);
self.etag_right = NonNull::new_unchecked(ptr);
Some(Self::create_item(self.cont_right, self.etag_right))
}
} else {
None
}
}
}
#[derive(Debug)]
pub struct TaggedGetter<'cont, Comp: 'cont> {
getter: Getter<'cont, Comp>,
etag: ManagedConstPtr<EntityTag>,
}
impl<Comp> TaggedGetter<'_, Comp> {
pub fn entity_index(&self) -> EntityIndex {
self.etag.index()
}
pub fn entity_name(&self) -> Option<&EntityName> {
self.etag.get_name()
}
pub fn component_names(&self) -> &[&'static str] {
self.etag.get_component_names()
}
}
impl<'cont, Comp> Deref for TaggedGetter<'cont, Comp> {
type Target = Getter<'cont, Comp>;
fn deref(&self) -> &Self::Target {
&self.getter
}
}
impl<'cont, Comp> IntoIterator for TaggedGetter<'cont, Comp> {
type Item = &'cont Comp;
type IntoIter = FlatIter<'cont, Comp>;
fn into_iter(self) -> Self::IntoIter {
self.getter.into_iter()
}
}
impl<'cont, Comp: Send + Sync> IntoParallelIterator for TaggedGetter<'cont, Comp> {
type Iter = ParFlatIter<'cont, Comp>;
type Item = &'cont Comp;
fn into_par_iter(self) -> Self::Iter {
self.getter.into_par_iter()
}
}
#[derive(Debug)]
pub struct TaggedGetterMut<'cont, Comp: 'cont> {
getter: GetterMut<'cont, Comp>,
etag: ManagedConstPtr<EntityTag>,
}
impl<Comp> TaggedGetterMut<'_, Comp> {
pub fn entity_index(&self) -> EntityIndex {
self.etag.index()
}
pub fn entity_name(&self) -> Option<&EntityName> {
self.etag.get_name()
}
pub fn component_names(&self) -> &[&'static str] {
self.etag.get_component_names()
}
}
impl<'cont, Comp> Deref for TaggedGetterMut<'cont, Comp> {
type Target = GetterMut<'cont, Comp>;
fn deref(&self) -> &Self::Target {
&self.getter
}
}
impl<Comp> DerefMut for TaggedGetterMut<'_, Comp> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.getter
}
}
impl<'cont, Comp> IntoIterator for TaggedGetterMut<'cont, Comp> {
type Item = &'cont mut Comp;
type IntoIter = FlatIterMut<'cont, Comp>;
fn into_iter(self) -> Self::IntoIter {
self.getter.into_iter()
}
}
impl<'cont, Comp: Send + Sync> IntoParallelIterator for TaggedGetterMut<'cont, Comp> {
type Iter = ParFlatIterMut<'cont, Comp>;
type Item = &'cont mut Comp;
fn into_par_iter(self) -> Self::Iter {
self.getter.into_par_iter()
}
}
#[cfg(test)]
mod tests {
#[test]
#[rustfmt::skip]
fn test_my_ecs_macros_filter() {
use crate as my_ecs;
use crate::prelude::*;
use crate::ecs::{
sys::select::Select,
ent::component::ComponentKey,
};
#[derive(Component)] struct Ca;
#[derive(Component)] struct Cb;
#[derive(Component)] struct Cc;
#[derive(Component)] struct Cd;
#[derive(Component)] struct Ce;
#[derive(Component)] struct Cf;
filter!(F0, Target = Ca);
let [all, any, none] = F0::all_any_none();
assert_eq!(<F0 as Select>::Target::key(), Ca::key());
assert!(all.is_empty());
assert!(any.is_empty());
assert!(none.is_empty());
filter!(F1, All = Ca);
let [all, any, none] = F1::all_any_none();
validate_slice(&all, &[Ca::key()]);
assert!(any.is_empty());
assert!(none.is_empty());
filter!(F2, Any = Ca);
let [all, any, none] = F2::all_any_none();
assert!(all.is_empty());
validate_slice(&any, &[Ca::key()]);
assert!(none.is_empty());
filter!(F3, None = Ca);
let [all, any, none] = F3::all_any_none();
assert!(all.is_empty());
assert!(any.is_empty());
validate_slice(&none, &[Ca::key()]);
filter!(F4, All = (Ca, Cb), Any = (Cc, Cd), None = (Ce, Cf));
let [all, any, none] = F4::all_any_none();
validate_slice(&all, &[Ca::key(), Cb::key()]);
validate_slice(&any, &[Cc::key(), Cd::key()]);
validate_slice(&none, &[Ce::key(), Cf::key()]);
filter!(F5, Target = Ca, All = Cb, Any = Cc, None = Cd);
let [all, any, none] = F5::all_any_none();
assert_eq!(<F5 as Select>::Target::key(), Ca::key());
validate_slice(&all, &[Cb::key()]);
validate_slice(&any, &[Cc::key()]);
validate_slice(&none, &[Cd::key()]);
fn validate_slice(a: &[ComponentKey], b: &[ComponentKey]) {
assert_eq!(a.len(), b.len());
for (va, vb) in a.iter().zip(b) {
assert_eq!(va, vb);
}
}
}
}