async_ecs/join/
maybe.rs

1use hibitset::{BitSetAll, BitSetLike};
2
3use crate::entity::Index;
4
5use super::{Join, ParJoin};
6
7/// A `Join`-able structure that yields all indices, returning `None` for all
8/// missing elements and `Some(T)` for found elements.
9///
10/// For usage see [`Join::maybe()`].
11///
12/// WARNING: Do not have a join of only `MaybeJoin`s. Otherwise the join will
13/// iterate over every single index of the bitset. If you want a join with
14/// all `MaybeJoin`s, add an `Entities` to the join as well to bound the
15/// join to all entities that are alive.
16///
17/// [`Join::maybe()`]: trait.Join.html#method.maybe
18pub struct MaybeJoin<J: Join>(pub J);
19
20impl<T> Join for MaybeJoin<T>
21where
22    T: Join,
23{
24    type Mask = BitSetAll;
25    type Type = Option<<T as Join>::Type>;
26    type Value = (<T as Join>::Mask, <T as Join>::Value);
27
28    unsafe fn open(self) -> (Self::Mask, Self::Value) {
29        let (mask, value) = self.0.open();
30
31        (BitSetAll, (mask, value))
32    }
33
34    unsafe fn get((mask, value): &mut Self::Value, index: Index) -> Self::Type {
35        if mask.contains(index) {
36            Some(<T as Join>::get(value, index))
37        } else {
38            None
39        }
40    }
41
42    fn is_unconstrained() -> bool {
43        true
44    }
45}
46
47impl<T> ParJoin for MaybeJoin<T> where T: ParJoin {}