async_ecs/join/
impls.rs

1use std::ops::{Deref, DerefMut};
2
3use crate::{
4    access::{read::Read, write::Write},
5    entity::Index,
6    misc::BitAnd,
7    resource::{Ref, RefMut, Resource},
8};
9
10use super::{Join, ParJoin};
11
12macro_rules! define_tuple_join {
13    ($($from:ident),*) => {
14        impl<$($from,)*> Join for ($($from),*,)
15            where $($from: Join),*,
16                  ($(<$from as Join>::Mask,)*): BitAnd,
17        {
18            type Type = ($($from::Type),*,);
19            type Value = ($($from::Value),*,);
20            type Mask = <($($from::Mask,)*) as BitAnd>::Value;
21
22            #[allow(non_snake_case)]
23            unsafe fn open(self) -> (Self::Mask, Self::Value) {
24                let ($($from,)*) = self;
25                let ($($from,)*) = ($($from.open(),)*);
26
27                (
28                    ($($from.0),*,).and(),
29                    ($($from.1),*,)
30                )
31            }
32
33            #[allow(non_snake_case)]
34            unsafe fn get(v: &mut Self::Value, i: Index) -> Self::Type {
35                let ($(ref mut $from,)*) = v;
36
37                ($($from::get($from, i),)*)
38            }
39
40            #[inline]
41            fn is_unconstrained() -> bool {
42                let mut unconstrained = true;
43
44                $( unconstrained = unconstrained && $from::is_unconstrained(); )*
45
46                unconstrained
47            }
48        }
49
50        impl<$($from,)*> ParJoin for ($($from),*,)
51            where $($from: ParJoin),*,
52                  ($(<$from as Join>::Mask,)*): BitAnd,
53        {}
54    }
55}
56
57define_tuple_join! { A }
58define_tuple_join! { A, B }
59define_tuple_join! { A, B, C }
60define_tuple_join! { A, B, C, D }
61define_tuple_join! { A, B, C, D, E }
62define_tuple_join! { A, B, C, D, E, F }
63define_tuple_join! { A, B, C, D, E, F, G }
64define_tuple_join! { A, B, C, D, E, F, G, H }
65define_tuple_join! { A, B, C, D, E, F, G, H, I }
66define_tuple_join! { A, B, C, D, E, F, G, H, I, J }
67define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K }
68define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L }
69define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L, M }
70define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L, M, N }
71define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O }
72define_tuple_join! { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P }
73
74macro_rules! define_mutable_join {
75    ($ty:ty) => {
76        impl<'a, 'b, T> Join for &'a mut $ty
77        where
78            &'a mut T: Join,
79            T: Resource,
80        {
81            type Type = <&'a mut T as Join>::Type;
82            type Value = <&'a mut T as Join>::Value;
83            type Mask = <&'a mut T as Join>::Mask;
84
85            unsafe fn open(self) -> (Self::Mask, Self::Value) {
86                self.deref_mut().open()
87            }
88
89            unsafe fn get(v: &mut Self::Value, i: Index) -> Self::Type {
90                <&'a mut T as Join>::get(v, i)
91            }
92
93            #[inline]
94            fn is_unconstrained() -> bool {
95                <&'a mut T as Join>::is_unconstrained()
96            }
97        }
98
99        impl<'a, 'b, T> ParJoin for &'a mut $ty
100        where
101            &'a mut T: ParJoin,
102            T: Resource,
103        {
104        }
105    };
106}
107
108define_mutable_join!(Write<'b, T>);
109define_mutable_join!(RefMut<'b, T>);
110
111macro_rules! define_immutable_join {
112    ($ty:ty) => {
113        impl<'a, 'b, T> Join for &'a $ty
114        where
115            &'a T: Join,
116            T: Resource,
117        {
118            type Type = <&'a T as Join>::Type;
119            type Value = <&'a T as Join>::Value;
120            type Mask = <&'a T as Join>::Mask;
121
122            unsafe fn open(self) -> (Self::Mask, Self::Value) {
123                self.deref().open()
124            }
125
126            unsafe fn get(v: &mut Self::Value, i: Index) -> Self::Type {
127                <&'a T as Join>::get(v, i)
128            }
129
130            #[inline]
131            fn is_unconstrained() -> bool {
132                <&'a T as Join>::is_unconstrained()
133            }
134        }
135
136        impl<'a, 'b, T> ParJoin for &'a $ty
137        where
138            &'a T: ParJoin,
139            T: Resource,
140        {
141        }
142    };
143}
144
145define_immutable_join!(Read<'b, T>);
146define_immutable_join!(Ref<'b, T>);