shipyard 0.6.2

Entity Component System
Documentation
use super::abstract_mut::AbstractMut;
use super::with_id::LastId;
use crate::entity_id::EntityId;
#[cfg(feature = "parallel")]
use rayon::iter::plumbing::Producer;

#[allow(missing_docs)]
pub struct Tight<Storage> {
    pub(super) storage: Storage,
    pub(super) current: usize,
    pub(super) end: usize,
}

impl<Storage: AbstractMut> Iterator for Tight<Storage> {
    type Item = Storage::Out;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.current < self.end {
            self.current += 1;

            Some(unsafe { self.storage.get_data(self.current - 1) })
        } else {
            None
        }
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let exact = self.end - self.current;

        (exact, Some(exact))
    }
    #[inline]
    fn fold<B, F>(mut self, mut init: B, mut f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        while self.current < self.end {
            self.current += 1;

            init = f(init, unsafe { self.storage.get_data(self.current - 1) });
        }

        init
    }
}

impl<Storage: AbstractMut> ExactSizeIterator for Tight<Storage> {
    #[inline]
    fn len(&self) -> usize {
        self.end - self.current
    }
}

impl<Storage: AbstractMut> DoubleEndedIterator for Tight<Storage> {
    #[inline]
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.current < self.end {
            self.end -= 1;

            Some(unsafe { self.storage.get_data(self.end) })
        } else {
            None
        }
    }
    #[inline]
    fn rfold<B, F>(mut self, mut init: B, mut f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        while self.current < self.end {
            self.end -= 1;

            init = f(init, unsafe { self.storage.get_data(self.end) });
        }

        init
    }
}

impl<Storage: AbstractMut> LastId for Tight<Storage> {
    #[inline]
    unsafe fn last_id(&self) -> EntityId {
        self.storage.get_id(self.current - 1)
    }
    #[inline]
    unsafe fn last_id_back(&self) -> EntityId {
        self.storage.get_id(self.end + 1)
    }
}

#[cfg(feature = "parallel")]
impl<Storage: AbstractMut + Clone + Send> Producer for Tight<Storage> {
    type Item = <Self as Iterator>::Item;
    type IntoIter = Self;

    #[inline]
    fn into_iter(self) -> Self::IntoIter {
        self
    }
    #[inline]
    fn split_at(mut self, index: usize) -> (Self, Self) {
        let second_half = Tight {
            storage: self.storage.clone(),
            current: self.current + index,
            end: self.end,
        };

        self.end = second_half.current;

        (self, second_half)
    }
}