yaks 0.1.0

Minimalistic framework for automatic multithreading of hecs via rayon
Documentation
use crate::{Contains, DerefTuple, Ref, RefMut};

#[cfg(feature = "parallel")]
use crate::ResourceSet;

pub trait Fetch<'a, T, M0>: Sized {
    type Fetched: DerefTuple<'a, Output = Self>;

    fn fetch(resources: &T) -> Self::Fetched;

    fn release(resources: &T, fetched: Self::Fetched);

    #[cfg(feature = "parallel")]
    fn set_resource_bits(resource_set: &mut ResourceSet);
}

impl<'a, T, M0, R0> Fetch<'a, T, M0> for &'a R0
where
    T: Contains<R0, M0>,
    R0: 'a,
{
    type Fetched = Ref<R0>;

    fn fetch(resources: &T) -> Self::Fetched {
        T::borrow(resources)
    }

    fn release(resources: &T, fetched: Self::Fetched) {
        T::release(resources, fetched);
    }

    #[cfg(feature = "parallel")]
    fn set_resource_bits(resource_set: &mut ResourceSet) {
        T::set_resource_bit(&mut resource_set.immutable);
    }
}

impl<'a, T, M0, R0> Fetch<'a, T, M0> for &'a mut R0
where
    T: Contains<R0, M0>,
    R0: 'a,
{
    type Fetched = RefMut<R0>;

    fn fetch(resources: &T) -> Self::Fetched {
        T::borrow_mut(resources)
    }

    fn release(resources: &T, fetched: Self::Fetched) {
        T::release_mut(resources, fetched);
    }

    #[cfg(feature = "parallel")]
    fn set_resource_bits(resource_set: &mut ResourceSet) {
        T::set_resource_bit(&mut resource_set.mutable);
    }
}

impl<'a, T> Fetch<'a, T, ()> for () {
    type Fetched = ();

    fn fetch(_: &T) -> Self::Fetched {}

    fn release(_: &T, _: Self::Fetched) {}

    #[cfg(feature = "parallel")]
    fn set_resource_bits(_: &mut ResourceSet) {}
}

impl<'a, T, M0, F0> Fetch<'a, T, (M0,)> for (F0,)
where
    F0: Fetch<'a, T, M0>,
{
    type Fetched = (F0::Fetched,);

    fn fetch(resources: &T) -> Self::Fetched {
        (F0::fetch(resources),)
    }

    fn release(resources: &T, fetched: Self::Fetched) {
        F0::release(resources, fetched.0);
    }

    #[cfg(feature = "parallel")]
    fn set_resource_bits(resource_set: &mut ResourceSet) {
        F0::set_resource_bits(resource_set);
    }
}

macro_rules! impl_fetch {
    ($($letter:ident),*) => {
        paste::item! {
            impl<'a, T, $([<M $letter>],)* $([<F $letter>],)*> Fetch<'a, T, ($([<M $letter>],)*)>
                for ($([<F $letter>]),*)
            where
                $([<F $letter>]: Fetch<'a, T, [<M $letter>]>,)*
            {
                type Fetched = ($([<F $letter>]::Fetched,)*);

                fn fetch(resources: &T) -> Self::Fetched {
                    ($([<F $letter>]::fetch(resources)),*)
                }

                #[allow(non_snake_case)]
                fn release(resources: &T, fetched: Self::Fetched) {
                    let ($($letter,)*) = fetched;
                    $([<F $letter>]::release(resources, $letter);)*
                }

                #[cfg(feature = "parallel")]
                fn set_resource_bits(resource_set: &mut ResourceSet) {
                    $([<F $letter>]::set_resource_bits(resource_set);)*
                }
            }
        }
    }
}

impl_for_tuples!(impl_fetch);