use crate::{
component,
entities,
hlist::Get,
registry,
registry::{
contains::{
Contained,
NotContained,
Null,
},
Canonical,
},
};
use alloc::vec::Vec;
pub trait Sealed<Entities, Indices>:
Canonical<<Self::Canonical as entities::Contains>::Entity, Self::CanonicalContainments>
{
type Canonical: entities::Entities;
type CanonicalContainments;
fn canonical(entities: Entities) -> Self::Canonical;
}
impl<Registry, Entities, Containments, CanonicalContainments, Indices>
Sealed<Entities, (Containments, CanonicalContainments, Indices)> for Registry
where
Registry: Expanded<Entities, Containments, CanonicalContainments, Indices>,
{
type Canonical = Registry::Canonical;
type CanonicalContainments = CanonicalContainments;
fn canonical(entities: Entities) -> Self::Canonical {
Registry::canonical(entities)
}
}
pub trait Expanded<Entities, Containments, CanonicalContainments, Indices>:
Canonical<<Self::Canonical as entities::Contains>::Entity, CanonicalContainments>
{
type Canonical: entities::Entities;
fn canonical(entities: Entities) -> Self::Canonical;
}
impl<CanonicalContainments> Expanded<entities::Null, Null, CanonicalContainments, Null>
for registry::Null
where
Self: Canonical<<entities::Null as entities::Contains>::Entity, CanonicalContainments>,
{
type Canonical = entities::Null;
fn canonical(_entities: entities::Null) -> Self::Canonical {
entities::Null
}
}
impl<
Component,
Registry,
Entities,
Containments,
CanonicalContainment,
CanonicalContainments,
Index,
Indices,
>
Expanded<
Entities,
(Contained, Containments),
(CanonicalContainment, CanonicalContainments),
(Index, Indices),
> for (Component, Registry)
where
Self: Canonical<
<(
Vec<Component>,
<Registry as Expanded<
<Entities as Get<Vec<Component>, Index>>::Remainder,
Containments,
CanonicalContainments,
Indices,
>>::Canonical,
) as entities::Contains>::Entity,
(CanonicalContainment, CanonicalContainments),
>,
Registry: Expanded<
<Entities as Get<Vec<Component>, Index>>::Remainder,
Containments,
CanonicalContainments,
Indices,
>,
Entities: Get<Vec<Component>, Index>,
Component: component::Component,
{
type Canonical = (
Vec<Component>,
<Registry as Expanded<
<Entities as Get<Vec<Component>, Index>>::Remainder,
Containments,
CanonicalContainments,
Indices,
>>::Canonical,
);
fn canonical(entities: Entities) -> Self::Canonical {
let (component, remainder) = entities.get();
(component, Registry::canonical(remainder))
}
}
impl<Component, Registry, Entities, Containments, CanonicalContainment, CanonicalContainments, Indices> Expanded<Entities, (NotContained, Containments), (CanonicalContainment, CanonicalContainments), Indices> for (Component, Registry)
where
Self: Canonical<<<Registry as Expanded<Entities, Containments, CanonicalContainments, Indices>>::Canonical as entities::Contains>::Entity, (CanonicalContainment, CanonicalContainments)>,
Registry: Expanded<Entities, Containments, CanonicalContainments, Indices>,
{
type Canonical = <Registry as Expanded<Entities, Containments, CanonicalContainments, Indices>>::Canonical;
fn canonical(entities: Entities) -> Self::Canonical {
Registry::canonical(entities)
}
}
#[cfg(test)]
mod tests {
use super::Sealed;
use crate::{
entities,
Registry,
};
#[derive(Clone, Debug, Eq, PartialEq)]
struct A;
#[derive(Clone, Debug, Eq, PartialEq)]
struct B;
#[derive(Clone, Debug, Eq, PartialEq)]
struct C;
#[derive(Clone, Debug, Eq, PartialEq)]
struct D;
#[derive(Clone, Debug, Eq, PartialEq)]
struct E;
type Registry = Registry!(A, B, C, D, E);
#[test]
fn entities_empty() {
assert_eq!(
Registry::canonical(entities!((); 100).entities),
entities!((); 100).entities
);
}
#[test]
fn entities_subset() {
assert_eq!(
Registry::canonical(entities!((E, C, B); 100).entities),
entities!((B, C, E); 100).entities
);
}
#[test]
fn entities_all_components_already_canonical_order() {
assert_eq!(
Registry::canonical(entities!((A, B, C, D, E); 100).entities),
entities!((A, B, C, D, E); 100).entities
);
}
#[test]
fn entities_all_components_reordered() {
assert_eq!(
Registry::canonical(entities!((D, B, A, E, C); 100).entities),
entities!((A, B, C, D, E); 100).entities
);
}
}