Skip to main content

hecs_schedule/
traits.rs

1//! Defines common traits
2use hecs::{Query, QueryBorrow};
3
4#[cfg(feature = "parallel")]
5use hecs::Entity;
6
7/// Traits for types which represent a view or subset of some other type.
8pub trait View<'a> {
9    /// The type which View comes from
10    type Superset;
11    /// Splits from the containing superset
12    fn split(orig: Self::Superset) -> Self;
13}
14
15// Implement view for self. A set is always its own subset
16
17impl<'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
33/// Extends the queries for additional paralell operation
34pub trait QueryExt {
35    /// Item returned by the query
36    type Item<'a>;
37    /// Execute a function for each item of the query in pararell using rayon.
38    #[cfg(feature = "parallel")]
39    fn par_for_each<'a>(self, batch_size: u32, func: impl Fn((Entity, Self::Item<'a>)) + Send + Sync);
40    /// Fallible version of [`QueryBorrow::par_for_each`]
41    #[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}