1use crate::index::ArchetypeIndex;
2use crate::index::ChunkIndex;
3use crate::index::SetIndex;
4use crate::iterator::FissileZip;
5use crate::iterator::SliceVecIter;
6use crate::storage::ArchetypeData;
7use crate::storage::ArchetypeId;
8use crate::storage::Component;
9use crate::storage::ComponentStorage;
10use crate::storage::ComponentTypeId;
11use crate::storage::ComponentTypes;
12use crate::storage::Storage;
13use crate::storage::Tag;
14use crate::storage::TagTypeId;
15use crate::storage::TagTypes;
16use std::iter::Enumerate;
17use std::iter::Repeat;
18use std::iter::Take;
19use std::marker::PhantomData;
20use std::slice::Iter;
21use std::sync::atomic::AtomicU64;
22use std::sync::atomic::Ordering;
23
24pub mod filter_fns {
25 use super::*;
27
28 pub fn passthrough() -> EntityFilterTuple<Passthrough, Passthrough, Passthrough> {
29 EntityFilterTuple::new(Passthrough, Passthrough, Passthrough)
30 }
31
32 pub fn any() -> EntityFilterTuple<Any, Any, Any> { EntityFilterTuple::new(Any, Any, Any) }
33
34 pub fn component<T: Component>(
37 ) -> EntityFilterTuple<ComponentFilter<T>, Passthrough, Passthrough> {
38 EntityFilterTuple::new(ComponentFilter::new(), Passthrough, Passthrough)
39 }
40
41 pub fn tag<T: Tag>() -> EntityFilterTuple<TagFilter<T>, Passthrough, Passthrough> {
44 EntityFilterTuple::new(TagFilter::new(), Passthrough, Passthrough)
45 }
46
47 pub fn tag_value<'a, T: Tag>(
50 data: &'a T,
51 ) -> EntityFilterTuple<TagFilter<T>, TagValueFilter<'a, T>, Passthrough> {
52 EntityFilterTuple::new(TagFilter::new(), TagValueFilter::new(data), Passthrough)
53 }
54
55 pub fn changed<T: Component>(
58 ) -> EntityFilterTuple<ComponentFilter<T>, Passthrough, ComponentChangedFilter<T>> {
59 EntityFilterTuple::new(
60 ComponentFilter::new(),
61 Passthrough,
62 ComponentChangedFilter::new(),
63 )
64 }
65}
66
67pub(crate) trait FilterResult {
68 fn coalesce_and(self, other: Self) -> Self;
69 fn coalesce_or(self, other: Self) -> Self;
70 fn is_pass(&self) -> bool;
71}
72
73impl FilterResult for Option<bool> {
74 #[inline]
75 fn coalesce_and(self, other: Self) -> Self {
76 match self {
77 Some(x) => other.map(|y| x && y).or(Some(x)),
78 None => other,
79 }
80 }
81
82 #[inline]
83 fn coalesce_or(self, other: Self) -> Self {
84 match self {
85 Some(x) => other.map(|y| x || y).or(Some(x)),
86 None => other,
87 }
88 }
89
90 #[inline]
91 fn is_pass(&self) -> bool { self.unwrap_or(true) }
92}
93
94pub trait Filter<T: Copy>: Send + Sync + Sized {
96 type Iter: Iterator + Send + Sync;
97
98 fn init(&self) {}
100
101 fn collect(&self, source: T) -> Self::Iter;
103
104 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool>;
106
107 fn matches(&mut self, source: T) -> FilterIter<Self, T> {
110 FilterIter {
111 elements: self.collect(source),
112 filter: self,
113 _phantom: PhantomData,
114 }
115 }
116}
117
118pub struct FilterIter<'a, F: Filter<T>, T: Copy> {
120 elements: <F as Filter<T>>::Iter,
121 filter: &'a mut F,
122 _phantom: PhantomData<T>,
123}
124
125impl<'a, F: Filter<T>, T: Copy> Iterator for FilterIter<'a, F, T> {
126 type Item = bool;
127
128 fn next(&mut self) -> Option<Self::Item> {
129 self.elements
130 .next()
131 .map(|x| self.filter.is_match(&x).is_pass())
132 }
133}
134
135impl<'a, F: Filter<T>, T: Copy + 'a> FilterIter<'a, F, T> {
136 pub fn matching_indices(self) -> impl Iterator<Item = usize> + 'a {
138 self.enumerate().filter(|(_, x)| *x).map(|(i, _)| i)
139 }
140}
141
142#[derive(Copy, Clone)]
144pub struct ArchetypeFilterData<'a> {
145 pub component_types: &'a ComponentTypes,
147 pub tag_types: &'a TagTypes,
149}
150
151#[derive(Copy, Clone)]
153pub struct ChunksetFilterData<'a> {
154 pub archetype_data: &'a ArchetypeData,
156}
157
158#[derive(Copy, Clone)]
160pub struct ChunkFilterData<'a> {
161 pub chunks: &'a [ComponentStorage],
163}
164
165pub trait ActiveFilter {}
167
168pub trait EntityFilter: Send + Clone {
170 type ArchetypeFilter: for<'a> Filter<ArchetypeFilterData<'a>> + Clone;
171 type ChunksetFilter: for<'a> Filter<ChunksetFilterData<'a>> + Clone;
172 type ChunkFilter: for<'a> Filter<ChunkFilterData<'a>> + Clone;
173
174 fn init(&self);
176
177 fn filters(
179 &self,
180 ) -> (
181 &Self::ArchetypeFilter,
182 &Self::ChunksetFilter,
183 &Self::ChunkFilter,
184 );
185
186 fn into_filters(
188 self,
189 ) -> (
190 Self::ArchetypeFilter,
191 Self::ChunksetFilter,
192 Self::ChunkFilter,
193 );
194
195 fn iter_archetype_indexes<'a, 'b>(
197 &'a self,
198 storage: &'b Storage,
199 ) -> FilterArchIter<'b, 'a, Self::ArchetypeFilter>;
200
201 fn iter_chunkset_indexes<'a, 'b>(
203 &'a self,
204 archetype: &'b ArchetypeData,
205 ) -> FilterChunkIter<'b, 'a, Self::ChunksetFilter>;
206
207 fn iter<'a, 'b>(
209 &'a self,
210 storage: &'b Storage,
211 ) -> FilterEntityIter<'b, 'a, Self::ArchetypeFilter, Self::ChunksetFilter>;
212}
213
214#[derive(Debug, Clone)]
216pub struct EntityFilterTuple<A, S, C> {
217 pub arch_filter: A,
218 pub chunkset_filter: S,
219 pub chunk_filter: C,
220}
221
222impl<A, S, C> EntityFilterTuple<A, S, C>
223where
224 A: for<'a> Filter<ArchetypeFilterData<'a>>,
225 S: for<'a> Filter<ChunksetFilterData<'a>>,
226 C: for<'a> Filter<ChunkFilterData<'a>>,
227{
228 pub fn new(arch_filter: A, chunkset_filter: S, chunk_filter: C) -> Self {
230 Self {
231 arch_filter,
232 chunkset_filter,
233 chunk_filter,
234 }
235 }
236}
237
238impl<A, S, C> EntityFilter for EntityFilterTuple<A, S, C>
239where
240 A: for<'a> Filter<ArchetypeFilterData<'a>> + Clone,
241 S: for<'a> Filter<ChunksetFilterData<'a>> + Clone,
242 C: for<'a> Filter<ChunkFilterData<'a>> + Clone,
243{
244 type ArchetypeFilter = A;
245 type ChunksetFilter = S;
246 type ChunkFilter = C;
247
248 fn init(&self) {
249 self.arch_filter.init();
250 self.chunkset_filter.init();
251 self.chunk_filter.init();
252 }
253
254 fn filters(
255 &self,
256 ) -> (
257 &Self::ArchetypeFilter,
258 &Self::ChunksetFilter,
259 &Self::ChunkFilter,
260 ) {
261 (&self.arch_filter, &self.chunkset_filter, &self.chunk_filter)
262 }
263
264 fn into_filters(
265 self,
266 ) -> (
267 Self::ArchetypeFilter,
268 Self::ChunksetFilter,
269 Self::ChunkFilter,
270 ) {
271 (self.arch_filter, self.chunkset_filter, self.chunk_filter)
272 }
273
274 fn iter_archetype_indexes<'a, 'b>(&'a self, storage: &'b Storage) -> FilterArchIter<'b, 'a, A> {
275 let data = ArchetypeFilterData {
276 component_types: storage.component_types(),
277 tag_types: storage.tag_types(),
278 };
279
280 let iter = self.arch_filter.collect(data);
281 FilterArchIter {
282 archetypes: iter.enumerate(),
283 filter: &self.arch_filter,
284 }
285 }
286
287 fn iter_chunkset_indexes<'a, 'b>(
288 &'a self,
289 archetype: &'b ArchetypeData,
290 ) -> FilterChunkIter<'b, 'a, S> {
291 let data = ChunksetFilterData {
292 archetype_data: archetype,
293 };
294
295 let iter = self.chunkset_filter.collect(data);
296 FilterChunkIter {
297 chunks: iter.enumerate(),
298 filter: &self.chunkset_filter,
299 }
300 }
301
302 fn iter<'a, 'b>(&'a self, storage: &'b Storage) -> FilterEntityIter<'b, 'a, A, S> {
303 let data = ArchetypeFilterData {
304 component_types: storage.component_types(),
305 tag_types: storage.tag_types(),
306 };
307
308 let iter = self.arch_filter.collect(data).enumerate();
309 FilterEntityIter {
310 storage,
311 arch_filter: &self.arch_filter,
312 chunk_filter: &self.chunkset_filter,
313 archetypes: iter,
314 chunks: None,
315 }
316 }
317}
318
319impl<A, S, C> std::ops::Not for EntityFilterTuple<A, S, C>
320where
321 A: std::ops::Not,
322 S: std::ops::Not,
323 C: std::ops::Not,
324{
325 type Output = EntityFilterTuple<A::Output, S::Output, C::Output>;
326
327 #[inline]
328 fn not(self) -> Self::Output {
329 EntityFilterTuple {
330 arch_filter: !self.arch_filter,
331 chunkset_filter: !self.chunkset_filter,
332 chunk_filter: !self.chunk_filter,
333 }
334 }
335}
336
337impl<'a, A1, S1, C1, A2, S2, C2> std::ops::BitAnd<EntityFilterTuple<A2, S2, C2>>
338 for EntityFilterTuple<A1, S1, C1>
339where
340 A1: std::ops::BitAnd<A2>,
341 S1: std::ops::BitAnd<S2>,
342 C1: std::ops::BitAnd<C2>,
343{
344 type Output = EntityFilterTuple<A1::Output, S1::Output, C1::Output>;
345
346 #[inline]
347 fn bitand(self, rhs: EntityFilterTuple<A2, S2, C2>) -> Self::Output {
348 EntityFilterTuple {
349 arch_filter: self.arch_filter & rhs.arch_filter,
350 chunkset_filter: self.chunkset_filter & rhs.chunkset_filter,
351 chunk_filter: self.chunk_filter & rhs.chunk_filter,
352 }
353 }
354}
355
356impl<'a, A1, S1, C1, A2, S2, C2> std::ops::BitOr<EntityFilterTuple<A2, S2, C2>>
357 for EntityFilterTuple<A1, S1, C1>
358where
359 A1: std::ops::BitOr<A2>,
360 S1: std::ops::BitOr<S2>,
361 C1: std::ops::BitOr<C2>,
362{
363 type Output = EntityFilterTuple<A1::Output, S1::Output, C1::Output>;
364
365 #[inline]
366 fn bitor(self, rhs: EntityFilterTuple<A2, S2, C2>) -> Self::Output {
367 EntityFilterTuple {
368 arch_filter: self.arch_filter | rhs.arch_filter,
369 chunkset_filter: self.chunkset_filter | rhs.chunkset_filter,
370 chunk_filter: self.chunk_filter | rhs.chunk_filter,
371 }
372 }
373}
374
375pub struct FilterArchIter<'a, 'b, F: Filter<ArchetypeFilterData<'a>>> {
377 filter: &'b F,
378 archetypes: Enumerate<F::Iter>,
379}
380
381impl<'a, 'b, F: Filter<ArchetypeFilterData<'a>>> Iterator for FilterArchIter<'a, 'b, F> {
382 type Item = ArchetypeIndex;
383
384 fn next(&mut self) -> Option<Self::Item> {
385 while let Some((i, data)) = self.archetypes.next() {
386 if self.filter.is_match(&data).is_pass() {
387 return Some(ArchetypeIndex(i));
388 }
389 }
390
391 None
392 }
393}
394
395pub struct FilterChunkIter<'a, 'b, F: Filter<ChunksetFilterData<'a>>> {
397 filter: &'b F,
398 chunks: Enumerate<F::Iter>,
399}
400
401impl<'a, 'b, F: Filter<ChunksetFilterData<'a>>> Iterator for FilterChunkIter<'a, 'b, F> {
402 type Item = SetIndex;
403
404 fn next(&mut self) -> Option<Self::Item> {
405 if let Some((i, data)) = self.chunks.next() {
406 if self.filter.is_match(&data).is_pass() {
407 return Some(SetIndex(i));
408 }
409 }
410
411 None
412 }
413}
414
415pub struct FilterEntityIter<
417 'a,
418 'b,
419 Arch: Filter<ArchetypeFilterData<'a>>,
420 Chunk: Filter<ChunksetFilterData<'a>>,
421> {
422 storage: &'a Storage,
423 arch_filter: &'b Arch,
424 chunk_filter: &'b Chunk,
425 archetypes: Enumerate<Arch::Iter>,
426 chunks: Option<(ArchetypeId, Enumerate<Chunk::Iter>)>,
427}
428
429impl<'a, 'b, Arch: Filter<ArchetypeFilterData<'a>>, Chunk: Filter<ChunksetFilterData<'a>>> Iterator
430 for FilterEntityIter<'a, 'b, Arch, Chunk>
431{
432 type Item = (ArchetypeId, ChunkIndex);
433
434 fn next(&mut self) -> Option<Self::Item> {
435 loop {
436 if let Some((arch_id, ref mut chunks)) = self.chunks {
437 for (chunk_index, chunk_data) in chunks {
438 if self.chunk_filter.is_match(&chunk_data).is_pass() {
439 return Some((arch_id, ChunkIndex(chunk_index)));
440 }
441 }
442 }
443 loop {
444 match self.archetypes.next() {
445 Some((arch_index, arch_data)) => {
446 if self.arch_filter.is_match(&arch_data).is_pass() {
447 self.chunks = {
448 let archetype =
449 unsafe { self.storage.archetypes().get_unchecked(arch_index) };
450 let data = ChunksetFilterData {
451 archetype_data: archetype,
452 };
453
454 Some((archetype.id(), self.chunk_filter.collect(data).enumerate()))
455 };
456 break;
457 }
458 }
459 None => return None,
460 }
461 }
462 }
463 }
464}
465
466#[derive(Debug, Clone)]
468pub struct Passthrough;
469
470impl<'a> Filter<ArchetypeFilterData<'a>> for Passthrough {
471 type Iter = Take<Repeat<()>>;
472
473 #[inline]
474 fn init(&self) {}
475
476 #[inline]
477 fn collect(&self, arch: ArchetypeFilterData<'a>) -> Self::Iter {
478 std::iter::repeat(()).take(arch.component_types.len())
479 }
480
481 #[inline]
482 fn is_match(&self, _: &<Self::Iter as Iterator>::Item) -> Option<bool> { None }
483}
484
485impl<'a> Filter<ChunksetFilterData<'a>> for Passthrough {
486 type Iter = Take<Repeat<()>>;
487
488 #[inline]
489 fn init(&self) {}
490
491 #[inline]
492 fn collect(&self, sets: ChunksetFilterData<'a>) -> Self::Iter {
493 std::iter::repeat(()).take(sets.archetype_data.len())
494 }
495
496 #[inline]
497 fn is_match(&self, _: &<Self::Iter as Iterator>::Item) -> Option<bool> { None }
498}
499
500impl<'a> Filter<ChunkFilterData<'a>> for Passthrough {
501 type Iter = Take<Repeat<()>>;
502
503 #[inline]
504 fn init(&self) {}
505
506 #[inline]
507 fn collect(&self, chunk: ChunkFilterData<'a>) -> Self::Iter {
508 std::iter::repeat(()).take(chunk.chunks.len())
509 }
510
511 #[inline]
512 fn is_match(&self, _: &<Self::Iter as Iterator>::Item) -> Option<bool> { None }
513}
514
515impl std::ops::Not for Passthrough {
516 type Output = Passthrough;
517
518 #[inline]
519 fn not(self) -> Self::Output { self }
520}
521
522impl<'a, Rhs> std::ops::BitAnd<Rhs> for Passthrough {
523 type Output = Rhs;
524
525 #[inline]
526 fn bitand(self, rhs: Rhs) -> Self::Output { rhs }
527}
528
529impl<'a, Rhs> std::ops::BitOr<Rhs> for Passthrough {
530 type Output = Rhs;
531
532 #[inline]
533 fn bitor(self, rhs: Rhs) -> Self::Output { rhs }
534}
535
536#[derive(Debug, Clone)]
537pub struct Any;
538
539impl ActiveFilter for Any {}
540
541impl<'a> Filter<ArchetypeFilterData<'a>> for Any {
542 type Iter = Take<Repeat<()>>;
543
544 #[inline]
545 fn init(&self) {}
546
547 #[inline]
548 fn collect(&self, arch: ArchetypeFilterData<'a>) -> Self::Iter {
549 std::iter::repeat(()).take(arch.component_types.len())
550 }
551
552 #[inline]
553 fn is_match(&self, _: &<Self::Iter as Iterator>::Item) -> Option<bool> { Some(true) }
554}
555
556impl<'a> Filter<ChunksetFilterData<'a>> for Any {
557 type Iter = Take<Repeat<()>>;
558
559 #[inline]
560 fn init(&self) {}
561
562 #[inline]
563 fn collect(&self, sets: ChunksetFilterData<'a>) -> Self::Iter {
564 std::iter::repeat(()).take(sets.archetype_data.len())
565 }
566
567 #[inline]
568 fn is_match(&self, _: &<Self::Iter as Iterator>::Item) -> Option<bool> { Some(true) }
569}
570
571impl<'a> Filter<ChunkFilterData<'a>> for Any {
572 type Iter = Take<Repeat<()>>;
573
574 #[inline]
575 fn init(&self) {}
576
577 #[inline]
578 fn collect(&self, chunk: ChunkFilterData<'a>) -> Self::Iter {
579 std::iter::repeat(()).take(chunk.chunks.len())
580 }
581
582 #[inline]
583 fn is_match(&self, _: &<Self::Iter as Iterator>::Item) -> Option<bool> { Some(true) }
584}
585
586impl<Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for Any {
587 type Output = Rhs;
588
589 #[inline]
590 fn bitand(self, rhs: Rhs) -> Self::Output { rhs }
591}
592
593impl std::ops::BitAnd<Passthrough> for Any {
594 type Output = Self;
595
596 #[inline]
597 fn bitand(self, _: Passthrough) -> Self::Output { self }
598}
599
600impl<Rhs: ActiveFilter> std::ops::BitOr<Rhs> for Any {
601 type Output = Self;
602
603 #[inline]
604 fn bitor(self, _: Rhs) -> Self::Output { self }
605}
606
607impl std::ops::BitOr<Passthrough> for Any {
608 type Output = Self;
609
610 #[inline]
611 fn bitor(self, _: Passthrough) -> Self::Output { self }
612}
613
614#[derive(Debug, Clone)]
616pub struct Not<F> {
617 pub filter: F,
618}
619
620impl<F> ActiveFilter for Not<F> {}
621
622impl<'a, T: Copy, F: Filter<T>> Filter<T> for Not<F> {
623 type Iter = F::Iter;
624
625 #[inline]
626 fn init(&self) { self.filter.init(); }
627
628 #[inline]
629 fn collect(&self, source: T) -> Self::Iter { self.filter.collect(source) }
630
631 #[inline]
632 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
633 self.filter.is_match(item).map(|x| !x)
634 }
635}
636
637impl<'a, F, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for Not<F> {
638 type Output = And<(Self, Rhs)>;
639
640 #[inline]
641 fn bitand(self, rhs: Rhs) -> Self::Output {
642 And {
643 filters: (self, rhs),
644 }
645 }
646}
647
648impl<'a, F> std::ops::BitAnd<Passthrough> for Not<F> {
649 type Output = Self;
650
651 #[inline]
652 fn bitand(self, _: Passthrough) -> Self::Output { self }
653}
654
655impl<'a, F, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for Not<F> {
656 type Output = Or<(Self, Rhs)>;
657
658 #[inline]
659 fn bitor(self, rhs: Rhs) -> Self::Output {
660 Or {
661 filters: (self, rhs),
662 }
663 }
664}
665
666impl<'a, F> std::ops::BitOr<Passthrough> for Not<F> {
667 type Output = Self;
668
669 #[inline]
670 fn bitor(self, _: Passthrough) -> Self::Output { self }
671}
672
673#[derive(Debug, Clone)]
675pub struct And<T> {
676 pub filters: T,
677}
678
679impl<T> ActiveFilter for And<(T,)> {}
680
681impl<'a, T: Copy, F: Filter<T>> Filter<T> for And<(F,)> {
682 type Iter = F::Iter;
683
684 #[inline]
685 fn init(&self) { self.filters.0.init(); }
686
687 #[inline]
688 fn collect(&self, source: T) -> Self::Iter { self.filters.0.collect(source) }
689
690 #[inline]
691 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
692 self.filters.0.is_match(item)
693 }
694}
695
696impl<T> std::ops::Not for And<(T,)> {
697 type Output = Not<Self>;
698
699 #[inline]
700 fn not(self) -> Self::Output { Not { filter: self } }
701}
702
703impl<T, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for And<(T,)> {
704 type Output = And<(T, Rhs)>;
705
706 #[inline]
707 fn bitand(self, rhs: Rhs) -> Self::Output {
708 And {
709 filters: (self.filters.0, rhs),
710 }
711 }
712}
713
714impl<T> std::ops::BitAnd<Passthrough> for And<(T,)> {
715 type Output = Self;
716
717 #[inline]
718 fn bitand(self, _: Passthrough) -> Self::Output { self }
719}
720
721impl<T, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for And<(T,)> {
722 type Output = Or<(Self, Rhs)>;
723
724 #[inline]
725 fn bitor(self, rhs: Rhs) -> Self::Output {
726 Or {
727 filters: (self, rhs),
728 }
729 }
730}
731
732impl<T> std::ops::BitOr<Passthrough> for And<(T,)> {
733 type Output = Self;
734
735 #[inline]
736 fn bitor(self, _: Passthrough) -> Self::Output { self }
737}
738
739macro_rules! recursive_zip {
740 (@value $first:expr, $($rest:expr),*) => { FissileZip::new($first, recursive_zip!(@value $($rest),*)) };
741 (@value $last:expr) => { $last };
742 (@type $first:ty, $($rest:ty),*) => { FissileZip<$first, recursive_zip!(@type $($rest),*)> };
743 (@type $last:ty) => { $last };
744 (@unzip $first:ident, $($rest:ident),*) => { ($first, recursive_zip!(@unzip $($rest),*)) };
745 (@unzip $last:ident) => { $last };
746}
747
748macro_rules! impl_and_filter {
749 ( $( $ty: ident => $ty2: ident ),* ) => {
750 impl<$( $ty ),*> ActiveFilter for And<($( $ty, )*)> {}
751
752 impl<'a, T: Copy, $( $ty: Filter<T> ),*> Filter<T> for And<($( $ty, )*)> {
753 type Iter = recursive_zip!(@type $($ty::Iter),*);
755
756 #[inline]
757 fn init(&self) {
758 #![allow(non_snake_case)]
759 let ($( $ty, )*) = &self.filters;
760 $( $ty.init(); )*
761 }
762
763 fn collect(&self, source: T) -> Self::Iter {
764 #![allow(non_snake_case)]
765 let ($( $ty, )*) = &self.filters;
766 recursive_zip!(@value $($ty.collect(source)),*)
771 }
772
773 #[inline]
774 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
775 #![allow(non_snake_case)]
776 let ($( $ty, )*) = &self.filters;
777 let recursive_zip!(@unzip $($ty2),*) = item;
779 let mut result: Option<bool> = None;
780 $( result = result.coalesce_and($ty.is_match($ty2)); )*
781 result
782 }
783 }
784
785 impl<$( $ty ),*> std::ops::Not for And<($( $ty, )*)> {
786 type Output = Not<Self>;
787
788 #[inline]
789 fn not(self) -> Self::Output {
790 Not { filter: self }
791 }
792 }
793
794 impl<$( $ty ),*, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for And<($( $ty, )*)> {
795 type Output = And<($( $ty, )* Rhs)>;
796
797 #[inline]
798 fn bitand(self, rhs: Rhs) -> Self::Output {
799 #![allow(non_snake_case)]
800 let ($( $ty, )*) = self.filters;
801 And {
802 filters: ($( $ty, )* rhs),
803 }
804 }
805 }
806
807 impl<$( $ty ),*> std::ops::BitAnd<Passthrough> for And<($( $ty, )*)> {
808 type Output = Self;
809
810 #[inline]
811 fn bitand(self, _: Passthrough) -> Self::Output {
812 self
813 }
814 }
815
816 impl<$( $ty ),*, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for And<($( $ty, )*)> {
817 type Output = Or<(Self, Rhs)>;
818
819 #[inline]
820 fn bitor(self, rhs: Rhs) -> Self::Output {
821 Or {
822 filters: (self, rhs),
823 }
824 }
825 }
826
827 impl<$( $ty ),*> std::ops::BitOr<Passthrough> for And<($( $ty, )*)> {
828 type Output = Self;
829
830 #[inline]
831 fn bitor(self, _: Passthrough) -> Self::Output {
832 self
833 }
834 }
835 }
836}
837
838impl_and_filter!(A => a, B => b);
839impl_and_filter!(A => a, B => b, C => c);
840impl_and_filter!(A => a, B => b, C => c, D => d);
841impl_and_filter!(A => a, B => b, C => c, D => d, E => e);
842impl_and_filter!(A => a, B => b, C => c, D => d, E => e, F => f);
843impl_and_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g);
844impl_and_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h);
845impl_and_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i);
846impl_and_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j);
847impl_and_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k);
848impl_and_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l);
849
850#[derive(Debug, Clone)]
852pub struct Or<T> {
853 pub filters: T,
854}
855
856macro_rules! impl_or_filter {
857 ( $( $ty: ident => $ty2: ident ),* ) => {
858 impl<$( $ty ),*> ActiveFilter for Or<($( $ty, )*)> {}
859
860 impl<'a, T: Copy, $( $ty: Filter<T> ),*> Filter<T> for Or<($( $ty, )*)> {
861 type Iter = recursive_zip!(@type $($ty::Iter),*);
863
864 #[inline]
865 fn init(&self) {
866 #![allow(non_snake_case)]
867 let ($( $ty, )*) = &self.filters;
868 $( $ty.init(); )*
869 }
870
871 fn collect(&self, source: T) -> Self::Iter {
872 #![allow(non_snake_case)]
873 let ($( $ty, )*) = &self.filters;
874 recursive_zip!(@value $($ty.collect(source)),*)
879 }
880
881 #[inline]
882 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
883 #![allow(non_snake_case)]
884 let ($( $ty, )*) = &self.filters;
885 let recursive_zip!(@unzip $($ty2),*) = item;
887 let mut result: Option<bool> = None;
888 $( result = result.coalesce_or($ty.is_match($ty2)); )*
889 result
890 }
891 }
892
893 impl<$( $ty ),*> std::ops::Not for Or<($( $ty, )*)> {
894 type Output = Not<Self>;
895
896 #[inline]
897 fn not(self) -> Self::Output {
898 Not { filter: self }
899 }
900 }
901
902 impl<$( $ty ),*, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for Or<($( $ty, )*)> {
903 type Output = And<(Self, Rhs)>;
904
905 #[inline]
906 fn bitand(self, rhs: Rhs) -> Self::Output {
907 And {
908 filters: (self, rhs),
909 }
910 }
911 }
912
913 impl<$( $ty ),*> std::ops::BitAnd<Passthrough> for Or<($( $ty, )*)> {
914 type Output = Self;
915
916 #[inline]
917 fn bitand(self, _: Passthrough) -> Self::Output {
918 self
919 }
920 }
921
922 impl<$( $ty ),*, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for Or<($( $ty, )*)> {
923 type Output = Or<($( $ty, )* Rhs)>;
924
925 #[inline]
926 fn bitor(self, rhs: Rhs) -> Self::Output {
927 #![allow(non_snake_case)]
928 let ($( $ty, )*) = self.filters;
929 Or {
930 filters: ($( $ty, )* rhs),
931 }
932 }
933 }
934
935 impl<$( $ty ),*> std::ops::BitOr<Passthrough> for Or<($( $ty, )*)> {
936 type Output = Self;
937
938 #[inline]
939 fn bitor(self, _: Passthrough) -> Self::Output {
940 self
941 }
942 }
943 }
944}
945
946impl_or_filter!(A => a, B => b);
947impl_or_filter!(A => a, B => b, C => c);
948impl_or_filter!(A => a, B => b, C => c, D => d);
949impl_or_filter!(A => a, B => b, C => c, D => d, E => e);
950impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f);
951impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g);
952impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h);
953impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i);
954impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j);
955impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k);
956impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l);
957
958#[derive(Debug)]
960pub struct ComponentFilter<T>(PhantomData<T>);
961
962impl<T: Component> ComponentFilter<T> {
963 fn new() -> Self { ComponentFilter(PhantomData) }
964}
965
966impl<T> ActiveFilter for ComponentFilter<T> {}
967
968impl<T> Copy for ComponentFilter<T> {}
969impl<T> Clone for ComponentFilter<T> {
970 fn clone(&self) -> Self { *self }
971}
972
973impl<'a, T: Component> Filter<ArchetypeFilterData<'a>> for ComponentFilter<T> {
974 type Iter = SliceVecIter<'a, ComponentTypeId>;
975
976 #[inline]
977 fn init(&self) {}
978
979 #[inline]
980 fn collect(&self, source: ArchetypeFilterData<'a>) -> Self::Iter {
981 source.component_types.iter()
982 }
983
984 #[inline]
985 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
986 Some(item.contains(&ComponentTypeId::of::<T>()))
987 }
988}
989
990impl<T> std::ops::Not for ComponentFilter<T> {
991 type Output = Not<Self>;
992
993 #[inline]
994 fn not(self) -> Self::Output { Not { filter: self } }
995}
996
997impl<'a, T, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for ComponentFilter<T> {
998 type Output = And<(Self, Rhs)>;
999
1000 #[inline]
1001 fn bitand(self, rhs: Rhs) -> Self::Output {
1002 And {
1003 filters: (self, rhs),
1004 }
1005 }
1006}
1007
1008impl<'a, T> std::ops::BitAnd<Passthrough> for ComponentFilter<T> {
1009 type Output = Self;
1010
1011 #[inline]
1012 fn bitand(self, _: Passthrough) -> Self::Output { self }
1013}
1014
1015impl<'a, T, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for ComponentFilter<T> {
1016 type Output = Or<(Self, Rhs)>;
1017
1018 #[inline]
1019 fn bitor(self, rhs: Rhs) -> Self::Output {
1020 Or {
1021 filters: (self, rhs),
1022 }
1023 }
1024}
1025
1026impl<'a, T> std::ops::BitOr<Passthrough> for ComponentFilter<T> {
1027 type Output = Self;
1028
1029 #[inline]
1030 fn bitor(self, _: Passthrough) -> Self::Output { self }
1031}
1032
1033#[derive(Debug)]
1035pub struct TagFilter<T>(PhantomData<T>);
1036
1037impl<T: Tag> TagFilter<T> {
1038 fn new() -> Self { TagFilter(PhantomData) }
1039}
1040
1041impl<T> ActiveFilter for TagFilter<T> {}
1042
1043impl<T> Copy for TagFilter<T> {}
1044impl<T> Clone for TagFilter<T> {
1045 fn clone(&self) -> Self { *self }
1046}
1047
1048impl<'a, T: Tag> Filter<ArchetypeFilterData<'a>> for TagFilter<T> {
1049 type Iter = SliceVecIter<'a, TagTypeId>;
1050
1051 #[inline]
1052 fn init(&self) {}
1053
1054 #[inline]
1055 fn collect(&self, source: ArchetypeFilterData<'a>) -> Self::Iter { source.tag_types.iter() }
1056
1057 #[inline]
1058 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1059 Some(item.contains(&TagTypeId::of::<T>()))
1060 }
1061}
1062
1063impl<T> std::ops::Not for TagFilter<T> {
1064 type Output = Not<Self>;
1065
1066 #[inline]
1067 fn not(self) -> Self::Output { Not { filter: self } }
1068}
1069
1070impl<'a, T, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for TagFilter<T> {
1071 type Output = And<(Self, Rhs)>;
1072
1073 #[inline]
1074 fn bitand(self, rhs: Rhs) -> Self::Output {
1075 And {
1076 filters: (self, rhs),
1077 }
1078 }
1079}
1080
1081impl<'a, T> std::ops::BitAnd<Passthrough> for TagFilter<T> {
1082 type Output = Self;
1083
1084 #[inline]
1085 fn bitand(self, _: Passthrough) -> Self::Output { self }
1086}
1087
1088impl<'a, T, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for TagFilter<T> {
1089 type Output = Or<(Self, Rhs)>;
1090
1091 #[inline]
1092 fn bitor(self, rhs: Rhs) -> Self::Output {
1093 Or {
1094 filters: (self, rhs),
1095 }
1096 }
1097}
1098
1099impl<'a, T> std::ops::BitOr<Passthrough> for TagFilter<T> {
1100 type Output = Self;
1101
1102 #[inline]
1103 fn bitor(self, _: Passthrough) -> Self::Output { self }
1104}
1105
1106#[derive(Debug)]
1108pub struct TagValueFilter<'a, T> {
1109 value: &'a T,
1110}
1111
1112impl<'a, T: Tag> TagValueFilter<'a, T> {
1113 fn new(value: &'a T) -> Self { TagValueFilter { value } }
1114}
1115
1116impl<'a, T> ActiveFilter for TagValueFilter<'a, T> {}
1117
1118impl<'a, T> Copy for TagValueFilter<'a, T> {}
1119impl<'a, T> Clone for TagValueFilter<'a, T> {
1120 fn clone(&self) -> Self { *self }
1121}
1122
1123impl<'a, 'b, T: Tag> Filter<ChunksetFilterData<'a>> for TagValueFilter<'b, T> {
1124 type Iter = Iter<'a, T>;
1125
1126 #[inline]
1127 fn init(&self) {}
1128
1129 fn collect(&self, source: ChunksetFilterData<'a>) -> Self::Iter {
1130 unsafe {
1131 source
1132 .archetype_data
1133 .tags()
1134 .get(TagTypeId::of::<T>())
1135 .unwrap()
1136 .data_slice::<T>()
1137 .iter()
1138 }
1139 }
1140
1141 #[inline]
1142 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1143 Some(**item == *self.value)
1144 }
1145}
1146
1147impl<'a, T> std::ops::Not for TagValueFilter<'a, T> {
1148 type Output = Not<Self>;
1149
1150 #[inline]
1151 fn not(self) -> Self::Output { Not { filter: self } }
1152}
1153
1154impl<'a, T, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for TagValueFilter<'a, T> {
1155 type Output = And<(Self, Rhs)>;
1156
1157 #[inline]
1158 fn bitand(self, rhs: Rhs) -> Self::Output {
1159 And {
1160 filters: (self, rhs),
1161 }
1162 }
1163}
1164
1165impl<'a, T> std::ops::BitAnd<Passthrough> for TagValueFilter<'a, T> {
1166 type Output = Self;
1167
1168 #[inline]
1169 fn bitand(self, _: Passthrough) -> Self::Output { self }
1170}
1171
1172impl<'a, T, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for TagValueFilter<'a, T> {
1173 type Output = Or<(Self, Rhs)>;
1174
1175 #[inline]
1176 fn bitor(self, rhs: Rhs) -> Self::Output {
1177 Or {
1178 filters: (self, rhs),
1179 }
1180 }
1181}
1182
1183impl<'a, T> std::ops::BitOr<Passthrough> for TagValueFilter<'a, T> {
1184 type Output = Self;
1185
1186 #[inline]
1187 fn bitor(self, _: Passthrough) -> Self::Output { self }
1188}
1189
1190#[derive(Debug)]
1193pub struct ComponentChangedFilter<T: Component> {
1194 high_water_mark: AtomicU64,
1195 version_threshold: AtomicU64,
1196 phantom: PhantomData<T>,
1197}
1198
1199impl<T: Component> ComponentChangedFilter<T> {
1200 fn new() -> ComponentChangedFilter<T> {
1201 ComponentChangedFilter {
1202 high_water_mark: AtomicU64::new(0),
1203 version_threshold: AtomicU64::new(0),
1204 phantom: PhantomData,
1205 }
1206 }
1207}
1208
1209impl<T: Component> ActiveFilter for ComponentChangedFilter<T> {}
1210
1211impl<T: Component> Clone for ComponentChangedFilter<T> {
1212 fn clone(&self) -> Self {
1213 Self {
1214 high_water_mark: AtomicU64::new(self.high_water_mark.load(Ordering::Relaxed)),
1215 version_threshold: AtomicU64::new(self.version_threshold.load(Ordering::Relaxed)),
1216 phantom: PhantomData,
1217 }
1218 }
1219}
1220
1221impl<'a, T: Component> Filter<ChunkFilterData<'a>> for ComponentChangedFilter<T> {
1222 type Iter = ComponentChangedState<'a, ComponentStorage>;
1223
1224 #[inline]
1225 fn init(&self) {
1226 let version = self.high_water_mark.load(Ordering::Relaxed);
1227 let mut threshold = self.version_threshold.load(Ordering::Relaxed);
1228 if threshold < version {
1229 loop {
1230 match self.version_threshold.compare_exchange_weak(
1231 threshold,
1232 version,
1233 Ordering::Relaxed,
1234 Ordering::Relaxed,
1235 ) {
1236 Ok(_) => break,
1237 Err(stored_last_read) => {
1238 threshold = stored_last_read;
1239 if threshold >= version {
1240 break;
1242 }
1243 }
1244 }
1245 }
1246 }
1247 }
1248
1249 fn collect(&self, source: ChunkFilterData<'a>) -> Self::Iter {
1250 let compare_version = self.version_threshold.load(Ordering::Relaxed);
1251 ComponentChangedState {
1252 iter: source.chunks.iter(),
1253 version_threshold: compare_version,
1254 }
1255 }
1256
1257 #[inline]
1258 fn is_match(&self, item: &<Self::Iter as Iterator>::Item) -> Option<bool> {
1259 let (version_threshold, storage) = item;
1260
1261 let components = storage.components(ComponentTypeId::of::<T>());
1262 if components.is_none() {
1263 return Some(false);
1264 }
1265
1266 let version = components.unwrap().version();
1267 let mut last_read = self.high_water_mark.load(Ordering::Relaxed);
1268 if last_read < version {
1269 loop {
1270 match self.high_water_mark.compare_exchange_weak(
1271 last_read,
1272 version,
1273 Ordering::Relaxed,
1274 Ordering::Relaxed,
1275 ) {
1276 Ok(_) => break,
1277 Err(stored_last_read) => {
1278 last_read = stored_last_read;
1279 if last_read >= version {
1280 break;
1282 }
1283 }
1284 }
1285 }
1286 }
1287
1288 if version > *version_threshold {
1289 Some(true)
1290 } else {
1291 Some(false)
1292 }
1293 }
1294}
1295
1296pub struct ComponentChangedState<'a, T: Component> {
1297 iter: Iter<'a, T>,
1298 version_threshold: u64,
1299}
1300
1301impl<'a, T: Component> Iterator for ComponentChangedState<'a, T> {
1302 type Item = (u64, &'a T);
1303
1304 fn next(&mut self) -> Option<Self::Item> {
1305 self.iter.next().map(|c| (self.version_threshold, c))
1306 }
1307}
1308
1309impl<'a, T: Component> std::ops::Not for ComponentChangedFilter<T> {
1310 type Output = Not<Self>;
1311
1312 #[inline]
1313 fn not(self) -> Self::Output { Not { filter: self } }
1314}
1315
1316impl<'a, T: Component, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for ComponentChangedFilter<T> {
1317 type Output = And<(Self, Rhs)>;
1318
1319 #[inline]
1320 fn bitand(self, rhs: Rhs) -> Self::Output {
1321 And {
1322 filters: (self, rhs),
1323 }
1324 }
1325}
1326
1327impl<'a, T: Component> std::ops::BitAnd<Passthrough> for ComponentChangedFilter<T> {
1328 type Output = Self;
1329
1330 #[inline]
1331 fn bitand(self, _: Passthrough) -> Self::Output { self }
1332}
1333
1334impl<'a, T: Component, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for ComponentChangedFilter<T> {
1335 type Output = Or<(Self, Rhs)>;
1336
1337 #[inline]
1338 fn bitor(self, rhs: Rhs) -> Self::Output {
1339 Or {
1340 filters: (self, rhs),
1341 }
1342 }
1343}
1344
1345impl<'a, T: Component> std::ops::BitOr<Passthrough> for ComponentChangedFilter<T> {
1346 type Output = Self;
1347
1348 #[inline]
1349 fn bitor(self, _: Passthrough) -> Self::Output { self }
1350}
1351
1352#[cfg(test)]
1353mod test {
1354 use super::filter_fns::*;
1355 use crate::prelude::*;
1356
1357 #[test]
1358 pub fn create() {
1359 let _ = tracing_subscriber::fmt::try_init();
1360
1361 let filter = component::<usize>() | tag_value(&5isize);
1362 tracing::trace!(?filter);
1363 }
1364
1365 #[test]
1366 fn component_changed_filter() {
1367 let _ = tracing_subscriber::fmt::try_init();
1368
1369 let universe = Universe::new();
1370 let mut world = universe.create_world();
1371
1372 let entity1 = world.insert((), vec![(1usize,)])[0];
1373 let entity2 = world.insert((), vec![(2usize, false)])[0];
1374
1375 let query = <Read<usize>>::query().filter(changed::<usize>());
1376
1377 assert_eq!(2, query.iter_chunks(&world).collect::<Vec<_>>().len());
1378
1379 *world.get_component_mut::<usize>(entity1).unwrap() = 3usize;
1380
1381 assert_eq!(1, query.iter_chunks(&world).collect::<Vec<_>>().len());
1382
1383 *world.get_component_mut::<usize>(entity1).unwrap() = 4usize;
1384 *world.get_component_mut::<usize>(entity2).unwrap() = 5usize;
1385
1386 assert_eq!(2, query.iter_chunks(&world).collect::<Vec<_>>().len());
1387
1388 *world.get_component_mut::<usize>(entity1).unwrap() = 6usize;
1389 *world.get_component_mut::<usize>(entity1).unwrap() = 7usize;
1390 *world.get_component_mut::<usize>(entity2).unwrap() = 8usize;
1391
1392 assert_eq!(2, query.iter_chunks(&world).collect::<Vec<_>>().len());
1393
1394 *world.get_component_mut::<usize>(entity2).unwrap() = 6usize;
1395 *world.get_component_mut::<usize>(entity2).unwrap() = 7usize;
1396 *world.get_component_mut::<usize>(entity1).unwrap() = 8usize;
1397
1398 assert_eq!(2, query.iter_chunks(&world).collect::<Vec<_>>().len());
1399 }
1400}