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::multi_property::static_reorder_by_keys;
8use crate::entity::property::Property;
9use crate::entity::{ContextEntitiesExt, Entity, EntityId, HashValueType, Query};
10use crate::hashing::one_shot_128;
11use crate::Context;
12
13impl<E: Entity> Query<E> for () {
14 fn get_query(&self) -> Vec<(usize, HashValueType)> {
15 Vec::new()
16 }
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 multi_property_value_hash(&self) -> HashValueType {
27 let empty: &[u128] = &[];
28 one_shot_128(&empty)
29 }
30
31 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
32 EntitySet::from_source(SourceSet::Population(context.get_entity_count::<E>()))
33 }
34
35 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
36 EntitySetIterator::from_population_iterator(context.get_entity_iterator::<E>())
37 }
38
39 fn match_entity(&self, _entity_id: EntityId<E>, _context: &Context) -> bool {
40 true
42 }
43
44 fn filter_entities(&self, _entities: &mut Vec<EntityId<E>>, _context: &Context) {
45 }
47}
48
49impl<E: Entity + Copy> Query<E> for E {
52 fn get_query(&self) -> Vec<(usize, HashValueType)> {
53 Vec::new()
54 }
55
56 fn get_type_ids(&self) -> Vec<TypeId> {
57 Vec::new()
58 }
59
60 fn multi_property_id(&self) -> Option<usize> {
61 None
62 }
63
64 fn multi_property_value_hash(&self) -> HashValueType {
65 let empty: &[u128] = &[];
66 one_shot_128(&empty)
67 }
68
69 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
70 EntitySet::from_source(SourceSet::Population(context.get_entity_count::<E>()))
71 }
72
73 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
74 let population_iterator = context.get_entity_iterator::<E>();
75 EntitySetIterator::from_population_iterator(population_iterator)
76 }
77
78 fn match_entity(&self, _entity_id: EntityId<E>, _context: &Context) -> bool {
79 true
80 }
81
82 fn filter_entities(&self, _entities: &mut Vec<EntityId<E>>, _context: &Context) {
83 }
85}
86
87impl<E: Entity, P1: Property<E>> Query<E> for (P1,) {
89 fn get_query(&self) -> Vec<(usize, HashValueType)> {
90 let value = P1::make_canonical(self.0);
91 vec![(P1::id(), P1::hash_property_value(&value))]
92 }
93
94 fn get_type_ids(&self) -> Vec<TypeId> {
95 vec![P1::type_id()]
96 }
97
98 fn multi_property_id(&self) -> Option<usize> {
99 Some(P1::index_id())
102 }
103
104 fn multi_property_value_hash(&self) -> HashValueType {
105 P1::hash_property_value(&P1::make_canonical(self.0))
106 }
107
108 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
109 let property_store = context.entity_store.get_property_store::<E>();
110
111 if let Some(multi_property_id) = self.multi_property_id() {
116 match property_store.get_index_set_with_hash_for_property_id(
117 multi_property_id,
118 self.multi_property_value_hash(),
119 ) {
120 IndexSetResult::Set(people_set) => {
121 return EntitySet::from_source(SourceSet::IndexSet(people_set));
122 }
123 IndexSetResult::Empty => {
124 return EntitySet::empty();
125 }
126 IndexSetResult::Unsupported => {}
127 }
128 }
130
131 let mut sources: Vec<SourceSet<E>> = Vec::new();
133
134 if let Some(source_set) = SourceSet::new::<P1>(self.0, context) {
135 sources.push(source_set);
136 } else {
137 return EntitySet::empty();
139 }
140
141 EntitySet::from_intersection_sources(sources)
142 }
143
144 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
145 let property_store = context.entity_store.get_property_store::<E>();
148
149 if let Some(multi_property_id) = self.multi_property_id() {
150 match property_store.get_index_set_with_hash_for_property_id(
151 multi_property_id,
152 self.multi_property_value_hash(),
153 ) {
154 IndexSetResult::Set(people_set) => {
155 return EntitySetIterator::from_index_set(people_set);
156 }
157 IndexSetResult::Empty => {
158 return EntitySetIterator::empty();
159 }
160 IndexSetResult::Unsupported => {}
161 }
162 }
163
164 let mut sources: Vec<SourceSet<E>> = Vec::new();
165
166 if let Some(source_set) = SourceSet::new::<P1>(self.0, context) {
167 sources.push(source_set);
168 } else {
169 return EntitySetIterator::empty();
170 }
171
172 EntitySetIterator::from_sources(sources)
173 }
174
175 fn match_entity(&self, entity_id: EntityId<E>, context: &Context) -> bool {
176 let found_value: P1 = context.get_property(entity_id);
177 found_value == self.0
178 }
179
180 fn filter_entities(&self, entities: &mut Vec<EntityId<E>>, context: &Context) {
181 let property_value_store = context.get_property_value_store::<E, P1>();
182 entities.retain(|entity| self.0 == property_value_store.get(*entity));
183 }
184}
185
186macro_rules! impl_query {
187 ($ct:expr) => {
188 seq!(N in 0..$ct {
189 impl<
190 E: Entity,
191 #(
192 T~N : Property<E>,
193 )*
194 > Query<E> for (
195 #(
196 T~N,
197 )*
198 )
199 {
200 fn get_query(&self) -> Vec<(usize, HashValueType)> {
201 let mut ordered_items = vec![
202 #(
203 (T~N::id(), T~N::hash_property_value(&T~N::make_canonical(self.N))),
204 )*
205 ];
206 ordered_items.sort_unstable_by(|a, b| a.0.cmp(&b.0));
207 ordered_items
208 }
209
210 fn get_type_ids(&self) -> Vec<TypeId> {
211 vec![
212 #(
213 T~N::type_id(),
214 )*
215 ]
216 }
217
218 fn multi_property_value_hash(&self) -> HashValueType {
219 let keys: [&str; $ct] = [
232 #(
233 T~N::name(),
234 )*
235 ];
236 let mut values: [&Vec<u8>; $ct] = [
241 #(
242 &$crate::bincode::serde::encode_to_vec(self.N, bincode::config::standard()).unwrap(),
243 )*
244 ];
245 static_reorder_by_keys(&keys, &mut values);
246
247 let data = values.into_iter().flatten().copied().collect::<Vec<u8>>();
248 one_shot_128(&data.as_slice())
249 }
250
251 fn new_query_result<'c>(&self, context: &'c Context) -> EntitySet<'c, E> {
252 if let Some(multi_property_id) = self.multi_property_id() {
257 let property_store = context.entity_store.get_property_store::<E>();
258 match property_store.get_index_set_with_hash_for_property_id(
259 multi_property_id,
260 self.multi_property_value_hash(),
261 ) {
262 $crate::entity::index::IndexSetResult::Set(entity_set) => {
263 return EntitySet::from_source(SourceSet::IndexSet(entity_set));
264 }
265 $crate::entity::index::IndexSetResult::Empty => {
266 return EntitySet::empty();
267 }
268 $crate::entity::index::IndexSetResult::Unsupported => {}
269 }
270 }
272
273 let mut sources: Vec<SourceSet<E>> = Vec::new();
275
276 #(
277 if let Some(source_set) = SourceSet::new::<T~N>(self.N, context) {
278 sources.push(source_set);
279 } else {
280 return EntitySet::empty();
282 }
283 )*
284
285 EntitySet::from_intersection_sources(sources)
286 }
287
288 fn new_query_result_iterator<'c>(&self, context: &'c Context) -> EntitySetIterator<'c, E> {
289 if let Some(multi_property_id) = self.multi_property_id() {
292 let property_store = context.entity_store.get_property_store::<E>();
293 match property_store.get_index_set_with_hash_for_property_id(
294 multi_property_id,
295 self.multi_property_value_hash(),
296 ) {
297 $crate::entity::index::IndexSetResult::Set(entity_set) => {
298 return EntitySetIterator::from_index_set(entity_set);
299 }
300 $crate::entity::index::IndexSetResult::Empty => {
301 return EntitySetIterator::empty();
302 }
303 $crate::entity::index::IndexSetResult::Unsupported => {}
304 }
305 }
306
307 let mut sources: Vec<SourceSet<E>> = Vec::new();
308
309 #(
310 if let Some(source_set) = SourceSet::new::<T~N>(self.N, context) {
311 sources.push(source_set);
312 } else {
313 return EntitySetIterator::empty();
314 }
315 )*
316
317 EntitySetIterator::from_sources(sources)
318 }
319
320 fn match_entity(&self, entity_id: EntityId<E>, context: &Context) -> bool {
321 #(
322 {
323 let found_value: T~N = context.get_property(entity_id);
324 if found_value != self.N {
325 return false
326 }
327 }
328 )*
329 true
330 }
331
332 fn filter_entities(&self, entities: &mut Vec<EntityId<E>>, context: &Context) {
333 if let Some(multi_property_id) = self.multi_property_id() {
335 let property_store = context.entity_store.get_property_store::<E>();
336 match property_store.get_index_set_with_hash_for_property_id(
337 multi_property_id,
338 self.multi_property_value_hash(),
339 ) {
340 $crate::entity::index::IndexSetResult::Set(entity_set) => {
341 entities.retain(|entity_id| entity_set.contains(entity_id));
342 return;
343 }
344 $crate::entity::index::IndexSetResult::Empty => {
345 entities.clear();
346 return;
347 }
348 $crate::entity::index::IndexSetResult::Unsupported => {}
349 }
350 }
352
353 #(
355 {
356 let property_value_store = context.get_property_value_store::<E, T~N>();
357 entities.retain(
358 |entity|{
359 self.N == property_value_store.get(*entity)
360 }
361 );
362 }
363 )*
364 }
365 }
366 });
367 }
368}
369
370seq!(Z in 2..20 {
372 impl_query!(Z);
373});