use crate::{
entity,
hlist::{
define_null,
Get,
},
query::view,
registry::ContainsViews,
};
define_null!();
pub trait Disjoint<OtherViews, Registry, Indices>: Sealed<OtherViews, Registry, Indices> {}
impl<Views, OtherViews, Registry, Indices> Disjoint<OtherViews, Registry, Indices> for Views where
Views: Sealed<OtherViews, Registry, Indices>
{
}
pub trait Sealed<OtherViews, Registry, Indices> {}
impl<
'a,
Views,
OtherViews,
Registry,
Indices,
InverseIndices,
OppositeIndices,
OppositeInverseIndices,
>
Sealed<
OtherViews,
Registry,
(
Indices,
InverseIndices,
OppositeIndices,
OppositeInverseIndices,
),
> for Views
where
OtherViews: view::Views<'a> + MutableInverse<Registry, InverseIndices>,
OtherViews::Result: ContainsViews<'a, Views, Indices>,
Views: view::Views<'a> + MutableInverse<Registry, OppositeInverseIndices>,
Views::Result: ContainsViews<'a, OtherViews, OppositeIndices>,
{
}
pub trait MutableInverse<Registry, Indices> {
type Result;
}
impl<Registry> MutableInverse<Registry, Null> for view::Null {
type Result = Registry;
}
impl<Component, Views, Registry, Indices> MutableInverse<Registry, Indices> for (&Component, Views)
where
Views: MutableInverse<Registry, Indices>,
{
type Result = <Views as MutableInverse<Registry, Indices>>::Result;
}
impl<Component, Views, Registry, Indices> MutableInverse<Registry, Indices>
for (Option<&Component>, Views)
where
Views: MutableInverse<Registry, Indices>,
{
type Result = <Views as MutableInverse<Registry, Indices>>::Result;
}
impl<Views, Registry, Indices> MutableInverse<Registry, Indices> for (entity::Identifier, Views)
where
Views: MutableInverse<Registry, Indices>,
{
type Result = <Views as MutableInverse<Registry, Indices>>::Result;
}
impl<Component, Views, Registry, Index, Indices> MutableInverse<Registry, (Index, Indices)>
for (&mut Component, Views)
where
Registry: Get<Component, Index>,
Views: MutableInverse<<Registry as Get<Component, Index>>::Remainder, Indices>,
{
type Result =
<Views as MutableInverse<<Registry as Get<Component, Index>>::Remainder, Indices>>::Result;
}
impl<Component, Views, Registry, Index, Indices> MutableInverse<Registry, (Index, Indices)>
for (Option<&mut Component>, Views)
where
Registry: Get<Component, Index>,
Views: MutableInverse<<Registry as Get<Component, Index>>::Remainder, Indices>,
{
type Result =
<Views as MutableInverse<<Registry as Get<Component, Index>>::Remainder, Indices>>::Result;
}
#[cfg(test)]
mod tests {
use super::Disjoint;
use crate::{
entity,
query::Views,
Registry,
};
fn is_disjoint<Views, OtherViews, Registry, Indices>()
where
Views: Disjoint<OtherViews, Registry, Indices>,
{
}
struct A;
struct B;
struct C;
type Registry = Registry!(A, B, C);
#[test]
fn empty() {
is_disjoint::<Views!(), Views!(), Registry!(), _>();
}
#[test]
fn empty_first_views() {
is_disjoint::<Views!(), Views!(&A, &mut B, Option<&C>), Registry, _>();
}
#[test]
fn empty_second_views() {
is_disjoint::<Views!(&A, &mut B, Option<&C>), Views!(), Registry, _>();
}
#[test]
fn shared_immutable_views() {
is_disjoint::<Views!(&A, &B, &C), Views!(&A, &B, &C), Registry, _>();
}
#[test]
fn shared_immutable_optional_views() {
is_disjoint::<
Views!(Option<&A>, Option<&B>, Option<&C>),
Views!(Option<&A>, Option<&B>, Option<&C>),
Registry,
_,
>();
}
#[test]
fn disjoint_mutable_views() {
is_disjoint::<Views!(&mut A, &mut C), Views!(&mut B, entity::Identifier), Registry, _>();
}
#[test]
fn disjoint_mutable_optional_views() {
is_disjoint::<
Views!(Option<&mut A>, Option<&mut C>),
Views!(Option<&mut B>, entity::Identifier),
Registry,
_,
>();
}
#[test]
fn entity_identifier() {
is_disjoint::<Views!(entity::Identifier), Views!(entity::Identifier), Registry, _>();
}
}