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::index_id())
113 }
114
115 fn query_parts(&self) -> Self::QueryParts<'_> {
116 P1::query_parts_for_value(&self.0)
117 }
118
119 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
120 let property_store = context.entity_store.get_property_store::<E>();
121
122 if let Some(multi_property_id) = self.multi_property_id() {
127 let query_parts = P1::query_parts_for_value(&self.0);
128 let lookup_result = property_store
129 .get_index_set_for_query_parts(multi_property_id, query_parts.as_ref());
130 match lookup_result {
131 IndexSetResult::Set(people_set) => {
132 return EntitySet::from_source(SourceSet::IndexSet(people_set));
133 }
134 IndexSetResult::Empty => {
135 return EntitySet::empty();
136 }
137 IndexSetResult::Unsupported => {}
138 }
139 }
141
142 let mut sources: Vec<SourceSet<E>> = Vec::new();
144
145 if let Some(source_set) = SourceSet::new::<P1>(self.0, context) {
146 sources.push(source_set);
147 } else {
148 return EntitySet::empty();
150 }
151
152 EntitySet::from_intersection_sources(sources)
153 }
154
155 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
156 let property_store = context.entity_store.get_property_store::<E>();
159
160 if let Some(multi_property_id) = self.multi_property_id() {
161 let query_parts = P1::query_parts_for_value(&self.0);
162 let lookup_result = property_store
163 .get_index_set_for_query_parts(multi_property_id, query_parts.as_ref());
164 match lookup_result {
165 IndexSetResult::Set(people_set) => {
166 return EntitySetIterator::from_index_set(people_set);
167 }
168 IndexSetResult::Empty => {
169 return EntitySetIterator::empty();
170 }
171 IndexSetResult::Unsupported => {}
172 }
173 }
174
175 let mut sources: Vec<SourceSet<E>> = Vec::new();
176
177 if let Some(source_set) = SourceSet::new::<P1>(self.0, context) {
178 sources.push(source_set);
179 } else {
180 return EntitySetIterator::empty();
181 }
182
183 EntitySetIterator::from_sources(sources)
184 }
185
186 fn match_entity(&self, entity_id: EntityId<E>, context: &Context) -> bool {
187 let found_value: P1 = context.get_property(entity_id);
188 found_value == self.0
189 }
190
191 fn filter_entities(&self, entities: &mut Vec<EntityId<E>>, context: &Context) {
192 let property_value_store = context.get_property_value_store::<E, P1>();
193 entities.retain(|entity| self.0 == property_value_store.get(*entity));
194 }
195}
196
197macro_rules! impl_query {
198 ($ct:expr) => {
199 seq!(N in 0..$ct {
200 impl<
201 E: Entity,
202 #(
203 T~N : Property<E>,
204 )*
205 > QueryInternal<E> for (
206 #(
207 T~N,
208 )*
209 )
210 {
211 type QueryParts<'a> = [&'a dyn std::any::Any; $ct] where Self: 'a;
212
213 fn get_type_ids(&self) -> Vec<TypeId> {
214 vec![
215 #(
216 <T~N as $crate::entity::property::Property<E>>::type_id(),
217 )*
218 ]
219 }
220
221 fn query_parts(&self) -> Self::QueryParts<'_> {
222 let keys = [
223 #(
224 <T~N as $crate::entity::property::Property<E>>::name(),
225 )*
226 ];
227 let mut query_parts = [
228 #(
229 &self.N as &dyn std::any::Any,
230 )*
231 ];
232 $crate::entity::multi_property::static_reorder_by_keys(&keys, &mut query_parts);
233 query_parts
234 }
235
236 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
237 if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
242 let property_store = context.entity_store.get_property_store::<E>();
243 let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
244 let lookup_result = property_store.get_index_set_for_query_parts(
245 multi_property_id,
246 query_parts.as_ref(),
247 );
248 match lookup_result {
249 $crate::entity::index::IndexSetResult::Set(entity_set) => {
250 return EntitySet::from_source(SourceSet::IndexSet(entity_set));
251 }
252 $crate::entity::index::IndexSetResult::Empty => {
253 return EntitySet::empty();
254 }
255 $crate::entity::index::IndexSetResult::Unsupported => {}
256 }
257 }
259
260 let mut sources: Vec<SourceSet<E>> = Vec::new();
262
263 #(
264 if let Some(source_set) = SourceSet::new::<T~N>(self.N, context) {
265 sources.push(source_set);
266 } else {
267 return EntitySet::empty();
269 }
270 )*
271
272 EntitySet::from_intersection_sources(sources)
273 }
274
275 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
276 if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
279 let property_store = context.entity_store.get_property_store::<E>();
280 let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
281 let lookup_result = property_store.get_index_set_for_query_parts(
282 multi_property_id,
283 query_parts.as_ref(),
284 );
285 match lookup_result {
286 $crate::entity::index::IndexSetResult::Set(entity_set) => {
287 return EntitySetIterator::from_index_set(entity_set);
288 }
289 $crate::entity::index::IndexSetResult::Empty => {
290 return EntitySetIterator::empty();
291 }
292 $crate::entity::index::IndexSetResult::Unsupported => {}
293 }
294 }
295
296 let mut sources: Vec<SourceSet<E>> = Vec::new();
297
298 #(
299 if let Some(source_set) = SourceSet::new::<T~N>(self.N, context) {
300 sources.push(source_set);
301 } else {
302 return EntitySetIterator::empty();
303 }
304 )*
305
306 EntitySetIterator::from_sources(sources)
307 }
308
309 fn match_entity(&self, entity_id: EntityId<E>, context: &Context) -> bool {
310 #(
311 {
312 let found_value: T~N = context.get_property(entity_id);
313 if found_value != self.N {
314 return false
315 }
316 }
317 )*
318 true
319 }
320
321 fn filter_entities(&self, entities: &mut Vec<EntityId<E>>, context: &Context) {
322 if let Some(multi_property_id) = <Self as $crate::entity::QueryInternal<E>>::multi_property_id(self) {
324 let property_store = context.entity_store.get_property_store::<E>();
325 let query_parts = <Self as $crate::entity::QueryInternal<E>>::query_parts(self);
326 let lookup_result = property_store.get_index_set_for_query_parts(
327 multi_property_id,
328 query_parts.as_ref(),
329 );
330 match lookup_result {
331 $crate::entity::index::IndexSetResult::Set(entity_set) => {
332 entities.retain(|entity_id| entity_set.contains(entity_id));
333 return;
334 }
335 $crate::entity::index::IndexSetResult::Empty => {
336 entities.clear();
337 return;
338 }
339 $crate::entity::index::IndexSetResult::Unsupported => {}
340 }
341 }
343
344 #(
346 {
347 let property_value_store = context.get_property_value_store::<E, T~N>();
348 entities.retain(
349 |entity|{
350 self.N == property_value_store.get(*entity)
351 }
352 );
353 }
354 )*
355 }
356 }
357 });
358 }
359}
360
361seq!(Z in 2..20 {
363 impl_query!(Z);
364});