1#[cfg(test)]
2mod test;
3
4use std::{any::TypeId, collections::HashSet, marker::PhantomData};
5
6use crate::{
7 prelude::{Filter, Query},
8 query::{QueryFragment, WorldQuery},
9};
10
11pub struct QuerySet<Inner> {
52 world: std::ptr::NonNull<crate::World>,
53 _m: PhantomData<Inner>,
54}
55
56unsafe impl<T> Send for QuerySet<T> {}
57unsafe impl<T> Sync for QuerySet<T> {}
58
59macro_rules! impl_tuple {
60 ($($idx: tt , $t: ident , $f: ident , $q: ident , $q_mut: ident , $set: ident);+ $(;)?) => {
61 impl<'a, $($t, $f),*> QuerySet<($(Query<'a, $t, $f>),*)>
62 where
63 $(
64 $t: QueryFragment,
65 $f: Filter,
66 )*
67 {
68 $(
69 pub fn $q<'b>(&'b self) -> Query<'b, $t, $f>
70 where 'a: 'b
71 {
72 unsafe {Query::new(self.world.as_ref())}
73 }
74
75 pub fn $q_mut<'b>(&'b mut self) -> Query<'b, $t, $f>
76 where 'a: 'b
77 {
78 unsafe {Query::new(self.world.as_ref())}
79 }
80 )*
81 }
82
83 unsafe impl<'a, $($t, $f),*> WorldQuery<'a> for QuerySet<($(Query<'a, $t, $f>),*)>
84 where
85 $(
86 $t: QueryFragment,
87 $f: Filter,
88 )*
89 {
90 fn new(db: &'a crate::World, _system_idx: usize) -> Self {
91 Self {
92 world: std::ptr::NonNull::from(db),
93 _m: PhantomData,
94 }
95 }
96
97 fn exclusive() -> bool {false}
98
99 fn read_only() -> bool {
100 true
101 $(
102 &&
103 <$t as QueryFragment>::read_only()
104 )*
105 }
106
107 fn components_mut(set: &mut HashSet<TypeId>) {
108 $(
112 let mut $set = set.clone();
113 <$t as QueryFragment>::types_mut(&mut $set);
114 )*
115
116 $(
117 set.extend($set.into_iter());
118 )*
119 }
120
121 fn components_const(set: &mut HashSet<TypeId>) {
122 $(
123 <$t as QueryFragment>::types_const(set);
124 )*
125 let mut mutable_components = HashSet::new();
127 let mut tmp = HashSet::new();
128 $(
129 tmp.clear();
130 <$t as QueryFragment>::types_mut(&mut tmp);
133 mutable_components.extend(tmp.drain());
134 )*
135 set.retain(|t| !mutable_components.contains(t));
136 }
137 }
138 };
139}
140
141impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1;);
142impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1; 2 , T2 , F2 , q2 , q2_mut , set2;);
143impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1; 2 , T2 , F2 , q2 , q2_mut , set2; 3 , T3 , F3 , q3 , q3_mut , set3;);
144impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1; 2 , T2 , F2 , q2 , q2_mut , set2; 3 , T3 , F3 , q3 , q3_mut , set3; 4 , T4 , F4 , q4 , q4_mut , set4;);
145impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1; 2 , T2 , F2 , q2 , q2_mut , set2; 3 , T3 , F3 , q3 , q3_mut , set3; 4 , T4 , F4 , q4 , q4_mut , set4; 5 , T5 , F5 , q5 , q5_mut , set5;);
146impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1; 2 , T2 , F2 , q2 , q2_mut , set2; 3 , T3 , F3 , q3 , q3_mut , set3; 4 , T4 , F4 , q4 , q4_mut , set4; 5 , T5 , F5 , q5 , q5_mut , set5; 6 , T6 , F6 , q6 , q6_mut , set6;);
147impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1; 2 , T2 , F2 , q2 , q2_mut , set2; 3 , T3 , F3 , q3 , q3_mut , set3; 4 , T4 , F4 , q4 , q4_mut , set4; 5 , T5 , F5 , q5 , q5_mut , set5; 6 , T6 , F6 , q6 , q6_mut , set6; 7 , T7 , F7 , q7 , q7_mut , set7;);
148impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1; 2 , T2 , F2 , q2 , q2_mut , set2; 3 , T3 , F3 , q3 , q3_mut , set3; 4 , T4 , F4 , q4 , q4_mut , set4; 5 , T5 , F5 , q5 , q5_mut , set5; 6 , T6 , F6 , q6 , q6_mut , set6; 7 , T7 , F7 , q7 , q7_mut , set7; 8 , T8 , F8 , q8 , q8_mut , set8;);
149impl_tuple!(0 , T0 , F0 , q0 , q0_mut , set0; 1 , T1 , F1 , q1 , q1_mut , set1; 2 , T2 , F2 , q2 , q2_mut , set2; 3 , T3 , F3 , q3 , q3_mut , set3; 4 , T4 , F4 , q4 , q4_mut , set4; 5 , T5 , F5 , q5 , q5_mut , set5; 6 , T6 , F6 , q6 , q6_mut , set6; 7 , T7 , F7 , q7 , q7_mut , set7; 8 , T8 , F8 , q8 , q8_mut , set8; 9 , T9 , F9 , q9 , q9_mut , set9;);