use hecs::{Entity, Fetch, Query, QueryBorrow};
use rayon::iter::{ParallelBridge, ParallelIterator};
pub trait View<'a> {
type Superset;
fn split(orig: Self::Superset) -> Self;
}
impl<'a, T> View<'a> for &'a T {
type Superset = Self;
fn split(orig: Self::Superset) -> Self {
orig
}
}
impl<'a, T> View<'a> for &'a mut T {
type Superset = Self;
fn split(orig: Self::Superset) -> Self {
orig
}
}
pub trait QueryExt {
type Item;
fn par_for_each(self, batch_size: u32, func: impl Fn((Entity, Self::Item)) + Send + Sync);
fn try_par_for_each<E: Send>(
self,
batch_size: u32,
func: impl Fn((Entity, Self::Item)) -> Result<(), E> + Send + Sync,
) -> Result<(), E>;
}
impl<'w, 'q, Q> QueryExt for &'q mut QueryBorrow<'w, Q>
where
Q: Query + Send + Sync,
{
type Item = <Q::Fetch as Fetch<'q>>::Item;
fn par_for_each(self, batch_size: u32, func: impl Fn((Entity, Self::Item)) + Send + Sync) {
self.iter_batched(batch_size)
.par_bridge()
.for_each(|batch| batch.for_each(&func))
}
fn try_par_for_each<E: Send>(
self,
batch_size: u32,
func: impl Fn((Entity, Self::Item)) -> Result<(), E> + Send + Sync,
) -> Result<(), E> {
self.iter_batched(batch_size)
.par_bridge()
.try_for_each(|mut batch| batch.try_for_each(&func))
}
}