ixa/entity/query/
query_impls.rs1use std::any::TypeId;
2
3use seq_macro::seq;
4
5use crate::entity::entity_set::{EntitySet, EntitySetIterator, SourceSet};
6use crate::entity::index::IndexSetResult;
7use crate::entity::property::Property;
8use crate::entity::query::QueryInternal;
9use crate::entity::{ContextEntitiesExt, Entity, EntityId};
10use crate::Context;
11
12impl<E: Entity> QueryInternal<E> for () {
13 type QueryParts<'a>
14 = [&'a dyn std::any::Any; 0]
15 where
16 Self: 'a;
17
18 fn get_type_ids(&self) -> Vec<TypeId> {
19 Vec::new()
20 }
21
22 fn multi_property_id(&self) -> Option<usize> {
23 None
24 }
25
26 fn is_empty_query(&self) -> bool {
27 true
28 }
29
30 fn query_parts(&self) -> Self::QueryParts<'_> {
31 []
32 }
33
34 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
35 EntitySet::from_source(SourceSet::PopulationRange(
36 0..context.get_entity_count::<E>(),
37 ))
38 }
39
40 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
41 EntitySetIterator::from_population_iterator(context.get_entity_iterator::<E>())
42 }
43
44 fn match_entity(&self, _entity_id: EntityId<E>, _context: &Context) -> bool {
45 true
47 }
48
49 fn filter_entities(&self, _entities: &mut Vec<EntityId<E>>, _context: &Context) {
50 }
52}
53
54impl<E: Entity> QueryInternal<E> for E {
57 type QueryParts<'a>
58 = [&'a dyn std::any::Any; 0]
59 where
60 Self: 'a;
61
62 fn get_type_ids(&self) -> Vec<TypeId> {
63 Vec::new()
64 }
65
66 fn multi_property_id(&self) -> Option<usize> {
67 None
68 }
69
70 fn is_empty_query(&self) -> bool {
71 true
72 }
73
74 fn query_parts(&self) -> Self::QueryParts<'_> {
75 []
76 }
77
78 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
79 EntitySet::from_source(SourceSet::PopulationRange(
80 0..context.get_entity_count::<E>(),
81 ))
82 }
83
84 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
85 let population_iterator = context.get_entity_iterator::<E>();
86 EntitySetIterator::from_population_iterator(population_iterator)
87 }
88
89 fn match_entity(&self, _entity_id: EntityId<E>, _context: &Context) -> bool {
90 true
91 }
92
93 fn filter_entities(&self, _entities: &mut Vec<EntityId<E>>, _context: &Context) {
94 }
96}
97
98impl<E: Entity, P1: Property<E>> QueryInternal<E> for (P1,) {
100 type QueryParts<'a>
101 = P1::QueryParts<'a>
102 where
103 Self: 'a;
104
105 fn get_type_ids(&self) -> Vec<TypeId> {
106 vec![P1::type_id()]
107 }
108
109 fn multi_property_id(&self) -> Option<usize> {
110 Some(P1::id())
111 }
112
113 fn query_parts(&self) -> Self::QueryParts<'_> {
114 P1::query_parts_for_value(&self.0)
115 }
116
117 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
118 let property_store = context.entity_store.get_property_store::<E>();
119
120 if let Some(multi_property_id) = self.multi_property_id() {
125 let query_parts = P1::query_parts_for_value(&self.0);
126 let lookup_result = property_store
127 .get_index_set_for_query_parts(multi_property_id, query_parts.as_ref());
128 match lookup_result {
129 IndexSetResult::Set(people_set) => {
130 return EntitySet::from_source(SourceSet::IndexSet(people_set));
131 }
132 IndexSetResult::Empty => {
133 return EntitySet::empty();
134 }
135 IndexSetResult::Unsupported => {}
136 }
137 }
139
140 let mut sources: Vec<SourceSet<E>> = Vec::new();
142
143 if let Some(source_set) = SourceSet::new::<P1>(self.0, context) {
144 sources.push(source_set);
145 } else {
146 return EntitySet::empty();
148 }
149
150 EntitySet::from_intersection_sources(sources)
151 }
152
153 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
154 let property_store = context.entity_store.get_property_store::<E>();
157
158 if let Some(multi_property_id) = self.multi_property_id() {
159 let query_parts = P1::query_parts_for_value(&self.0);
160 let lookup_result = property_store
161 .get_index_set_for_query_parts(multi_property_id, query_parts.as_ref());
162 match lookup_result {
163 IndexSetResult::Set(people_set) => {
164 return EntitySetIterator::from_index_set(people_set);
165 }
166 IndexSetResult::Empty => {
167 return EntitySetIterator::empty();
168 }
169 IndexSetResult::Unsupported => {}
170 }
171 }
172
173 let mut sources: Vec<SourceSet<E>> = Vec::new();
174
175 if let Some(source_set) = SourceSet::new::<P1>(self.0, context) {
176 sources.push(source_set);
177 } else {
178 return EntitySetIterator::empty();
179 }
180
181 EntitySetIterator::from_sources(sources)
182 }
183
184 fn match_entity(&self, entity_id: EntityId<E>, context: &Context) -> bool {
185 let found_value: P1 = context.get_property(entity_id);
186 found_value == self.0
187 }
188
189 fn filter_entities(&self, entities: &mut Vec<EntityId<E>>, context: &Context) {
190 let property_value_store = context.get_property_value_store::<E, P1>();
191 entities.retain(|entity| self.0 == property_value_store.get(*entity));
192 }
193}
194
195macro_rules! impl_query {
196 ($ct:expr) => {
197 seq!(N in 0..$ct {
198 impl<
199 E: Entity,
200 #(
201 T~N : Property<E>,
202 )*
203 > QueryInternal<E> for (
204 #(
205 T~N,
206 )*
207 )
208 {
209 type QueryParts<'a> = [&'a dyn std::any::Any; $ct] where Self: 'a;
210
211 fn get_type_ids(&self) -> Vec<TypeId> {
212 vec![
213 #(
214 <T~N as $crate::entity::property::Property<E>>::type_id(),
215 )*
216 ]
217 }
218
219 fn query_parts(&self) -> Self::QueryParts<'_> {
220 let keys = [
221 #(
222 <T~N as $crate::entity::property::Property<E>>::type_id(),
223 )*
224 ];
225 let mut query_parts = [
226 #(
227 &self.N as &dyn std::any::Any,
228 )*
229 ];
230 $crate::entity::multi_property::static_reorder_by_keys(&keys, &mut query_parts);
231 query_parts
232 }
233
234 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
235 if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
240 let property_store = context.entity_store.get_property_store::<E>();
241 let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
242 let lookup_result = property_store.get_index_set_for_query_parts(
243 multi_property_id,
244 query_parts.as_ref(),
245 );
246 match lookup_result {
247 $crate::entity::index::IndexSetResult::Set(entity_set) => {
248 return EntitySet::from_source(SourceSet::IndexSet(entity_set));
249 }
250 $crate::entity::index::IndexSetResult::Empty => {
251 return EntitySet::empty();
252 }
253 $crate::entity::index::IndexSetResult::Unsupported => {}
254 }
255 }
257
258 let mut sources: Vec<SourceSet<E>> = Vec::new();
260
261 #(
262 if let Some(source_set) = SourceSet::new::<T~N>(self.N, context) {
263 sources.push(source_set);
264 } else {
265 return EntitySet::empty();
267 }
268 )*
269
270 EntitySet::from_intersection_sources(sources)
271 }
272
273 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
274 if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
277 let property_store = context.entity_store.get_property_store::<E>();
278 let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
279 let lookup_result = property_store.get_index_set_for_query_parts(
280 multi_property_id,
281 query_parts.as_ref(),
282 );
283 match lookup_result {
284 $crate::entity::index::IndexSetResult::Set(entity_set) => {
285 return EntitySetIterator::from_index_set(entity_set);
286 }
287 $crate::entity::index::IndexSetResult::Empty => {
288 return EntitySetIterator::empty();
289 }
290 $crate::entity::index::IndexSetResult::Unsupported => {}
291 }
292 }
293
294 let mut sources: Vec<SourceSet<E>> = Vec::new();
295
296 #(
297 if let Some(source_set) = SourceSet::new::<T~N>(self.N, context) {
298 sources.push(source_set);
299 } else {
300 return EntitySetIterator::empty();
301 }
302 )*
303
304 EntitySetIterator::from_sources(sources)
305 }
306
307 fn match_entity(&self, entity_id: EntityId<E>, context: &Context) -> bool {
308 #(
309 {
310 let found_value: T~N = context.get_property(entity_id);
311 if found_value != self.N {
312 return false
313 }
314 }
315 )*
316 true
317 }
318
319 fn filter_entities(&self, entities: &mut Vec<EntityId<E>>, context: &Context) {
320 if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
322 let property_store = context.entity_store.get_property_store::<E>();
323 let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
324 let lookup_result = property_store.get_index_set_for_query_parts(
325 multi_property_id,
326 query_parts.as_ref(),
327 );
328 match lookup_result {
329 $crate::entity::index::IndexSetResult::Set(entity_set) => {
330 entities.retain(|entity_id| entity_set.contains(entity_id));
331 return;
332 }
333 $crate::entity::index::IndexSetResult::Empty => {
334 entities.clear();
335 return;
336 }
337 $crate::entity::index::IndexSetResult::Unsupported => {}
338 }
339 }
341
342 #(
344 {
345 let property_value_store = context.get_property_value_store::<E, T~N>();
346 entities.retain(
347 |entity|{
348 self.N == property_value_store.get(*entity)
349 }
350 );
351 }
352 )*
353 }
354 }
355 });
356 }
357}
358
359seq!(Z in 2..20 {
361 impl_query!(Z);
362});