use crate::{
archetype,
component::Component,
entity,
hlist::{
Get,
Reshape,
},
query::{
view,
view::{
ParViews,
ParViewsSeal,
},
},
registry,
registry::{
contains::{
Contained,
EntityIdentifierMarker,
NotContained,
Null,
},
CanonicalParViews,
Registry,
},
};
use rayon::{
iter,
iter::{
IntoParallelRefIterator,
ParallelIterator,
},
};
#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))]
pub trait Sealed<'a, V, P, I, Q>: Registry
where
V: ParViews<'a>,
{
type Viewable: ContainsParViewsOuter<'a, V, P, I, Q>;
}
impl<'a, T, V, P, I, Q> Sealed<'a, V, P, I, Q> for T
where
T: Registry,
V: ParViews<'a>,
(EntityIdentifierMarker, T): ContainsParViewsOuter<'a, V, P, I, Q>,
{
type Viewable = (EntityIdentifierMarker, Self);
}
#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))]
pub trait ContainsParViewsOuter<'a, V, P, I, Q>
where
V: ParViews<'a>,
{
type Canonical: ParViews<'a, ParResults = Self::CanonicalResults>;
type CanonicalResults: Reshape<V::ParResults, Q, iter::RepeatN<view::Null>>;
unsafe fn par_view<R>(
columns: &[(*mut u8, usize)],
entity_identifiers: (*mut entity::Identifier, usize),
length: usize,
archetype_identifier: archetype::identifier::Iter<R>,
) -> Self::CanonicalResults
where
R: Registry;
}
impl<'a, I, IS, P, V, R, Q> ContainsParViewsOuter<'a, V, (Contained, P), (I, IS), Q>
for (EntityIdentifierMarker, R)
where
R: ContainsParViewsInner<'a, <V as Get<entity::Identifier, I>>::Remainder, P, IS>
+ CanonicalParViews<
'a,
<R as ContainsParViewsInner<
'a,
<V as Get<entity::Identifier, I>>::Remainder,
P,
IS,
>>::Canonical,
P,
>,
V: ParViews<'a> + Get<entity::Identifier, I>,
(
rayon::iter::Cloned<rayon::slice::Iter<'a, entity::Identifier>>,
<<R as ContainsParViewsInner<
'a,
<V as Get<entity::Identifier, I>>::Remainder,
P,
IS,
>>::Canonical as ParViewsSeal<'a>>::ParResults,
): Reshape<<V as ParViewsSeal<'a>>::ParResults, Q, iter::RepeatN<view::Null>>,
{
type Canonical = (
entity::Identifier,
<R as ContainsParViewsInner<
'a,
<V as Get<entity::Identifier, I>>::Remainder,
P,
IS,
>>::Canonical,
);
type CanonicalResults = <Self::Canonical as ParViewsSeal<'a>>::ParResults;
unsafe fn par_view<R_>(
columns: &[(*mut u8, usize)],
entity_identifiers: (*mut entity::Identifier, usize),
length: usize,
archetype_identifier: archetype::identifier::Iter<R_>,
) -> Self::CanonicalResults
where
R_: Registry,
{
(
unsafe {
core::slice::from_raw_parts_mut::<'a, entity::Identifier>(
entity_identifiers.0,
length,
)
}
.par_iter()
.cloned(),
unsafe { R::par_view(columns, length, archetype_identifier) },
)
}
}
impl<'a, I, P, R, V, Q> ContainsParViewsOuter<'a, V, (NotContained, P), I, Q>
for (EntityIdentifierMarker, R)
where
R: ContainsParViewsInner<'a, V, P, I>
+ CanonicalParViews<'a, <R as ContainsParViewsInner<'a, V, P, I>>::Canonical, P>,
V: ParViews<'a>,
<<R as ContainsParViewsInner<'a, V, P, I>>::Canonical as ParViewsSeal<'a>>::ParResults:
Reshape<<V as ParViewsSeal<'a>>::ParResults, Q, iter::RepeatN<view::Null>>,
{
type Canonical = <R as ContainsParViewsInner<'a, V, P, I>>::Canonical;
type CanonicalResults = <Self::Canonical as ParViewsSeal<'a>>::ParResults;
unsafe fn par_view<R_>(
columns: &[(*mut u8, usize)],
_entity_identifiers: (*mut entity::Identifier, usize),
length: usize,
archetype_identifier: archetype::identifier::Iter<R_>,
) -> Self::CanonicalResults
where
R_: Registry,
{
unsafe { R::par_view(columns, length, archetype_identifier) }
}
}
#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))]
pub trait ContainsParViewsInner<'a, V, P, I> {
type Canonical: ParViews<'a>;
}
impl ContainsParViewsInner<'_, view::Null, Null, Null> for registry::Null {
type Canonical = view::Null;
}
impl<'a, C, I, IS, P, R, V> ContainsParViewsInner<'a, V, (&'a Contained, P), (I, IS)> for (C, R)
where
C: Component + Sync,
R: ContainsParViewsInner<'a, <V as Get<&'a C, I>>::Remainder, P, IS>,
V: Get<&'a C, I>,
{
type Canonical = (
&'a C,
<R as ContainsParViewsInner<'a, <V as Get<&'a C, I>>::Remainder, P, IS>>::Canonical,
);
}
impl<'a, C, I, IS, P, R, V> ContainsParViewsInner<'a, V, (&'a mut Contained, P), (I, IS)> for (C, R)
where
C: Component + Send,
R: ContainsParViewsInner<'a, <V as Get<&'a mut C, I>>::Remainder, P, IS>,
V: Get<&'a mut C, I>,
{
type Canonical = (
&'a mut C,
<R as ContainsParViewsInner<'a, <V as Get<&'a mut C, I>>::Remainder, P, IS>>::Canonical,
);
}
impl<'a, C, I, IS, P, R, V> ContainsParViewsInner<'a, V, (Option<&'a Contained>, P), (I, IS)>
for (C, R)
where
C: Component + Sync,
R: ContainsParViewsInner<'a, <V as Get<Option<&'a C>, I>>::Remainder, P, IS>,
V: Get<Option<&'a C>, I>,
{
type Canonical = (
Option<&'a C>,
<R as ContainsParViewsInner<'a, <V as Get<Option<&'a C>, I>>::Remainder, P, IS>>::Canonical,
);
}
impl<'a, C, I, IS, P, R, V> ContainsParViewsInner<'a, V, (Option<&'a mut Contained>, P), (I, IS)>
for (C, R)
where
C: Component + Send,
R: ContainsParViewsInner<'a, <V as Get<Option<&'a mut C>, I>>::Remainder, P, IS>,
V: Get<Option<&'a mut C>, I>,
{
type Canonical = (
Option<&'a mut C>,
<R as ContainsParViewsInner<
'a,
<V as Get<Option<&'a mut C>, I>>::Remainder,
P,
IS,
>>::Canonical,
);
}
impl<'a, C, I, P, R, V> ContainsParViewsInner<'a, V, (NotContained, P), I> for (C, R)
where
R: ContainsParViewsInner<'a, V, P, I>,
{
type Canonical = <R as ContainsParViewsInner<'a, V, P, I>>::Canonical;
}