shipyard 0.11.2

Entity Component System
Documentation
use crate::iter::{Shiperator, ShiperatorCaptain, ShiperatorSailor};

#[allow(missing_docs)]
pub struct ParShiperator<S>(pub(crate) Shiperator<S>);

impl<S: ShiperatorCaptain + ShiperatorSailor + Send + Clone>
    rayon::iter::plumbing::UnindexedProducer for Shiperator<S>
{
    type Item = S::Out;

    fn split(self) -> (Self, Option<Self>) {
        let follow_up_len = self.entities.follow_up_len();
        let remaining = self.end - self.start;

        let max_len = self.end - self.start + follow_up_len;
        if max_len <= 1 {
            return (self, None);
        }

        let new_end = self.start + (remaining / 2);

        let (entities, other_entities) = self.entities.split_at(follow_up_len / 2);

        (
            Shiperator {
                shiperator: self.shiperator.clone(),
                entities,
                is_exact_sized: self.is_exact_sized,
                start: self.start,
                end: new_end,
            },
            Some(Shiperator {
                shiperator: self.shiperator,
                entities: other_entities,
                is_exact_sized: self.is_exact_sized,
                start: new_end,
                end: self.end,
            }),
        )
    }

    fn fold_with<F>(self, folder: F) -> F
    where
        F: rayon::iter::plumbing::Folder<Self::Item>,
    {
        folder.consume_iter(self)
    }
}

impl<S: ShiperatorCaptain + ShiperatorSailor + Send + Clone> rayon::iter::ParallelIterator
    for ParShiperator<S>
where
    S::Out: Send,
{
    type Item = S::Out;

    #[inline]
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
    where
        C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
    {
        rayon::iter::plumbing::bridge_unindexed(self.0, consumer)
    }

    #[inline]
    fn opt_len(&self) -> Option<usize> {
        if self.0.is_exact_sized {
            self.0.size_hint().1
        } else {
            None
        }
    }
}