1use crate::borrow::RefIter;
2use crate::borrow::RefIterMut;
3use crate::borrow::RefMap;
4use crate::borrow::RefMapMut;
5use crate::borrow::RefMapMutSet;
6use crate::borrow::RefMapSet;
7use crate::borrow::TryRefIter;
8use crate::borrow::TryRefIterMut;
9use crate::entity::Entity;
10use crate::filter::And;
11use crate::filter::ArchetypeFilterData;
12use crate::filter::ChunkFilterData;
13use crate::filter::ChunksetFilterData;
14use crate::filter::ComponentFilter;
15use crate::filter::EntityFilter;
16use crate::filter::EntityFilterTuple;
17use crate::filter::Filter;
18use crate::filter::FilterResult;
19use crate::filter::Passthrough;
20use crate::filter::TagFilter;
21use crate::index::ChunkIndex;
22use crate::index::{ArchetypeIndex, SetIndex};
23#[cfg(feature = "par-iter")]
24use crate::iterator::{FissileEnumerate, FissileIterator};
25use crate::storage::ArchetypeData;
26use crate::storage::Component;
27use crate::storage::ComponentStorage;
28use crate::storage::ComponentTypeId;
29use crate::storage::Tag;
30use crate::storage::TagTypeId;
31use crate::subworld::{ComponentAccess, StorageAccessor};
32use crate::{permission::Permissions, world::EntityStore};
33use derivative::Derivative;
34use std::any::TypeId;
35use std::iter::Enumerate;
36use std::iter::Repeat;
37use std::iter::Take;
38use std::marker::PhantomData;
39use std::slice::Iter;
40use std::slice::IterMut;
41
42#[cfg(feature = "par-iter")]
43use rayon::{
44 iter::plumbing::{bridge_unindexed, Folder, UnindexedConsumer, UnindexedProducer},
45 prelude::*,
46};
47
48pub trait View<'a>: Sized + Send + Sync + 'static {
51 type Iter: Iterator + 'a;
53
54 fn fetch(
56 archetype: &'a ArchetypeData,
57 chunk: &'a ComponentStorage,
58 chunk_index: ChunkIndex,
59 set_index: SetIndex,
60 ) -> Self::Iter;
61
62 fn validate() -> bool;
64
65 fn validate_access(access: &ComponentAccess) -> bool;
67
68 fn reads<T: Component>() -> bool;
70
71 fn writes<T: Component>() -> bool;
73
74 fn requires_permissions() -> Permissions<ComponentTypeId>;
76}
77
78pub trait DefaultFilter {
80 type Filter: EntityFilter;
82
83 fn filter() -> Self::Filter;
85}
86
87#[doc(hidden)]
88pub trait ReadOnly {}
89
90#[doc(hidden)]
91pub trait ViewElement {
92 type Component;
93}
94
95pub trait IntoQuery: DefaultFilter + for<'a> View<'a> {
97 fn query() -> Query<Self, <Self as DefaultFilter>::Filter>;
99}
100
101impl<T: DefaultFilter + for<'a> View<'a>> IntoQuery for T {
102 fn query() -> Query<Self, <Self as DefaultFilter>::Filter> {
103 if !Self::validate() {
104 panic!("invalid view, please ensure the view contains no duplicate component types");
105 }
106
107 Query {
108 view: PhantomData,
109 filter: Self::filter(),
110 }
111 }
112}
113
114#[derive(Derivative, Debug)]
116#[derivative(Default(bound = ""))]
117pub struct Read<T: Component>(PhantomData<T>);
118
119impl<T: Component> ReadOnly for Read<T> {}
120impl<T: Component> Copy for Read<T> {}
121impl<T: Component> Clone for Read<T> {
122 fn clone(&self) -> Self { *self }
123}
124
125impl<'a, T: Component> DefaultFilter for Read<T> {
126 type Filter = EntityFilterTuple<ComponentFilter<T>, Passthrough, Passthrough>;
127
128 fn filter() -> Self::Filter { super::filter::filter_fns::component() }
129}
130
131impl<'a, T: Component> View<'a> for Read<T> {
132 type Iter = RefIter<'a, T, Iter<'a, T>>;
133
134 fn fetch(
135 _: &'a ArchetypeData,
136 chunk: &'a ComponentStorage,
137 _: ChunkIndex,
138 _: SetIndex,
139 ) -> Self::Iter {
140 let (slice_borrow, slice) = unsafe {
141 chunk
142 .components(ComponentTypeId::of::<T>())
143 .unwrap_or_else(|| {
144 panic!(
145 "Component of type {:?} not found in chunk when fetching Read view",
146 std::any::type_name::<T>()
147 )
148 })
149 .data_slice::<T>()
150 .deconstruct()
151 };
152 RefIter::new(slice_borrow, slice.iter())
153 }
154
155 fn validate() -> bool { true }
156
157 fn reads<D: Component>() -> bool { TypeId::of::<T>() == TypeId::of::<D>() }
158
159 fn writes<D: Component>() -> bool { false }
160
161 fn validate_access(access: &ComponentAccess) -> bool {
162 access.allows_read(ComponentTypeId::of::<T>())
163 }
164
165 fn requires_permissions() -> Permissions<ComponentTypeId> {
166 let mut permissions = Permissions::new();
167 permissions.push_read(ComponentTypeId::of::<T>());
168 permissions
169 }
170}
171
172impl<T: Component> ViewElement for Read<T> {
173 type Component = T;
174}
175
176#[derive(Derivative, Debug)]
178#[derivative(Default(bound = ""))]
179pub struct TryRead<T: Component>(PhantomData<T>);
180
181impl<T: Component> ReadOnly for TryRead<T> {}
182
183impl<T: Component> Copy for TryRead<T> {}
184impl<T: Component> Clone for TryRead<T> {
185 fn clone(&self) -> Self { *self }
186}
187
188impl<'a, T: Component> DefaultFilter for TryRead<T> {
189 type Filter = EntityFilterTuple<Passthrough, Passthrough, Passthrough>;
190
191 fn filter() -> Self::Filter { super::filter::filter_fns::passthrough() }
192}
193
194impl<'a, T: Component> View<'a> for TryRead<T> {
195 type Iter = TryRefIter<'a, T, Iter<'a, T>>;
196
197 fn fetch(
198 _: &'a ArchetypeData,
199 chunk: &'a ComponentStorage,
200 _: ChunkIndex,
201 _: SetIndex,
202 ) -> Self::Iter {
203 unsafe {
204 chunk
205 .components(ComponentTypeId::of::<T>())
206 .map(|x| {
207 let (borrow, slice) = x.data_slice::<T>().deconstruct();
208 TryRefIter::found(borrow, slice.iter())
209 })
210 .unwrap_or_else(|| TryRefIter::missing(chunk.len()))
211 }
212 }
213
214 fn validate() -> bool { true }
215
216 fn reads<D: Component>() -> bool { TypeId::of::<T>() == TypeId::of::<D>() }
217
218 fn writes<D: Component>() -> bool { false }
219
220 fn requires_permissions() -> Permissions<ComponentTypeId> {
221 let mut permissions = Permissions::new();
222 permissions.push_read(ComponentTypeId::of::<T>());
223 permissions
224 }
225
226 fn validate_access(access: &ComponentAccess) -> bool {
227 access.allows_read(ComponentTypeId::of::<T>())
228 }
229}
230
231impl<T: Component> ViewElement for TryRead<T> {
232 type Component = T;
233}
234
235#[derive(Derivative, Debug)]
237#[derivative(Default(bound = ""))]
238pub struct Write<T: Component>(PhantomData<T>);
239
240impl<T: Component> Copy for Write<T> {}
241impl<T: Component> Clone for Write<T> {
242 fn clone(&self) -> Self { *self }
243}
244
245impl<'a, T: Component> DefaultFilter for Write<T> {
246 type Filter = EntityFilterTuple<ComponentFilter<T>, Passthrough, Passthrough>;
247
248 fn filter() -> Self::Filter { super::filter::filter_fns::component() }
249}
250
251impl<'a, T: Component> View<'a> for Write<T> {
252 type Iter = RefIterMut<'a, T, IterMut<'a, T>>;
253
254 #[inline]
255 fn fetch(
256 _: &'a ArchetypeData,
257 chunk: &'a ComponentStorage,
258 _: ChunkIndex,
259 _: SetIndex,
260 ) -> Self::Iter {
261 let (slice_borrow, slice) = unsafe {
262 chunk
263 .components(ComponentTypeId::of::<T>())
264 .unwrap_or_else(|| {
265 panic!(
266 "Component of type {:?} not found in chunk when fetching Write view",
267 std::any::type_name::<T>()
268 )
269 })
270 .data_slice_mut::<T>()
271 .deconstruct()
272 };
273 RefIterMut::new(slice_borrow, slice.iter_mut())
274 }
275
276 #[inline]
277 fn validate() -> bool { true }
278
279 #[inline]
280 fn reads<D: Component>() -> bool { TypeId::of::<T>() == TypeId::of::<D>() }
281
282 #[inline]
283 fn writes<D: Component>() -> bool { TypeId::of::<T>() == TypeId::of::<D>() }
284
285 fn requires_permissions() -> Permissions<ComponentTypeId> {
286 let mut permissions = Permissions::new();
287 permissions.push(ComponentTypeId::of::<T>());
288 permissions
289 }
290
291 fn validate_access(access: &ComponentAccess) -> bool {
292 access.allows_write(ComponentTypeId::of::<T>())
293 }
294}
295
296impl<T: Component> ViewElement for Write<T> {
297 type Component = T;
298}
299
300#[derive(Derivative, Debug)]
302#[derivative(Default(bound = ""))]
303pub struct TryWrite<T: Component>(PhantomData<T>);
304
305impl<T: Component> Copy for TryWrite<T> {}
306impl<T: Component> Clone for TryWrite<T> {
307 fn clone(&self) -> Self { *self }
308}
309
310impl<'a, T: Component> DefaultFilter for TryWrite<T> {
311 type Filter = EntityFilterTuple<Passthrough, Passthrough, Passthrough>;
312
313 fn filter() -> Self::Filter { super::filter::filter_fns::passthrough() }
314}
315
316impl<'a, T: Component> View<'a> for TryWrite<T> {
317 type Iter = TryRefIterMut<'a, T, IterMut<'a, T>>;
318
319 fn fetch(
320 _: &'a ArchetypeData,
321 chunk: &'a ComponentStorage,
322 _: ChunkIndex,
323 _: SetIndex,
324 ) -> Self::Iter {
325 unsafe {
326 chunk
327 .components(ComponentTypeId::of::<T>())
328 .map(|x| {
329 let (borrow, slice) = x.data_slice_mut::<T>().deconstruct();
330 TryRefIterMut::found(borrow, slice.iter_mut())
331 })
332 .unwrap_or_else(|| TryRefIterMut::missing(chunk.len()))
333 }
334 }
335
336 fn validate() -> bool { true }
337
338 #[inline]
339 fn reads<D: Component>() -> bool { TypeId::of::<T>() == TypeId::of::<D>() }
340
341 #[inline]
342 fn writes<D: Component>() -> bool { TypeId::of::<T>() == TypeId::of::<D>() }
343
344 fn requires_permissions() -> Permissions<ComponentTypeId> {
345 let mut permissions = Permissions::new();
346 permissions.push(ComponentTypeId::of::<T>());
347 permissions
348 }
349
350 fn validate_access(access: &ComponentAccess) -> bool {
351 access.allows_write(ComponentTypeId::of::<T>())
352 }
353}
354
355impl<T: Component> ViewElement for TryWrite<T> {
356 type Component = T;
357}
358
359#[derive(Debug)]
361pub struct Tagged<T: Tag>(PhantomData<T>);
362
363impl<T: Tag> ReadOnly for Tagged<T> {}
364
365impl<T: Tag> Copy for Tagged<T> {}
366impl<T: Tag> Clone for Tagged<T> {
367 fn clone(&self) -> Self { *self }
368}
369
370impl<'a, T: Tag> DefaultFilter for Tagged<T> {
371 type Filter = EntityFilterTuple<TagFilter<T>, Passthrough, Passthrough>;
372
373 fn filter() -> Self::Filter { super::filter::filter_fns::tag() }
374}
375
376impl<'a, T: Tag> View<'a> for Tagged<T> {
377 type Iter = Take<Repeat<&'a T>>;
378
379 #[inline]
380 fn fetch(
381 archetype: &'a ArchetypeData,
382 chunk: &'a ComponentStorage,
383 _: ChunkIndex,
384 SetIndex(set_index): SetIndex,
385 ) -> Self::Iter {
386 let data = unsafe {
387 archetype
388 .tags()
389 .get(TagTypeId::of::<T>())
390 .unwrap_or_else(|| {
391 panic!(
392 "Component of type {:?} not found in archetype when fetching Tagged view",
393 std::any::type_name::<T>()
394 )
395 })
396 .data_slice::<T>()
397 .get_unchecked(set_index)
398 };
399 std::iter::repeat(data).take(chunk.len())
400 }
401
402 #[inline]
403 fn validate() -> bool { true }
404
405 #[inline]
406 fn reads<D: Component>() -> bool { false }
407
408 #[inline]
409 fn writes<D: Component>() -> bool { false }
410
411 fn requires_permissions() -> Permissions<ComponentTypeId> { Permissions::new() }
412
413 #[inline]
414 fn validate_access(_: &ComponentAccess) -> bool { true }
415}
416
417impl<T: Tag> ViewElement for Tagged<T> {
418 type Component = Tagged<T>;
419}
420
421macro_rules! impl_view_tuple {
422 ( $( $ty: ident ),* ) => {
423 impl<$( $ty: ViewElement + DefaultFilter ),*> DefaultFilter for ($( $ty, )*) {
424 type Filter = EntityFilterTuple<
425 And<($( <$ty::Filter as EntityFilter>::ArchetypeFilter, )*)>,
426 And<($( <$ty::Filter as EntityFilter>::ChunksetFilter, )*)>,
427 And<($( <$ty::Filter as EntityFilter>::ChunkFilter, )*)>,
428 >;
429
430 fn filter() -> Self::Filter {
431 #![allow(non_snake_case)]
432 $( let $ty = $ty::filter().into_filters(); )*
433 EntityFilterTuple::new(
434 And { filters: ($( $ty.0, )*) },
435 And { filters: ($( $ty.1, )*) },
436 And { filters: ($( $ty.2, )*) },
437 )
438 }
439 }
440
441 impl<$( $ty: ReadOnly ),* > ReadOnly for ($( $ty, )*) {}
442
443 impl<$( $ty: ViewElement ),*> ViewElement for ($( $ty, )*) {
444 type Component = ($( $ty::Component, )*);
445 }
446
447 impl<'a, $( $ty: ViewElement + View<'a> ),* > View<'a> for ($( $ty, )*) {
448 type Iter = crate::zip::Zip<($( $ty::Iter, )*)>;
449
450 #[inline]
451 fn fetch(
452 archetype: &'a ArchetypeData,
453 chunk: &'a ComponentStorage,
454 chunk_index: ChunkIndex,
455 set_index: SetIndex,
456 ) -> Self::Iter {
457 crate::zip::multizip(($( $ty::fetch(archetype.clone(), chunk.clone(), chunk_index, set_index), )*))
458 }
459
460 fn validate() -> bool {
461 let types = &[$( TypeId::of::<$ty::Component>() ),*];
462 for i in 0..types.len() {
463 for j in (i + 1)..types.len() {
464 if unsafe { types.get_unchecked(i) == types.get_unchecked(j) } {
465 return false;
466 }
467 }
468 }
469
470 true
471 }
472
473 fn validate_access(access: &ComponentAccess) -> bool {
474 $( $ty::validate_access(access) )&&*
475 }
476
477 fn reads<Data: Component>() -> bool {
478 $( $ty::reads::<Data>() )||*
479 }
480
481 fn writes<Data: Component>() -> bool {
482 $( $ty::writes::<Data>() )||*
483 }
484
485 fn requires_permissions() -> Permissions<ComponentTypeId> {
486 let mut permissions = Permissions::new();
487 $( permissions.add($ty::requires_permissions()); )*
488 permissions
489 }
490 }
491 };
492}
493
494impl_view_tuple!(A);
495impl_view_tuple!(A, B);
496impl_view_tuple!(A, B, C);
497impl_view_tuple!(A, B, C, D);
498impl_view_tuple!(A, B, C, D, E);
499impl_view_tuple!(A, B, C, D, E, F);
500impl_view_tuple!(A, B, C, D, E, F, G);
501impl_view_tuple!(A, B, C, D, E, F, G, H);
502impl_view_tuple!(A, B, C, D, E, F, G, H, I);
503impl_view_tuple!(A, B, C, D, E, F, G, H, I, J);
504impl_view_tuple!(A, B, C, D, E, F, G, H, I, J, K);
505impl_view_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
506
507pub struct Chunk<'a, V: for<'b> View<'b>> {
509 archetype: &'a ArchetypeData,
510 components: &'a ComponentStorage,
511 chunk_index: ChunkIndex,
512 set_index: SetIndex,
513 view: PhantomData<V>,
514}
515
516impl<'a, V: for<'b> View<'b>> Chunk<'a, V> {
517 pub fn new(archetype: &'a ArchetypeData, set_index: SetIndex, chunk_index: ChunkIndex) -> Self {
518 Self {
519 components: unsafe {
520 archetype
521 .chunkset_unchecked(set_index)
522 .chunk_unchecked(chunk_index)
523 },
524 archetype,
525 chunk_index,
526 set_index,
527 view: PhantomData,
528 }
529 }
530
531 #[inline]
533 pub fn entities(&self) -> &'a [Entity] { self.components.entities() }
534
535 #[inline]
537 pub fn iter_mut(&mut self) -> <V as View<'a>>::Iter {
538 V::fetch(
539 self.archetype,
540 self.components,
541 self.chunk_index,
542 self.set_index,
543 )
544 }
545
546 #[inline]
548 pub fn iter_entities_mut(&mut self) -> ZipEntities<'a, V> {
549 ZipEntities {
550 entities: self.entities(),
551 data: V::fetch(
552 self.archetype,
553 self.components,
554 self.chunk_index,
555 self.set_index,
556 ),
557 index: 0,
558 view: PhantomData,
559 }
560 }
561
562 pub fn tag<T: Tag>(&self) -> Option<&T> {
564 self.archetype
565 .tags()
566 .get(TagTypeId::of::<T>())
567 .map(|tags| unsafe { tags.data_slice::<T>() })
568 .map(|slice| unsafe { slice.get_unchecked(*self.set_index) })
569 }
570
571 pub fn components<T: Component>(&self) -> Option<RefMap<'a, &[T]>> {
578 if !V::reads::<T>() {
579 panic!("data type not readable via this query");
580 }
581 self.components
582 .components(ComponentTypeId::of::<T>())
583 .map(|c| unsafe { c.data_slice::<T>() })
584 }
585
586 pub fn components_mut<T: Component>(&self) -> Option<RefMapMut<'a, &mut [T]>> {
593 if !V::writes::<T>() {
594 panic!("data type not writable via this query");
595 }
596 self.components
597 .components(ComponentTypeId::of::<T>())
598 .map(|c| unsafe { c.data_slice_mut::<T>() })
599 }
600}
601
602pub struct ZipEntities<'data, V: View<'data>> {
604 entities: &'data [Entity],
605 data: <V as View<'data>>::Iter,
606 index: usize,
607 view: PhantomData<V>,
608}
609
610impl<'data, V: View<'data>> Iterator for ZipEntities<'data, V> {
611 type Item = (Entity, <V::Iter as Iterator>::Item);
612
613 #[inline]
614 fn next(&mut self) -> Option<Self::Item> {
615 if let Some(data) = self.data.next() {
616 let i = self.index;
617 self.index += 1;
618 unsafe { Some((*self.entities.get_unchecked(i), data)) }
619 } else {
620 None
621 }
622 }
623
624 #[inline]
625 fn size_hint(&self) -> (usize, Option<usize>) {
626 let len = self.entities.len() - self.index;
627 (len, Some(len))
628 }
629}
630
631pub struct ChunkViewIter<'data, 'filter, V, FArch, FChunkset, FChunk>
633where
634 V: for<'a> View<'a>,
635 FArch: Filter<ArchetypeFilterData<'data>>,
636 FChunkset: Filter<ChunksetFilterData<'data>>,
637 FChunk: Filter<ChunkFilterData<'data>>,
638{
639 _view: PhantomData<V>,
640 storage: StorageAccessor<'data>,
641 arch_filter: &'filter FArch,
642 chunkset_filter: &'filter FChunkset,
643 chunk_filter: &'filter FChunk,
644 archetypes: Enumerate<FArch::Iter>,
645 set_frontier: Option<(&'data ArchetypeData, Take<Enumerate<FChunkset::Iter>>)>,
646 chunk_frontier: Option<(
647 &'data ArchetypeData,
648 SetIndex,
649 Take<Enumerate<FChunk::Iter>>,
650 )>,
651}
652
653impl<'data, 'filter, V, FArch, FChunkset, FChunk>
654 ChunkViewIter<'data, 'filter, V, FArch, FChunkset, FChunk>
655where
656 V: for<'a> View<'a>,
657 FArch: Filter<ArchetypeFilterData<'data>>,
658 FChunkset: Filter<ChunksetFilterData<'data>>,
659 FChunk: Filter<ChunkFilterData<'data>>,
660{
661 fn next_set(&mut self) -> Option<(&'data ArchetypeData, SetIndex)> {
662 loop {
663 if let Some((ref arch, ref mut chunks)) = self.set_frontier {
665 for (set_index, filter_data) in chunks {
666 if self.chunkset_filter.is_match(&filter_data).is_pass() {
667 return Some((arch, SetIndex(set_index)));
668 }
669 }
670 }
671
672 loop {
674 match self.archetypes.next() {
675 Some((arch_index, arch_data)) => {
676 if self.arch_filter.is_match(&arch_data).is_pass() {
677 if !self
679 .storage
680 .can_access_archetype(ArchetypeIndex(arch_index))
681 {
682 panic!(
683 "query attempted to access archetype unavailable via sub world"
684 );
685 }
686 self.set_frontier = {
688 let chunks = unsafe {
689 self.storage.inner().archetypes().get_unchecked(arch_index)
690 };
691 let data = ChunksetFilterData {
692 archetype_data: chunks,
693 };
694
695 Some((
696 chunks,
697 self.chunkset_filter
698 .collect(data)
699 .enumerate()
700 .take(chunks.len()),
701 ))
702 };
703 break;
704 }
705 }
706 None => return None,
708 }
709 }
710 }
711 }
712}
713
714impl<'data, 'filter, V, FArch, FChunkset, FChunk> Iterator
715 for ChunkViewIter<'data, 'filter, V, FArch, FChunkset, FChunk>
716where
717 V: for<'a> View<'a>,
718 FArch: Filter<ArchetypeFilterData<'data>>,
719 FChunkset: Filter<ChunksetFilterData<'data>>,
720 FChunk: Filter<ChunkFilterData<'data>>,
721{
722 type Item = Chunk<'data, V>;
723
724 fn next(&mut self) -> Option<Self::Item> {
725 loop {
726 if let Some((ref arch, set_index, ref mut set)) = self.chunk_frontier {
728 for (chunk_index, filter_data) in set {
729 if self.chunk_filter.is_match(&filter_data).is_pass() {
730 return Some(Chunk::new(arch, set_index, ChunkIndex(chunk_index)));
731 }
732 }
733 }
734
735 if let Some((ref arch, set_index)) = self.next_set() {
737 let chunks = unsafe { arch.chunkset_unchecked(set_index) }.occupied();
738 self.chunk_frontier = Some((
739 arch,
740 set_index,
741 self.chunk_filter
742 .collect(ChunkFilterData { chunks })
743 .enumerate()
744 .take(chunks.len()),
745 ))
746 } else {
747 return None;
748 }
749 }
750 }
751}
752
753pub struct ChunkDataIter<'data, V, I>
755where
756 V: for<'a> View<'a>,
757 I: Iterator<Item = Chunk<'data, V>>,
758{
759 iter: I,
760 frontier: Option<<V as View<'data>>::Iter>,
761 _view: PhantomData<V>,
762}
763
764impl<'data, V, I> Iterator for ChunkDataIter<'data, V, I>
765where
766 V: for<'a> View<'a>,
767 I: Iterator<Item = Chunk<'data, V>>,
768{
769 type Item = <<V as View<'data>>::Iter as Iterator>::Item;
770
771 #[inline(always)]
772 fn next(&mut self) -> Option<Self::Item> {
773 loop {
774 if let Some(ref mut inner) = self.frontier {
775 if let elt @ Some(_) = inner.next() {
776 return elt;
777 }
778 }
779 match self.iter.next() {
780 Some(mut inner) => self.frontier = Some(inner.iter_mut()),
781 None => return None,
782 }
783 }
784 }
785}
786
787pub struct ChunkEntityIter<'data, V, I>
789where
790 V: for<'a> View<'a>,
791 I: Iterator<Item = Chunk<'data, V>>,
792{
793 iter: I,
794 frontier: Option<ZipEntities<'data, V>>,
795 _view: PhantomData<V>,
796}
797
798impl<'data, 'query, V, I> Iterator for ChunkEntityIter<'data, V, I>
799where
800 V: for<'a> View<'a>,
801 I: Iterator<Item = Chunk<'data, V>>,
802{
803 type Item = (Entity, <<V as View<'data>>::Iter as Iterator>::Item);
804
805 #[inline]
806 fn next(&mut self) -> Option<Self::Item> {
807 loop {
808 if let Some(ref mut inner) = self.frontier {
809 if let elt @ Some(_) = inner.next() {
810 return elt;
811 }
812 }
813 match self.iter.next() {
814 Some(mut inner) => self.frontier = Some(inner.iter_entities_mut()),
815 None => return None,
816 }
817 }
818 }
819}
820
821#[derive(Derivative)]
944#[derivative(Clone(bound = "F: Clone"))]
945pub struct Query<V: for<'a> View<'a>, F: EntityFilter> {
946 view: PhantomData<V>,
947 pub filter: F,
948}
949
950impl<V, F> Query<V, F>
951where
952 V: for<'a> View<'a>,
953 F: EntityFilter,
954{
955 pub fn filter<T: EntityFilter>(self, filter: T) -> Query<V, <F as std::ops::BitAnd<T>>::Output>
957 where
958 F: std::ops::BitAnd<T>,
959 <F as std::ops::BitAnd<T>>::Output: EntityFilter,
960 {
961 Query {
962 view: self.view,
963 filter: self.filter & filter,
964 }
965 }
966
967 pub unsafe fn iter_chunks_unchecked<'a, 'data, T: EntityStore>(
980 &'a self,
981 world: &'data T,
982 ) -> ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter> {
983 self.filter.init();
984 let (arch_filter, chunkset_filter, chunk_filter) = self.filter.filters();
985 let storage = world.get_component_storage::<V>().unwrap();
986 let archetypes = arch_filter
987 .collect(ArchetypeFilterData {
988 component_types: storage.inner().component_types(),
989 tag_types: storage.inner().tag_types(),
990 })
991 .enumerate();
992 ChunkViewIter {
993 storage,
994 arch_filter,
995 chunkset_filter,
996 chunk_filter,
997 archetypes,
998 set_frontier: None,
999 chunk_frontier: None,
1000 _view: PhantomData,
1001 }
1002 }
1003
1004 pub fn iter_chunks<'a, 'data, T: EntityStore>(
1006 &'a self,
1007 world: &'data T,
1008 ) -> ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>
1009 where
1010 V: ReadOnly,
1011 {
1012 unsafe { self.iter_chunks_unchecked(world) }
1014 }
1015
1016 pub fn iter_chunks_mut<'a, 'data, T: EntityStore>(
1018 &'a self,
1019 world: &'data mut T,
1020 ) -> ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter> {
1021 unsafe { self.iter_chunks_unchecked(world) }
1023 }
1024
1025 pub unsafe fn iter_entities_unchecked<'a, 'data, T: EntityStore>(
1038 &'a self,
1039 world: &'data T,
1040 ) -> ChunkEntityIter<
1041 'data,
1042 V,
1043 ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>,
1044 > {
1045 ChunkEntityIter {
1046 iter: self.iter_chunks_unchecked(world),
1047 frontier: None,
1048 _view: PhantomData,
1049 }
1050 }
1051
1052 pub fn iter_entities<'a, 'data, T: EntityStore>(
1054 &'a self,
1055 world: &'data T,
1056 ) -> ChunkEntityIter<
1057 'data,
1058 V,
1059 ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>,
1060 >
1061 where
1062 V: ReadOnly,
1063 {
1064 unsafe { self.iter_entities_unchecked(world) }
1066 }
1067
1068 pub fn iter_entities_mut<'a, 'data, T: EntityStore>(
1070 &'a self,
1071 world: &'data mut T,
1072 ) -> ChunkEntityIter<
1073 'data,
1074 V,
1075 ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>,
1076 > {
1077 unsafe { self.iter_entities_unchecked(world) }
1079 }
1080
1081 pub unsafe fn iter_unchecked<'a, 'data, T: EntityStore>(
1094 &'a self,
1095 world: &'data T,
1096 ) -> ChunkDataIter<
1097 'data,
1098 V,
1099 ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>,
1100 > {
1101 ChunkDataIter {
1102 iter: self.iter_chunks_unchecked(world),
1103 frontier: None,
1104 _view: PhantomData,
1105 }
1106 }
1107
1108 pub fn iter<'a, 'data, T: EntityStore>(
1110 &'a self,
1111 world: &'data T,
1112 ) -> ChunkDataIter<
1113 'data,
1114 V,
1115 ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>,
1116 >
1117 where
1118 V: ReadOnly,
1119 {
1120 unsafe { self.iter_unchecked(world) }
1122 }
1123
1124 pub fn iter_mut<'a, 'data, T: EntityStore>(
1126 &'a self,
1127 world: &'data mut T,
1128 ) -> ChunkDataIter<
1129 'data,
1130 V,
1131 ChunkViewIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>,
1132 > {
1133 unsafe { self.iter_unchecked(world) }
1135 }
1136
1137 pub unsafe fn for_each_entities_unchecked<'a, 'data, T, W>(&'a self, world: &'data W, mut f: T)
1150 where
1151 T: Fn((Entity, <<V as View<'data>>::Iter as Iterator>::Item)),
1152 W: EntityStore,
1153 {
1154 for mut chunk in self.iter_chunks_unchecked(world) {
1155 chunk.iter_entities_mut().for_each(&mut f)
1156 }
1157 }
1158
1159 pub fn for_each_entities<'a, 'data, T, W>(&'a self, world: &'data W, f: T)
1161 where
1162 T: Fn((Entity, <<V as View<'data>>::Iter as Iterator>::Item)),
1163 V: ReadOnly,
1164 W: EntityStore,
1165 {
1166 unsafe { self.for_each_entities_unchecked(world, f) };
1168 }
1169
1170 pub fn for_each_entities_mut<'a, 'data, T, W>(&'a self, world: &'data mut W, f: T)
1172 where
1173 T: Fn((Entity, <<V as View<'data>>::Iter as Iterator>::Item)),
1174 W: EntityStore,
1175 {
1176 unsafe { self.for_each_entities_unchecked(world, f) };
1178 }
1179
1180 pub unsafe fn for_each_unchecked<'a, 'data, T, W>(&'a self, world: &'data W, mut f: T)
1193 where
1194 T: Fn(<<V as View<'data>>::Iter as Iterator>::Item),
1195 W: EntityStore,
1196 {
1197 for mut chunk in self.iter_chunks_unchecked(world) {
1198 chunk.iter_mut().for_each(&mut f)
1199 }
1200 }
1201
1202 pub fn for_each<'a, 'data, T, W>(&'a self, world: &'data W, f: T)
1204 where
1205 T: Fn(<<V as View<'data>>::Iter as Iterator>::Item),
1206 V: ReadOnly,
1207 W: EntityStore,
1208 {
1209 unsafe { self.for_each_unchecked(world, f) };
1211 }
1212
1213 pub fn for_each_mut<'a, 'data, T, W>(&'a self, world: &'data mut W, f: T)
1215 where
1216 T: Fn(<<V as View<'data>>::Iter as Iterator>::Item),
1217 W: EntityStore,
1218 {
1219 unsafe { self.for_each_unchecked(world, f) };
1221 }
1222
1223 pub fn components<'a, T: Component, W: EntityStore>(
1227 &self,
1228 world: &'a W,
1229 ) -> RefMapSet<'a, Vec<&'a T>> {
1230 if !V::reads::<T>() {
1231 panic!("data type not readable via this query");
1232 }
1233
1234 let mut borrows = vec![];
1235 let mut refs = vec![];
1236 let storage = world.get_component_storage::<Read<T>>().unwrap().inner();
1237
1238 unsafe {
1239 self.filter
1240 .iter_archetype_indexes(storage)
1241 .flat_map(|archetype_index| {
1242 storage
1243 .archetypes()
1244 .get_unchecked(archetype_index.0)
1245 .iter_data_slice::<T>()
1246 })
1247 .map(|x| x.deconstruct())
1248 .for_each(|(borrow, slice)| {
1249 borrows.push(borrow);
1250 refs.extend(slice);
1251 });
1252 }
1253
1254 RefMapSet::new(borrows, refs)
1255 }
1256
1257 pub fn components_mut<'a, T: Component, W: EntityStore>(
1260 &self,
1261 world: &'a mut W,
1262 ) -> RefMapMutSet<'a, Vec<&'a mut T>> {
1263 if !V::writes::<T>() {
1264 panic!("data type not writable via this query");
1265 }
1266
1267 let mut borrows = vec![];
1268 let mut refs = vec![];
1269 let storage = world.get_component_storage::<Read<T>>().unwrap().inner();
1270
1271 unsafe {
1272 self.filter
1273 .iter_archetype_indexes(storage)
1274 .flat_map(|archetype_index| {
1275 storage
1276 .archetypes()
1277 .get_unchecked(archetype_index.0)
1278 .iter_data_slice_unchecked_mut::<T>()
1279 })
1280 .map(|x| x.deconstruct())
1281 .for_each(|(borrow, slice)| {
1282 borrows.push(borrow);
1283 refs.extend(slice);
1284 });
1285 }
1286
1287 RefMapMutSet::new(borrows, refs)
1288 }
1289
1290 #[cfg(feature = "par-iter")]
1291 pub unsafe fn par_iter_chunks_unchecked<'a, 'data, W>(
1304 &'a self,
1305 world: &'data W,
1306 ) -> ChunkViewParIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>
1307 where
1308 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'data>>>::Iter: FissileIterator,
1309 <F::ChunksetFilter as Filter<ChunksetFilterData<'data>>>::Iter: FissileIterator,
1310 <F::ChunkFilter as Filter<ChunkFilterData<'data>>>::Iter: FissileIterator,
1311 W: EntityStore,
1312 {
1313 self.filter.init();
1314 let (arch_filter, chunkset_filter, chunk_filter) = self.filter.filters();
1315 let storage = world.get_component_storage::<V>().unwrap();
1316 let archetypes = FissileEnumerate::new(arch_filter.collect(ArchetypeFilterData {
1317 component_types: storage.inner().component_types(),
1318 tag_types: storage.inner().tag_types(),
1319 }));
1320 ChunkViewParIter {
1321 storage,
1322 arch_filter,
1323 chunkset_filter,
1324 chunk_filter,
1325 archetypes,
1326 set_frontier: None,
1327 chunk_frontier: None,
1328 _view: PhantomData,
1329 }
1330 }
1331
1332 #[cfg(feature = "par-iter")]
1333 pub fn par_iter_chunks<'a, 'data, W>(
1335 &'a self,
1336 world: &'data W,
1337 ) -> ChunkViewParIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>
1338 where
1339 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'data>>>::Iter: FissileIterator,
1340 <F::ChunksetFilter as Filter<ChunksetFilterData<'data>>>::Iter: FissileIterator,
1341 <F::ChunkFilter as Filter<ChunkFilterData<'data>>>::Iter: FissileIterator,
1342 V: ReadOnly,
1343 W: EntityStore,
1344 {
1345 unsafe { self.par_iter_chunks_unchecked(world) }
1347 }
1348
1349 #[cfg(feature = "par-iter")]
1350 pub fn par_iter_chunks_mut<'a, 'data, W>(
1352 &'a self,
1353 world: &'data mut W,
1354 ) -> ChunkViewParIter<'data, 'a, V, F::ArchetypeFilter, F::ChunksetFilter, F::ChunkFilter>
1355 where
1356 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'data>>>::Iter: FissileIterator,
1357 <F::ChunksetFilter as Filter<ChunksetFilterData<'data>>>::Iter: FissileIterator,
1358 <F::ChunkFilter as Filter<ChunkFilterData<'data>>>::Iter: FissileIterator,
1359 W: EntityStore,
1360 {
1361 unsafe { self.par_iter_chunks_unchecked(world) }
1363 }
1364
1365 #[cfg(feature = "par-iter")]
1378 pub unsafe fn par_entities_for_each_unchecked<'a, T, W>(&'a self, world: &'a W, f: T)
1379 where
1380 T: Fn((Entity, <<V as View<'a>>::Iter as Iterator>::Item)) + Send + Sync,
1381 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1382 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1383 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1384 W: EntityStore,
1385 {
1386 self.par_for_each_chunk_unchecked(world, |mut chunk| {
1387 for data in chunk.iter_entities_mut() {
1388 f(data);
1389 }
1390 });
1391 }
1392
1393 #[cfg(feature = "par-iter")]
1395 pub fn par_entities_for_each<'a, T, W>(&'a self, world: &'a W, f: T)
1396 where
1397 T: Fn((Entity, <<V as View<'a>>::Iter as Iterator>::Item)) + Send + Sync,
1398 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1399 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1400 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1401 V: ReadOnly,
1402 W: EntityStore,
1403 {
1404 unsafe { self.par_entities_for_each_unchecked(world, f) };
1406 }
1407
1408 #[cfg(feature = "par-iter")]
1410 pub fn par_entities_for_each_mut<'a, T, W>(&'a self, world: &'a mut W, f: T)
1411 where
1412 T: Fn((Entity, <<V as View<'a>>::Iter as Iterator>::Item)) + Send + Sync,
1413 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1414 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1415 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1416 W: EntityStore,
1417 {
1418 unsafe { self.par_entities_for_each_unchecked(world, f) };
1420 }
1421
1422 #[cfg(feature = "par-iter")]
1435 pub unsafe fn par_for_each_unchecked<'a, T, W>(&'a self, world: &'a W, f: T)
1436 where
1437 T: Fn(<<V as View<'a>>::Iter as Iterator>::Item) + Send + Sync,
1438 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1439 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1440 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1441 W: EntityStore,
1442 {
1443 self.par_for_each_chunk_unchecked(world, |mut chunk| {
1444 for data in chunk.iter_mut() {
1445 f(data);
1446 }
1447 });
1448 }
1449
1450 #[cfg(feature = "par-iter")]
1452 pub fn par_for_each<'a, T, W>(&'a self, world: &'a W, f: T)
1453 where
1454 T: Fn(<<V as View<'a>>::Iter as Iterator>::Item) + Send + Sync,
1455 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1456 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1457 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1458 V: ReadOnly,
1459 W: EntityStore,
1460 {
1461 unsafe { self.par_for_each_unchecked(world, f) };
1463 }
1464
1465 #[cfg(feature = "par-iter")]
1467 pub fn par_for_each_mut<'a, T, W>(&'a self, world: &'a mut W, f: T)
1468 where
1469 T: Fn(<<V as View<'a>>::Iter as Iterator>::Item) + Send + Sync,
1470 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1471 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1472 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1473 W: EntityStore,
1474 {
1475 unsafe { self.par_for_each_unchecked(world, f) };
1477 }
1478
1479 #[cfg(feature = "par-iter")]
1492 pub unsafe fn par_for_each_chunk_unchecked<'a, T, W>(&'a self, world: &'a W, f: T)
1493 where
1494 T: Fn(Chunk<'a, V>) + Send + Sync,
1495 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1496 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1497 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1498 W: EntityStore,
1499 {
1500 let par_iter = self.par_iter_chunks_unchecked(world);
1501 ParallelIterator::for_each(par_iter, |chunk| {
1502 f(chunk);
1503 });
1504 }
1505
1506 #[cfg(feature = "par-iter")]
1508 pub fn par_for_each_chunk<'a, T, W>(&'a self, world: &'a W, f: T)
1509 where
1510 T: Fn(Chunk<'a, V>) + Send + Sync,
1511 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1512 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1513 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1514 V: ReadOnly,
1515 W: EntityStore,
1516 {
1517 unsafe { self.par_for_each_chunk_unchecked(world, f) };
1519 }
1520
1521 #[cfg(feature = "par-iter")]
1523 pub fn par_for_each_chunk_mut<'a, T, W>(&'a self, world: &'a mut W, f: T)
1524 where
1525 T: Fn(Chunk<'a, V>) + Send + Sync,
1526 <F::ArchetypeFilter as Filter<ArchetypeFilterData<'a>>>::Iter: FissileIterator,
1527 <F::ChunksetFilter as Filter<ChunksetFilterData<'a>>>::Iter: FissileIterator,
1528 <F::ChunkFilter as Filter<ChunkFilterData<'a>>>::Iter: FissileIterator,
1529 W: EntityStore,
1530 {
1531 unsafe { self.par_for_each_chunk_unchecked(world, f) };
1533 }
1534}
1535
1536#[cfg(feature = "par-iter")]
1538pub struct ChunkViewParIter<'data, 'filter, V, FArch, FChunkset, FChunk>
1539where
1540 V: for<'a> View<'a>,
1541 FArch: Filter<ArchetypeFilterData<'data>>,
1542 FChunkset: Filter<ChunksetFilterData<'data>>,
1543 FChunk: Filter<ChunkFilterData<'data>>,
1544 FArch::Iter: FissileIterator,
1545 FChunkset::Iter: FissileIterator,
1546 FChunk::Iter: FissileIterator,
1547{
1548 _view: PhantomData<V>,
1549 storage: StorageAccessor<'data>,
1550 arch_filter: &'filter FArch,
1551 chunkset_filter: &'filter FChunkset,
1552 chunk_filter: &'filter FChunk,
1553 archetypes: FissileEnumerate<FArch::Iter>,
1554 set_frontier: Option<(
1555 &'data ArchetypeData,
1556 FissileEnumerate<FChunkset::Iter>,
1557 usize,
1558 )>,
1559 chunk_frontier: Option<(
1560 &'data ArchetypeData,
1561 SetIndex,
1562 FissileEnumerate<FChunk::Iter>,
1563 usize,
1564 )>,
1565}
1566
1567#[cfg(feature = "par-iter")]
1568impl<'data, 'filter, V, FArch, FChunkset, FChunk>
1569 ChunkViewParIter<'data, 'filter, V, FArch, FChunkset, FChunk>
1570where
1571 V: for<'a> View<'a>,
1572 FArch: Filter<ArchetypeFilterData<'data>>,
1573 FChunkset: Filter<ChunksetFilterData<'data>>,
1574 FChunk: Filter<ChunkFilterData<'data>>,
1575 FArch::Iter: FissileIterator,
1576 FChunkset::Iter: FissileIterator,
1577 FChunk::Iter: FissileIterator,
1578{
1579 fn next_set(&mut self) -> Option<(&'data ArchetypeData, SetIndex)> {
1580 loop {
1581 if let Some((ref arch, ref mut chunks, index_bound)) = self.set_frontier {
1583 for (set_index, filter_data) in chunks {
1584 if set_index < index_bound
1585 && self.chunkset_filter.is_match(&filter_data).is_pass()
1586 {
1587 return Some((arch, SetIndex(set_index)));
1588 }
1589 }
1590 }
1591
1592 loop {
1594 match self.archetypes.next() {
1595 Some((arch_index, arch_data)) => {
1596 if self.arch_filter.is_match(&arch_data).is_pass() {
1597 if !self
1599 .storage
1600 .can_access_archetype(ArchetypeIndex(arch_index))
1601 {
1602 panic!(
1603 "query attempted to access archetype unavailable via sub world"
1604 );
1605 }
1606 self.set_frontier = {
1608 let arch = unsafe {
1609 self.storage.inner().archetypes().get_unchecked(arch_index)
1610 };
1611 let data = ChunksetFilterData {
1612 archetype_data: arch,
1613 };
1614
1615 Some((
1616 arch,
1617 FissileEnumerate::new(self.chunkset_filter.collect(data)),
1618 arch.len(),
1619 ))
1620 };
1621 break;
1622 }
1623 }
1624 None => return None,
1626 }
1627 }
1628 }
1629 }
1630}
1631
1632#[cfg(feature = "par-iter")]
1633impl<'data, 'filter, V, FArch, FChunkset, FChunk> Iterator
1634 for ChunkViewParIter<'data, 'filter, V, FArch, FChunkset, FChunk>
1635where
1636 V: for<'a> View<'a>,
1637 FArch: Filter<ArchetypeFilterData<'data>>,
1638 FChunkset: Filter<ChunksetFilterData<'data>>,
1639 FChunk: Filter<ChunkFilterData<'data>>,
1640 FArch::Iter: FissileIterator,
1641 FChunkset::Iter: FissileIterator,
1642 FChunk::Iter: FissileIterator,
1643{
1644 type Item = Chunk<'data, V>;
1645
1646 fn next(&mut self) -> Option<Self::Item> {
1647 loop {
1648 if let Some((ref arch, set_index, ref mut set, index_bound)) = self.chunk_frontier {
1650 for (chunk_index, filter_data) in set {
1651 if chunk_index < index_bound
1652 && self.chunk_filter.is_match(&filter_data).is_pass()
1653 {
1654 return Some(Chunk::new(arch, set_index, ChunkIndex(chunk_index)));
1655 }
1656 }
1657 }
1658
1659 if let Some((ref arch, set_index)) = self.next_set() {
1661 let chunks = unsafe { arch.chunkset_unchecked(set_index) }.occupied();
1662 self.chunk_frontier = Some((
1663 arch,
1664 set_index,
1665 FissileEnumerate::new(self.chunk_filter.collect(ChunkFilterData { chunks })),
1666 chunks.len(),
1667 ))
1668 } else {
1669 return None;
1670 }
1671 }
1672 }
1673}
1674
1675#[cfg(feature = "par-iter")]
1676impl<'data, 'filter, V, FArch, FChunkset, FChunk> ParallelIterator
1677 for ChunkViewParIter<'data, 'filter, V, FArch, FChunkset, FChunk>
1678where
1679 V: for<'a> View<'a>,
1680 FArch: Filter<ArchetypeFilterData<'data>>,
1681 FChunkset: Filter<ChunksetFilterData<'data>>,
1682 FChunk: Filter<ChunkFilterData<'data>>,
1683 FArch::Iter: FissileIterator,
1684 FChunkset::Iter: FissileIterator,
1685 FChunk::Iter: FissileIterator,
1686{
1687 type Item = Chunk<'data, V>;
1688
1689 fn drive_unindexed<C>(self, consumer: C) -> C::Result
1690 where
1691 C: UnindexedConsumer<Self::Item>,
1692 {
1693 bridge_unindexed(self, consumer)
1694 }
1695}
1696
1697#[cfg(feature = "par-iter")]
1698impl<'data, 'filter, V, FArch, FChunkset, FChunk> UnindexedProducer
1699 for ChunkViewParIter<'data, 'filter, V, FArch, FChunkset, FChunk>
1700where
1701 V: for<'a> View<'a>,
1702 FArch: Filter<ArchetypeFilterData<'data>>,
1703 FChunkset: Filter<ChunksetFilterData<'data>>,
1704 FChunk: Filter<ChunkFilterData<'data>>,
1705 FArch::Iter: FissileIterator,
1706 FChunkset::Iter: FissileIterator,
1707 FChunk::Iter: FissileIterator,
1708{
1709 type Item = Chunk<'data, V>;
1710
1711 fn split(self) -> (Self, Option<Self>) {
1712 let Self {
1713 _view,
1714 storage,
1715 arch_filter,
1716 chunkset_filter,
1717 chunk_filter,
1718 archetypes,
1719 set_frontier,
1720 chunk_frontier,
1721 } = self;
1722
1723 let (left_archetypes, right_archetypes, arch_size) = archetypes.split();
1724
1725 let (left_set, right_set, set_size) = if let Some((data, iter, bound)) = set_frontier {
1726 let (left_iter, right_iter, iter_size) = iter.split();
1727 (
1728 Some((data, left_iter, bound)),
1729 Some((data, right_iter, bound)),
1730 iter_size,
1731 )
1732 } else {
1733 (None, None, 0)
1734 };
1735
1736 let (left_chunk, right_chunk, chunk_size) =
1737 if let Some((data, idx, iter, bound)) = chunk_frontier {
1738 let (left_iter, right_iter, iter_size) = iter.split();
1739 (
1740 Some((data, idx, left_iter, bound)),
1741 Some((data, idx, right_iter, bound)),
1742 iter_size,
1743 )
1744 } else {
1745 (None, None, 0)
1746 };
1747
1748 let right_split = Self {
1749 _view,
1750 storage: storage.clone(),
1751 arch_filter,
1752 chunkset_filter,
1753 chunk_filter,
1754 archetypes: right_archetypes,
1755 set_frontier: right_set,
1756 chunk_frontier: right_chunk,
1757 };
1758
1759 if arch_size + set_size + chunk_size == 0 {
1760 (right_split, None)
1761 } else {
1762 (
1763 Self {
1764 _view,
1765 storage,
1766 arch_filter,
1767 chunkset_filter,
1768 chunk_filter,
1769 archetypes: left_archetypes,
1770 set_frontier: left_set,
1771 chunk_frontier: left_chunk,
1772 },
1773 Some(right_split),
1774 )
1775 }
1776 }
1777 fn fold_with<F>(self, folder: F) -> F
1778 where
1779 F: Folder<Self::Item>,
1780 {
1781 folder.consume_iter(self)
1782 }
1783}