use std::any::{type_name, TypeId};
use hecs::{Fetch, Query};
use crate::borrow::ComponentBorrow;
#[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq)]
pub struct Access {
pub(crate) name: &'static str,
pub(crate) id: TypeId,
pub(crate) exclusive: bool,
}
impl std::fmt::Debug for Access {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.exclusive {
write!(f, "mut {}", self.name)
} else {
write!(f, "{}", self.name)
}
}
}
impl Access {
pub fn new(name: &'static str, id: TypeId, exclusive: bool) -> Self {
Self {
name,
id,
exclusive,
}
}
pub fn of<T: IntoAccess>() -> Self {
T::access()
}
#[inline]
pub fn exclusive(&self) -> bool {
self.exclusive
}
#[inline]
pub fn id(&self) -> std::any::TypeId {
self.id
}
#[inline]
pub fn name(&self) -> &'static str {
self.name
}
}
pub trait IntoAccess {
fn access() -> Access;
fn compatible<U: IntoAccess>() -> bool {
let l = Self::access();
let r = U::access();
l.id == r.id && (!r.exclusive || r.exclusive == l.exclusive)
}
}
impl<T: 'static> IntoAccess for &T {
fn access() -> Access {
Access {
id: TypeId::of::<T>(),
exclusive: false,
name: type_name::<T>(),
}
}
}
impl<T: 'static> IntoAccess for &mut T {
fn access() -> Access {
Access {
id: TypeId::of::<T>(),
exclusive: true,
name: type_name::<T>(),
}
}
}
pub struct AllAccess;
pub trait Subset {
fn is_subset<U: ComponentBorrow>() -> bool;
}
impl<'a, Q: Query> Subset for Q {
fn is_subset<U: ComponentBorrow>() -> bool {
let mut all = true;
Q::Fetch::for_each_borrow(|id, exclusive| {
if !U::has_dynamic(id, exclusive) {
all = false
}
});
all
}
}