kaige_ecs/internals/query/filter/
and.rs1use super::{
2 not::Not, or::Or, passthrough::Passthrough, ActiveFilter, DynamicFilter, FilterResult,
3 GroupMatcher, LayoutFilter,
4};
5use crate::internals::{query::view::Fetch, storage::component::ComponentTypeId, world::WorldId};
6
7#[derive(Debug, Clone)]
9pub struct And<T> {
10 pub(super) filters: T,
11}
12
13macro_rules! and_filter {
14 ($head_ty:ident) => {
15 impl_and_filter!($head_ty);
16 };
17 ($head_ty:ident, $( $tail_ty:ident ),*) => (
18 impl_and_filter!($head_ty, $( $tail_ty ),*);
19 and_filter!($( $tail_ty ),*);
20 );
21}
22
23macro_rules! impl_and_filter {
24 ( $( $ty:ident ),* ) => {
25 impl<$( $ty ),*> ActiveFilter for And<($( $ty, )*)> {}
26
27 impl<$( $ty: Default ),*> Default for And<($( $ty, )*)> {
28 fn default() -> Self {
29 Self {
30 filters: ($( $ty::default(), )*)
31 }
32 }
33 }
34
35 impl<$( $ty: GroupMatcher ),*> GroupMatcher for And<($( $ty, )*)> {
36 fn can_match_group() -> bool {
37 $( $ty::can_match_group() )&&*
38 }
39 fn group_components() -> Vec<ComponentTypeId> {
40 let mut components = Vec::new();
41 $( components.extend($ty::group_components()); )*
42 components
43 }
44 }
45
46 impl<$( $ty: LayoutFilter ),*> LayoutFilter for And<($( $ty, )*)> {
47 #[inline]
48 fn matches_layout(&self, components: &[ComponentTypeId]) -> FilterResult {
49 #![allow(non_snake_case)]
50 let ($( $ty, )*) = &self.filters;
51 let mut result = FilterResult::Defer;
52 $( result = result.coalesce_and($ty.matches_layout(components)); )*
53 result
54 }
55 }
56
57 impl<$( $ty: DynamicFilter ),*> DynamicFilter for And<($( $ty, )*)> {
58 #[inline]
59 fn prepare(&mut self, world: WorldId) {
60 #![allow(non_snake_case)]
61 let ($( $ty, )*) = &mut self.filters;
62 $( $ty.prepare(world); )*
63 }
64
65 #[inline]
66 fn matches_archetype<Fet: Fetch>(&mut self, fetch: &Fet) -> FilterResult {
67 #![allow(non_snake_case)]
68 let ($( $ty, )*) = &mut self.filters;
69 let mut result = FilterResult::Defer;
70 $( result = result.coalesce_and($ty.matches_archetype(fetch)); )*
71 result
72 }
73 }
74
75 impl<$( $ty ),*> std::ops::Not for And<($( $ty, )*)> {
76 type Output = Not<Self>;
77
78 #[inline]
79 fn not(self) -> Self::Output {
80 Not { filter: self }
81 }
82 }
83
84 impl<$( $ty ),*, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for And<($( $ty, )*)> {
85 type Output = And<($( $ty, )* Rhs)>;
86
87 #[inline]
88 fn bitand(self, rhs: Rhs) -> Self::Output {
89 #![allow(non_snake_case)]
90 let ($( $ty, )*) = self.filters;
91 And {
92 filters: ($( $ty, )* rhs),
93 }
94 }
95 }
96
97 impl<$( $ty ),*> std::ops::BitAnd<Passthrough> for And<($( $ty, )*)> {
98 type Output = Self;
99
100 #[inline]
101 fn bitand(self, _: Passthrough) -> Self::Output {
102 self
103 }
104 }
105
106 impl<$( $ty ),*, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for And<($( $ty, )*)> {
107 type Output = Or<(Self, Rhs)>;
108
109 #[inline]
110 fn bitor(self, rhs: Rhs) -> Self::Output {
111 Or {
112 filters: (self, rhs),
113 }
114 }
115 }
116
117 impl<$( $ty ),*> std::ops::BitOr<Passthrough> for And<($( $ty, )*)> {
118 type Output = Self;
119
120 #[inline]
121 fn bitor(self, _: Passthrough) -> Self::Output {
122 self
123 }
124 }
125 };
126}
127
128#[cfg(feature = "extended-tuple-impls")]
129and_filter!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);
130
131#[cfg(not(feature = "extended-tuple-impls"))]
132and_filter!(A, B, C, D, E, F, G, H);