1use std::ops::Deref;
3use std::{any::TypeId, marker::PhantomData};
4
5use any_vec::{traits::*, AnyVec};
6use moongraph::{Edges, GraphError, TypeKey, TypeMap, View};
7use parking_lot::{RwLockReadGuard, RwLockWriteGuard};
8use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
9
10use crate as apecs;
11use crate::storage::{
12 archetype::{Archetype, Components},
13 Entry,
14};
15
16use super::IsBundle;
17
18pub struct ComponentColumn<T>(PhantomData<T>);
21
22pub trait IsQuery {
25 type LockedColumns<'a>;
27 type ExtensionColumns: 'static;
30 type QueryResult<'a>: Iterator<Item = Self::QueryRow<'a>>;
32 type ParQueryResult<'a>: ParallelIterator<Item = Self::QueryRow<'a>> + IndexedParallelIterator;
35 type QueryRow<'a>: Send + Sync;
37
38 fn reads() -> Vec<TypeKey>;
39
40 fn writes() -> Vec<TypeKey>;
41
42 fn lock_columns<'a>(arch: &'a Archetype) -> Self::LockedColumns<'a>;
44
45 fn extend_locked_columns<'a, 'b>(
49 lock: &'b mut Self::LockedColumns<'a>,
50 extension_columns: Self::ExtensionColumns,
51 output_ids: Option<(&mut Vec<usize>, &mut usize)>,
52 );
53
54 fn iter_mut<'a, 'b>(lock: &'b mut Self::LockedColumns<'a>) -> Self::QueryResult<'b>;
56
57 fn iter_one<'a, 'b>(
59 lock: &'b mut Self::LockedColumns<'a>,
60 index: usize,
61 ) -> Self::QueryResult<'b>;
62
63 fn par_iter_mut<'a, 'b>(
65 len: usize,
66 lock: &'b mut Self::LockedColumns<'a>,
67 ) -> Self::ParQueryResult<'b>;
68}
69
70impl<'s, T: Send + Sync + 'static> IsQuery for &'s T {
71 type LockedColumns<'a> = Option<RwLockReadGuard<'a, AnyVec<dyn Send + Sync + 'static>>>;
72 type ExtensionColumns = ();
73 type QueryResult<'a> = std::slice::Iter<'a, Entry<T>>;
74 type ParQueryResult<'a> = rayon::slice::Iter<'a, Entry<T>>;
75 type QueryRow<'a> = &'a Entry<T>;
76
77 fn reads() -> Vec<TypeKey> {
78 vec![TypeKey::new::<ComponentColumn<T>>()]
79 }
80
81 fn writes() -> Vec<TypeKey> {
82 vec![]
83 }
84
85 #[inline]
86 fn lock_columns<'t>(arch: &'t Archetype) -> Self::LockedColumns<'t> {
87 let ty = TypeId::of::<Entry<T>>();
88 let i = arch.index_of(&ty)?;
89 let data = arch.data[i].read();
90 Some(data)
91 }
92
93 fn extend_locked_columns<'a, 'b>(
94 _: &'b mut Self::LockedColumns<'a>,
95 (): Self::ExtensionColumns,
96 _: Option<(&mut Vec<usize>, &mut usize)>,
97 ) {
98 panic!("cannot mutate a read-only lock");
99 }
100
101 #[inline]
102 fn iter_mut<'a, 'b>(locked: &'b mut Self::LockedColumns<'a>) -> Self::QueryResult<'b> {
103 locked.as_ref().map_or_else(
104 || (&[]).into_iter(),
105 |data| data.downcast_ref::<Entry<T>>().unwrap().into_iter(),
106 )
107 }
108
109 #[inline]
110 fn iter_one<'a, 'b>(
111 lock: &'b mut Self::LockedColumns<'a>,
112 index: usize,
113 ) -> Self::QueryResult<'b> {
114 lock.as_ref().map_or_else(
115 || (&[]).into_iter(),
116 |data| {
117 data.downcast_ref::<Entry<T>>()
118 .expect("can't downcast")
119 .as_slice()[index..=index]
120 .into_iter()
121 },
122 )
123 }
124
125 fn par_iter_mut<'a, 'b>(
127 _: usize,
128 lock: &'b mut Self::LockedColumns<'a>,
129 ) -> Self::ParQueryResult<'b> {
130 lock.as_ref().map_or_else(
131 || (&[]).into_par_iter(),
132 |data| {
133 data.downcast_ref::<Entry<T>>()
134 .expect("can't downcast")
135 .as_slice()
136 .into_par_iter()
137 },
138 )
139 }
140}
141
142impl<'s, T: Send + Sync + 'static> IsQuery for &'s mut T {
143 type LockedColumns<'a> = Option<RwLockWriteGuard<'a, AnyVec<dyn Send + Sync + 'static>>>;
144 type ExtensionColumns = Box<dyn Iterator<Item = Entry<T>>>;
145 type QueryResult<'a> = std::slice::IterMut<'a, Entry<T>>;
146 type ParQueryResult<'a> = rayon::slice::IterMut<'a, Entry<T>>;
147 type QueryRow<'a> = &'a mut Entry<T>;
148
149 fn reads() -> Vec<TypeKey> {
150 vec![]
151 }
152
153 fn writes() -> Vec<TypeKey> {
154 vec![TypeKey::new::<ComponentColumn<T>>()]
155 }
156
157 #[inline]
158 fn lock_columns<'t>(arch: &'t Archetype) -> Self::LockedColumns<'t> {
159 let ty = TypeId::of::<Entry<T>>();
160 let i = arch.index_of(&ty)?;
161 let data = arch.data[i].write();
162 Some(data)
163 }
164
165 fn extend_locked_columns<'a, 'b>(
166 lock: &'b mut Self::LockedColumns<'a>,
167 extension_columns: Self::ExtensionColumns,
168 output_ids: Option<(&mut Vec<usize>, &mut usize)>,
169 ) {
170 lock.as_mut().map(|guard| {
171 let mut vs = guard.downcast_mut::<Entry<T>>().expect("can't downcast");
172 let (lower, may_upper) = extension_columns.size_hint();
173 let additional = may_upper.unwrap_or(lower);
174 vs.reserve(additional);
175 if let Some((output_ids, max_id)) = output_ids {
176 for entry in extension_columns {
177 let id = entry.id();
178 *max_id = id.max(*max_id);
179 output_ids.push(id);
180 vs.push(entry);
181 }
182 } else {
183 for entry in extension_columns {
184 vs.push(entry);
185 }
186 }
187 });
188 }
189
190 #[inline]
191 fn iter_mut<'a, 'b>(locked: &'b mut Self::LockedColumns<'a>) -> Self::QueryResult<'b> {
192 locked.as_mut().map_or_else(
193 || (&mut []).into_iter(),
194 |data| {
195 data.downcast_mut::<Entry<T>>()
196 .expect("can't downcast")
197 .into_iter()
198 },
199 )
200 }
201
202 #[inline]
203 fn iter_one<'a, 'b>(
204 lock: &'b mut Self::LockedColumns<'a>,
205 index: usize,
206 ) -> Self::QueryResult<'b> {
207 lock.as_mut().map_or_else(
208 || (&mut []).into_iter(),
209 |data| {
210 (&mut data
211 .downcast_mut::<Entry<T>>()
212 .expect("can't downcast")
213 .as_mut_slice()[index..=index])
214 .into_iter()
215 },
216 )
217 }
218
219 fn par_iter_mut<'a, 'b>(
221 _: usize,
222 lock: &'b mut Self::LockedColumns<'a>,
223 ) -> Self::ParQueryResult<'b> {
224 lock.as_mut().map_or_else(
225 || (&mut []).into_par_iter(),
226 |data| {
227 data.downcast_mut::<Entry<T>>()
228 .expect("can't downcast")
229 .as_mut_slice()
230 .into_par_iter()
231 },
232 )
233 }
234}
235
236pub struct Maybe<T>(PhantomData<T>);
241
242impl<'s, T: Send + Sync + 'static> IsQuery for Maybe<&'s T> {
243 type LockedColumns<'a> = Option<RwLockReadGuard<'a, AnyVec<dyn Send + Sync + 'static>>>;
244 type ExtensionColumns = ();
245 type QueryResult<'a> = itertools::Either<
246 std::iter::RepeatWith<fn() -> Option<&'a Entry<T>>>,
247 std::iter::Map<
248 std::slice::Iter<'a, Entry<T>>,
249 for<'r> fn(&'r Entry<T>) -> Option<&'r Entry<T>>,
250 >,
251 >;
252 type ParQueryResult<'a> = rayon::iter::Either<
253 rayon::iter::Map<rayon::iter::RepeatN<()>, fn(()) -> Option<&'a Entry<T>>>,
254 rayon::iter::Map<
255 rayon::slice::Iter<'a, Entry<T>>,
256 for<'r> fn(&'r Entry<T>) -> Option<&'r Entry<T>>,
257 >,
258 >;
259 type QueryRow<'a> = Option<&'a Entry<T>>;
260
261 fn reads() -> Vec<TypeKey> {
262 <&T as IsQuery>::reads()
263 }
264
265 fn writes() -> Vec<TypeKey> {
266 <&T as IsQuery>::writes()
267 }
268
269 fn lock_columns<'a>(arch: &'a Archetype) -> Self::LockedColumns<'a> {
270 <&T as IsQuery>::lock_columns(arch)
271 }
272
273 fn extend_locked_columns<'a, 'b>(
274 _: &'b mut Self::LockedColumns<'a>,
275 _: Self::ExtensionColumns,
276 _: Option<(&mut Vec<usize>, &mut usize)>,
277 ) {
278 panic!("cannot extend Maybe columns");
279 }
280
281 fn iter_mut<'a, 'b>(lock: &'b mut Self::LockedColumns<'a>) -> Self::QueryResult<'b> {
282 lock.as_mut().map_or_else(
283 || {
284 itertools::Either::Left(std::iter::repeat_with(
285 (|| None) as fn() -> Option<&'a Entry<T>>,
286 ))
287 },
288 |data| {
289 itertools::Either::Right(
290 data.downcast_ref::<Entry<T>>()
291 .expect("can't downcast")
292 .into_iter()
293 .map((|e| Some(e)) as fn(&Entry<T>) -> Option<&Entry<T>>),
294 )
295 },
296 )
297 }
298
299 fn iter_one<'a, 'b>(
300 lock: &'b mut Self::LockedColumns<'a>,
301 index: usize,
302 ) -> Self::QueryResult<'b> {
303 lock.as_mut().map_or_else(
304 || {
305 itertools::Either::Left(std::iter::repeat_with(
306 (|| None) as fn() -> Option<&'b Entry<T>>,
307 ))
308 },
309 |data| {
310 itertools::Either::Right(
311 (&data
312 .downcast_ref::<Entry<T>>()
313 .expect("can't downcast")
314 .as_slice()[index..=index])
315 .into_iter()
316 .map((|e| Some(e)) as fn(&Entry<T>) -> Option<&Entry<T>>),
317 )
318 },
319 )
320 }
321
322 fn par_iter_mut<'a, 'b>(
323 len: usize,
324 lock: &'b mut Self::LockedColumns<'a>,
325 ) -> Self::ParQueryResult<'b> {
326 lock.as_mut().map_or_else(
327 || {
328 rayon::iter::Either::Left(
329 rayon::iter::repeatn((), len)
330 .map((|()| None) as fn(()) -> Option<&'a Entry<T>>),
331 )
332 },
333 |data| {
334 rayon::iter::Either::Right(
335 data.downcast_ref::<Entry<T>>()
336 .expect("can't downcast")
337 .as_slice()
338 .into_par_iter()
339 .map((|e| Some(e)) as fn(&Entry<T>) -> Option<&Entry<T>>),
340 )
341 },
342 )
343 }
344}
345
346impl<'s, T: Send + Sync + 'static> IsQuery for Maybe<&'s mut T> {
347 type LockedColumns<'a> = Option<RwLockWriteGuard<'a, AnyVec<dyn Send + Sync + 'static>>>;
348 type ExtensionColumns = ();
349 type QueryResult<'a> = itertools::Either<
350 std::iter::RepeatWith<fn() -> Option<&'a mut Entry<T>>>,
351 std::iter::Map<
352 std::slice::IterMut<'a, Entry<T>>,
353 for<'r> fn(&'r mut Entry<T>) -> Option<&'r mut Entry<T>>,
354 >,
355 >;
356 type ParQueryResult<'a> = rayon::iter::Either<
357 rayon::iter::Map<rayon::iter::RepeatN<()>, fn(()) -> Option<&'a mut Entry<T>>>,
358 rayon::iter::Map<
359 rayon::slice::IterMut<'a, Entry<T>>,
360 for<'r> fn(&'r mut Entry<T>) -> Option<&'r mut Entry<T>>,
361 >,
362 >;
363 type QueryRow<'a> = Option<&'a mut Entry<T>>;
364
365 fn reads() -> Vec<TypeKey> {
366 <&mut T as IsQuery>::reads()
367 }
368
369 fn writes() -> Vec<TypeKey> {
370 <&mut T as IsQuery>::writes()
371 }
372
373 fn lock_columns<'a>(arch: &'a Archetype) -> Self::LockedColumns<'a> {
374 <&mut T as IsQuery>::lock_columns(arch)
375 }
376
377 fn extend_locked_columns<'a, 'b>(
378 _: &'b mut Self::LockedColumns<'a>,
379 _: Self::ExtensionColumns,
380 _: Option<(&mut Vec<usize>, &mut usize)>,
381 ) {
382 panic!("cannot extend Maybe columns");
383 }
384
385 fn iter_mut<'a, 'b>(lock: &'b mut Self::LockedColumns<'a>) -> Self::QueryResult<'b> {
386 lock.as_mut().map_or_else(
387 || {
388 itertools::Either::Left(std::iter::repeat_with(
389 (|| None) as fn() -> Option<&'a mut Entry<T>>,
390 ))
391 },
392 |data| {
393 itertools::Either::Right(
394 data.downcast_mut::<Entry<T>>()
395 .expect("can't downcast")
396 .into_iter()
397 .map((|e| Some(e)) as fn(&mut Entry<T>) -> Option<&mut Entry<T>>),
398 )
399 },
400 )
401 }
402
403 fn iter_one<'a, 'b>(
404 lock: &'b mut Self::LockedColumns<'a>,
405 index: usize,
406 ) -> Self::QueryResult<'b> {
407 lock.as_mut().map_or_else(
408 || {
409 itertools::Either::Left(std::iter::repeat_with(
410 (|| None) as fn() -> Option<&'b mut Entry<T>>,
411 ))
412 },
413 |data| {
414 itertools::Either::Right(
415 (&mut data
416 .downcast_mut::<Entry<T>>()
417 .expect("can't downcast")
418 .as_mut_slice()[index..=index])
419 .into_iter()
420 .map((|e| Some(e)) as fn(&mut Entry<T>) -> Option<&mut Entry<T>>),
421 )
422 },
423 )
424 }
425
426 fn par_iter_mut<'a, 'b>(
427 len: usize,
428 lock: &'b mut Self::LockedColumns<'a>,
429 ) -> Self::ParQueryResult<'b> {
430 lock.as_mut().map_or_else(
431 || {
432 rayon::iter::Either::Left(
433 rayon::iter::repeatn((), len)
434 .map((|()| None) as fn(()) -> Option<&'a mut Entry<T>>),
435 )
436 },
437 |data| {
438 rayon::iter::Either::Right(
439 data.downcast_mut::<Entry<T>>()
440 .expect("can't downcast")
441 .as_mut_slice()
442 .into_par_iter()
443 .map((|e| Some(e)) as fn(&mut Entry<T>) -> Option<&mut Entry<T>>),
444 )
445 },
446 )
447 }
448}
449
450pub struct Without<T>(PhantomData<T>);
452
453impl<T: Send + Sync + 'static> IsQuery for Without<T> {
454 type LockedColumns<'a> = bool;
455 type ExtensionColumns = ();
456 type QueryResult<'a> = itertools::Either<std::iter::Repeat<()>, std::vec::IntoIter<()>>;
457 type ParQueryResult<'a> = rayon::iter::RepeatN<()>;
458 type QueryRow<'a> = ();
459
460 fn reads() -> Vec<TypeKey> {
461 <&T as IsQuery>::reads()
462 }
463
464 fn writes() -> Vec<TypeKey> {
465 <&T as IsQuery>::writes()
466 }
467
468 fn lock_columns<'a>(arch: &'a Archetype) -> Self::LockedColumns<'a> {
469 arch.has_component::<T>()
470 }
471
472 fn extend_locked_columns<'a, 'b>(
473 _: &'b mut Self::LockedColumns<'a>,
474 _: Self::ExtensionColumns,
475 _: Option<(&mut Vec<usize>, &mut usize)>,
476 ) {
477 panic!("cannot extend Without columns");
478 }
479
480 fn iter_mut<'a, 'b>(lock: &'b mut Self::LockedColumns<'a>) -> Self::QueryResult<'b> {
481 if *lock {
482 itertools::Either::Right(vec![].into_iter())
483 } else {
484 itertools::Either::Left(std::iter::repeat(()))
485 }
486 }
487
488 fn iter_one<'a, 'b>(lock: &'b mut Self::LockedColumns<'a>, _: usize) -> Self::QueryResult<'b> {
489 if *lock {
490 itertools::Either::Right(vec![].into_iter())
491 } else {
492 itertools::Either::Left(std::iter::repeat(()))
493 }
494 }
495
496 fn par_iter_mut<'a, 'b>(
497 len: usize,
498 lock: &'b mut Self::LockedColumns<'a>,
499 ) -> Self::ParQueryResult<'b> {
500 if *lock {
501 rayon::iter::repeatn((), 0)
502 } else {
503 rayon::iter::repeatn((), len)
504 }
505 }
506}
507
508impl<A> IsQuery for (A,)
509where
510 A: IsQuery,
511{
512 type LockedColumns<'a> = A::LockedColumns<'a>;
513 type ExtensionColumns = A::ExtensionColumns;
514 type QueryResult<'a> = A::QueryResult<'a>;
515 type ParQueryResult<'a> = A::ParQueryResult<'a>;
516 type QueryRow<'a> = A::QueryRow<'a>;
517
518 fn reads() -> Vec<TypeKey> {
519 A::reads()
520 }
521
522 fn writes() -> Vec<TypeKey> {
523 A::writes()
524 }
525
526 #[inline]
527 fn lock_columns<'t>(arch: &'t Archetype) -> Self::LockedColumns<'t> {
528 A::lock_columns(arch)
529 }
530
531 fn extend_locked_columns<'a, 'b>(
532 lock: &'b mut Self::LockedColumns<'a>,
533 ext: Self::ExtensionColumns,
534 output_ids: Option<(&mut Vec<usize>, &mut usize)>,
535 ) {
536 A::extend_locked_columns(lock, ext, output_ids);
537 }
538
539 #[inline]
540 fn iter_mut<'a, 'b>(lock: &'b mut Self::LockedColumns<'a>) -> Self::QueryResult<'b> {
541 A::iter_mut(lock)
542 }
543
544 fn iter_one<'a, 'b>(
545 lock: &'b mut Self::LockedColumns<'a>,
546 index: usize,
547 ) -> Self::QueryResult<'b> {
548 A::iter_one(lock, index)
549 }
550
551 fn par_iter_mut<'a, 'b>(
552 len: usize,
553 lock: &'b mut Self::LockedColumns<'a>,
554 ) -> Self::ParQueryResult<'b> {
555 A::par_iter_mut(len, lock)
556 }
557}
558
559impl<A, B> IsQuery for (A, B)
560where
561 A: IsQuery,
562 B: IsQuery,
563{
564 type LockedColumns<'a> = (A::LockedColumns<'a>, B::LockedColumns<'a>);
565 type ExtensionColumns = (A::ExtensionColumns, B::ExtensionColumns);
566 type QueryResult<'a> = std::iter::Zip<A::QueryResult<'a>, B::QueryResult<'a>>;
567 type ParQueryResult<'a> = rayon::iter::Zip<A::ParQueryResult<'a>, B::ParQueryResult<'a>>;
568 type QueryRow<'a> = (A::QueryRow<'a>, B::QueryRow<'a>);
569
570 fn reads() -> Vec<TypeKey> {
571 let mut bs = A::reads();
572 bs.extend(B::reads());
573 bs
574 }
575
576 fn writes() -> Vec<TypeKey> {
577 let mut bs = A::writes();
578 bs.extend(B::writes());
579 bs
580 }
581
582 #[inline]
583 fn lock_columns<'t>(arch: &'t Archetype) -> Self::LockedColumns<'t> {
584 let a = A::lock_columns(arch);
585 let b = B::lock_columns(arch);
586 (a, b)
587 }
588
589 fn extend_locked_columns<'a, 'b>(
590 (a, b): &'b mut Self::LockedColumns<'a>,
591 (ea, eb): Self::ExtensionColumns,
592 output_ids: Option<(&mut Vec<usize>, &mut usize)>,
593 ) {
594 A::extend_locked_columns(a, ea, output_ids);
595 B::extend_locked_columns(b, eb, None);
596 }
597
598 #[inline]
599 fn iter_mut<'a, 'b>((col_a, col_b): &'b mut Self::LockedColumns<'a>) -> Self::QueryResult<'b> {
600 A::iter_mut(col_a).zip(B::iter_mut(col_b))
601 }
602
603 fn iter_one<'a, 'b>(
604 (col_a, col_b): &'b mut Self::LockedColumns<'a>,
605 index: usize,
606 ) -> Self::QueryResult<'b> {
607 A::iter_one(col_a, index).zip(B::iter_one(col_b, index))
608 }
609
610 fn par_iter_mut<'a, 'b>(
611 len: usize,
612 (col_a, col_b): &'b mut Self::LockedColumns<'a>,
613 ) -> Self::ParQueryResult<'b> {
614 A::par_iter_mut(len, col_a).zip(B::par_iter_mut(len, col_b))
615 }
616}
617
618apecs_derive::impl_isquery_tuple!((A, B, C));
619apecs_derive::impl_isquery_tuple!((A, B, C, D));
620apecs_derive::impl_isquery_tuple!((A, B, C, D, E));
621apecs_derive::impl_isquery_tuple!((A, B, C, D, E, F));
622apecs_derive::impl_isquery_tuple!((A, B, C, D, E, F, G));
623apecs_derive::impl_isquery_tuple!((A, B, C, D, E, F, G, H));
624apecs_derive::impl_isquery_tuple!((A, B, C, D, E, F, G, H, I));
625apecs_derive::impl_isquery_tuple!((A, B, C, D, E, F, G, H, I, J));
626apecs_derive::impl_isquery_tuple!((A, B, C, D, E, F, G, H, I, J, K));
627apecs_derive::impl_isquery_tuple!((A, B, C, D, E, F, G, H, I, J, K, L));
628
629impl Components {
630 pub fn extend<B: IsBundle>(&mut self, extension: <B::MutBundle as IsQuery>::ExtensionColumns)
646 where
647 B::MutBundle: IsQuery,
648 {
649 let types = B::EntryBundle::ordered_types().unwrap();
650 let archetype_index;
651 let arch;
652 if let Some((i, a)) = self.get_archetype_mut(&types) {
653 archetype_index = i;
654 arch = a;
655 } else {
656 let new_arch = Archetype::new::<B>().unwrap();
657 archetype_index = self.archetypes.len();
658 self.archetypes.push(new_arch);
659 arch = &mut self.archetypes[archetype_index];
660 }
661 let mut index_lookup: Vec<usize> = vec![];
662 let mut max_id: usize = 0;
663 {
664 let mut lock = <B::MutBundle as IsQuery>::lock_columns(arch);
665 <B::MutBundle as IsQuery>::extend_locked_columns(
666 &mut lock,
667 extension,
668 Some((&mut index_lookup, &mut max_id)),
669 );
670 }
671 arch.index_lookup = index_lookup.clone();
672
673 if max_id >= self.entity_lookup.len() {
674 self.entity_lookup.resize_with(max_id + 1, Default::default);
675 }
676 index_lookup.iter().enumerate().for_each(|(i, id)| {
677 self.entity_lookup[*id] = Some((archetype_index, i));
678 });
679 }
680
681 pub fn query<Q: IsQuery + 'static>(&mut self) -> QueryGuard<'_, Q> {
695 QueryGuard(
696 self.archetypes.iter().map(|a| Q::lock_columns(a)).collect(),
697 self,
698 )
699 }
700}
701
702pub type QueryIter<'a, 'b, Q> = std::iter::FlatMap<
704 std::slice::IterMut<'b, <Q as IsQuery>::LockedColumns<'a>>,
705 <Q as IsQuery>::QueryResult<'b>,
706 for<'r> fn(&'r mut <Q as IsQuery>::LockedColumns<'a>) -> <Q as IsQuery>::QueryResult<'r>,
707>;
708
709pub struct QueryGuard<'a, Q: IsQuery + ?Sized>(Vec<Q::LockedColumns<'a>>, &'a Components);
713
714impl<'a, Q> QueryGuard<'a, Q>
715where
716 Q: IsQuery + ?Sized,
717{
718 pub fn iter_mut(&mut self) -> QueryIter<'a, '_, Q> {
723 self.0.iter_mut().flat_map(|cols| Q::iter_mut(cols))
724 }
725
726 pub fn find_one(&mut self, entity_id: usize) -> Option<Q::QueryRow<'_>> {
730 self.1
731 .entity_lookup
732 .get(entity_id)
733 .copied()
734 .and_then(|may_indices| {
735 let (archetype_index, component_index) = may_indices?;
736 let mut vs =
737 Q::iter_one(&mut self.0[archetype_index], component_index).collect::<Vec<_>>();
738 vs.pop()
739 })
740 }
741
742 pub fn par_iter_mut(
747 &mut self,
748 ) -> rayon::iter::Flatten<rayon::vec::IntoIter<<Q as IsQuery>::ParQueryResult<'_>>> {
749 let size_hints = self.1.archetypes.iter().map(|arch| arch.index_lookup.len());
750 size_hints
751 .zip(self.0.iter_mut())
752 .map(|(len, cols)| Q::par_iter_mut(len, cols))
753 .collect::<Vec<_>>()
754 .into_par_iter()
755 .flatten()
756 }
757}
758
759pub struct Query<T>(
870 Box<dyn Deref<Target = Components> + Send + Sync + 'static>,
871 PhantomData<T>,
872)
873where
874 T: IsQuery + ?Sized;
875
876impl<T> Edges for Query<T>
877where
878 T: IsQuery + Send + Sync + ?Sized,
879{
880 fn reads() -> Vec<TypeKey> {
881 let mut bs = <T as IsQuery>::reads();
882 bs.extend(View::<Components>::reads());
883 bs
884 }
885
886 fn writes() -> Vec<TypeKey> {
887 let mut bs = <T as IsQuery>::writes();
888 bs.extend(View::<Components>::writes());
889 bs
890 }
891
892 fn moves() -> Vec<TypeKey> {
893 vec![]
894 }
895
896 fn construct(loan_mngr: &mut TypeMap) -> Result<Self, GraphError> {
897 let all: View<Components> = View::construct(loan_mngr)?;
898 Ok(Query(Box::new(all), PhantomData))
899 }
900}
901
902impl<Q> Query<Q>
903where
904 Q: IsQuery + ?Sized,
905{
906 pub fn query(&self) -> QueryGuard<'_, Q> {
909 QueryGuard(
910 self.0
911 .archetypes
912 .iter()
913 .map(|a| Q::lock_columns(a))
914 .collect(),
915 &self.0,
916 )
917 }
918}
919
920pub type Ref<T> = &'static T;
922pub type Mut<T> = &'static mut T;
924pub type MaybeRef<T> = Maybe<&'static T>;
926pub type MaybeMut<T> = Maybe<&'static mut T>;
928
929#[cfg(test)]
930mod test {
931 use std::ops::DerefMut;
932
933 use super::*;
934
935 #[test]
936 fn can_query_all() {
937 let _ = env_logger::builder()
938 .is_test(true)
939 .filter_level(log::LevelFilter::Trace)
940 .try_init();
941
942 let mut all = Components::default();
943 all.insert_bundle(0, (0.0f32, true));
944 all.insert_bundle(1, (1.0f32, false, "hello"));
945 all.insert_bundle(2, (2.0f32, true, ()));
946 all.insert_bundle(3, (3.0f32, false));
947
948 let mut q = all.query::<&f32>();
949 let sum = q.iter_mut().fold(0.0f32, |sum, f| sum + **f);
950 assert_eq!(6.0, sum);
951 }
952
953 #[test]
954 fn iter_types() {
955 let _ = env_logger::builder()
956 .is_test(true)
957 .filter_level(log::LevelFilter::Trace)
958 .try_init();
959
960 println!("insert");
961 let mut store = Components::default();
962 store.insert_bundle(0, (0.0f32, "zero".to_string(), false));
963 store.insert_bundle(1, (1.0f32, "one".to_string(), false));
964 store.insert_bundle(2, (2.0f32, "two".to_string(), false));
965
966 {
967 println!("query 1");
968 let mut q = store.query::<&f32>();
969 let f32s = q.iter_mut().map(|f| **f).collect::<Vec<_>>();
970 let f32s_again = q.iter_mut().map(|f| **f).collect::<Vec<_>>();
971 assert_eq!(vec![0.0f32, 1.0, 2.0f32], f32s);
972 assert_eq!(vec![0.0f32, 1.0, 2.0f32], f32s_again);
973 }
974
975 {
976 println!("query 2");
977 let mut q = store.query::<(&mut bool, &f32)>();
978 let units: Vec<()> = q
979 .iter_mut()
980 .enumerate()
981 .map(|(i, (is_on, f))| {
982 **is_on = !**is_on;
983 assert!(**is_on);
984 assert!(**f as usize == i);
985 })
986 .collect::<Vec<_>>();
987 assert_eq!(3, units.len());
988 }
989
990 {
991 println!("query 3");
992 let mut q = store.query::<(&String, &mut bool, &mut f32)>();
993 println!("query 3 iteration");
994 q.iter_mut().for_each(|(s, is_on, f)| {
995 **is_on = true;
996 **f = s.len() as f32;
997 });
998 }
999
1000 println!("query 4");
1001 let mut q = store.query::<(&bool, &f32, &String)>();
1002 q.iter_mut().for_each(|(is_on, f, s)| {
1003 assert!(**is_on);
1004 assert_eq!(**f, s.len() as f32, "{}.len() != {}", **s, **f);
1005 });
1006 }
1007
1008 #[test]
1009 fn query_one() {
1010 let mut store = Components::default();
1011 store.insert_bundle(0, (0.0f32, "zero".to_string(), false));
1012 store.insert_bundle(1, (1.0f32, "one".to_string(), false));
1013 store.insert_bundle(2, (2.0f32, "two".to_string(), false));
1014
1015 {
1016 let mut q = store.query::<(&mut f32, &mut String, &bool)>();
1017 let (f, s, b) = q.find_one(1).unwrap();
1018 *f.deref_mut() = 666.0;
1019 **s = format!("blah {:?} {:?}", f.value(), b.value());
1020 }
1021
1022 let mut q = store.query::<(&f32, &String, &bool)>();
1023 let vs = q
1024 .iter_mut()
1025 .map(|(f, s, b)| (f.id(), **f, s.to_string(), **b))
1026 .collect::<Vec<_>>();
1027 assert_eq!(
1028 vec![
1029 (0usize, 0.0f32, "zero".to_string(), false,),
1030 (1, 666.0, "blah 666.0 false".to_string(), false,),
1031 (2, 2.0, "two".to_string(), false,),
1032 ],
1033 vs
1034 );
1035 }
1036
1037 #[test]
1038 fn sanity_query_iter() {
1039 let mut store = Components::default();
1040 store.insert_bundle(0, (0.0f32, "zero".to_string(), false));
1041 store.insert_bundle(1, (1.0f32, "one".to_string(), false));
1042 store.insert_bundle(2, (2.0f32, "two".to_string(), false));
1043
1044 type MyQuery<'a> = (&'a f32, &'a String, &'a bool);
1045 let mut locked = store
1046 .archetypes
1047 .iter()
1048 .map(|a| MyQuery::lock_columns(a))
1049 .collect::<Vec<_>>();
1050 let mut count = 0;
1051 let iter = locked.iter_mut().flat_map(|cols| MyQuery::iter_mut(cols));
1052 for (f, s, b) in iter {
1053 assert!(!**b, "{} {} {}", f.value(), s.value(), b.value());
1054 count += 1;
1055 }
1056 assert_eq!(3, count);
1057 }
1058
1059 #[test]
1060 fn can_query_maybe() {
1061 let mut components = Components::default();
1062 components.insert_bundle(0, (0.0f32, "zero".to_string()));
1063 components.insert_bundle(1, (1.0f32, "one".to_string(), false));
1064 components.insert_bundle(2, (2.0f32, "two".to_string()));
1065
1066 let cols = components
1067 .query::<(&f32, Maybe<&bool>, &String)>()
1068 .iter_mut()
1069 .map(|(f, mb, s)| (**f, mb.map(|b| **b), s.value().clone()))
1070 .collect::<Vec<_>>();
1071 assert_eq!(
1073 vec![
1074 (0.0, None, "zero".to_string()),
1075 (2.0, None, "two".to_string()),
1076 (1.0, Some(false), "one".to_string()),
1077 ],
1078 cols
1079 );
1080
1081 let par_cols = components
1082 .query::<(&f32, Maybe<&bool>, &String)>()
1083 .par_iter_mut()
1084 .map(|(f, mb, s)| (**f, mb.map(|b| **b), s.value().clone()))
1085 .collect::<Vec<_>>();
1086 assert_eq!(cols, par_cols);
1087 }
1088
1089 #[test]
1090 fn can_query_without() {
1091 let mut components = Components::default();
1092 components.insert_bundle(0, (0.0f32, "zero".to_string()));
1093 components.insert_bundle(1, (1.0f32, "one".to_string(), false));
1094 components.insert_bundle(2, (2.0f32, "two".to_string()));
1095
1096 let cols = components
1097 .query::<(&f32, Without<bool>, &String)>()
1098 .iter_mut()
1099 .map(|(f, (), s)| (**f, (), s.value().clone()))
1100 .collect::<Vec<_>>();
1101 assert_eq!(
1102 vec![(0.0, (), "zero".to_string()), (2.0, (), "two".to_string()),],
1103 cols
1104 );
1105
1106 let par_cols = components
1107 .query::<(&f32, Without<bool>, &String)>()
1108 .par_iter_mut()
1109 .map(|(f, (), s)| (**f, (), s.value().clone()))
1110 .collect::<Vec<_>>();
1111 assert_eq!(cols, par_cols);
1112 }
1113}