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