1use hecs::{Query, QueryBorrow};
3
4#[cfg(feature = "parallel")]
5use hecs::Entity;
6
7pub trait View<'a> {
9 type Superset;
11 fn split(orig: Self::Superset) -> Self;
13}
14
15impl<'a, T> View<'a> for &'a T {
18 type Superset = Self;
19
20 fn split(orig: Self::Superset) -> Self {
21 orig
22 }
23}
24
25impl<'a, T> View<'a> for &'a mut T {
26 type Superset = Self;
27
28 fn split(orig: Self::Superset) -> Self {
29 orig
30 }
31}
32
33pub trait QueryExt {
35 type Item<'a>;
37 #[cfg(feature = "parallel")]
39 fn par_for_each<'a>(self, batch_size: u32, func: impl Fn((Entity, Self::Item<'a>)) + Send + Sync);
40 #[cfg(feature = "parallel")]
42 fn try_par_for_each<'a, E: Send>(
43 self,
44 batch_size: u32,
45 func: impl Fn((Entity, Self::Item<'a>)) -> Result<(), E> + Send + Sync,
46 ) -> Result<(), E>;
47}
48
49impl<'w, 'q, Q> QueryExt for &'q mut QueryBorrow<'w, Q>
50where
51 Q: Query,
52 for <'a> Q::Item<'a>: Send,
53{
54 type Item<'a> = Q::Item<'q>;
55
56 #[cfg(feature = "parallel")]
57 fn par_for_each<'a>(self, batch_size: u32, func: impl Fn((Entity, Self::Item<'a>)) + Send + Sync) {
58 use rayon::iter::{ParallelBridge, ParallelIterator};
59 self.iter_batched(batch_size)
60 .par_bridge()
61 .for_each(|batch| batch.for_each(&func))
62 }
63
64 #[cfg(feature = "parallel")]
65 fn try_par_for_each<'a, E: Send>(
66 self,
67 batch_size: u32,
68 func: impl Fn((Entity, Self::Item<'a>)) -> Result<(), E> + Send + Sync,
69 ) -> Result<(), E> {
70 use rayon::iter::{ParallelBridge, ParallelIterator};
71 self.iter_batched(batch_size)
72 .par_bridge()
73 .try_for_each(|mut batch| batch.try_for_each(&func))
74 }
75}