use std::marker::PhantomData;
use std::ops::Deref;
use crate::{
resource::ResourceId,
system::{DynamicSystemData, SystemData},
};
pub trait Accessor: Sized {
fn reads(&self) -> Vec<ResourceId> {
Vec::new()
}
fn writes(&self) -> Vec<ResourceId> {
Vec::new()
}
fn try_new() -> Option<Self> {
None
}
}
pub type AccessorType<'a, T> = <T as DynamicSystemData<'a>>::Accessor;
#[derive(Default)]
pub struct StaticAccessor<T> {
marker: PhantomData<fn() -> T>,
}
impl<'a, T> Accessor for StaticAccessor<T>
where
T: SystemData<'a>,
{
fn try_new() -> Option<Self> {
Some(StaticAccessor {
marker: PhantomData,
})
}
fn reads(&self) -> Vec<ResourceId> {
T::reads()
}
fn writes(&self) -> Vec<ResourceId> {
T::writes()
}
}
pub enum AccessorCow<'a, 'b, T>
where
T: DynamicSystemData<'a> + ?Sized,
T::Accessor: 'b,
'a: 'b,
{
Borrow(&'b T::Accessor),
Owned(T::Accessor),
}
impl<'a, 'b, T> Deref for AccessorCow<'a, 'b, T>
where
AccessorType<'a, T>: 'b,
T: DynamicSystemData<'a> + ?Sized + 'b,
'a: 'b,
{
type Target = T::Accessor;
fn deref(&self) -> &T::Accessor {
match *self {
AccessorCow::Borrow(r) => &*r,
AccessorCow::Owned(ref o) => o,
}
}
}