1use crate::{
2 archetype::{Archetype, Slice, Slot},
3 fetch::PreparedFetch,
4 filter::{next_slice, Filtered},
5 Entity,
6};
7
8pub struct Chunk<'q, Q: PreparedFetch<'q>> {
11 arch: &'q Archetype,
12 fetch: Q::Chunk,
13 pos: Slot,
14 end: Slot,
15}
16
17impl<'q, Q: PreparedFetch<'q>> core::fmt::Debug for Chunk<'q, Q> {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 f.debug_struct("Batch")
20 .field("pos", &self.pos)
21 .field("end", &self.end)
22 .finish()
23 }
24}
25
26impl<'q, Q: PreparedFetch<'q>> Chunk<'q, Q> {
27 pub(crate) fn new(arch: &'q Archetype, chunk: Q::Chunk, slice: Slice) -> Self {
28 Self {
29 arch,
30 fetch: chunk,
31 pos: slice.start,
32 end: slice.end,
33 }
34 }
35
36 pub(crate) fn slots(&self) -> Slice {
37 Slice::new(self.pos, self.end)
38 }
39
40 pub fn arch(&self) -> &Archetype {
44 self.arch
45 }
46
47 pub fn len(&self) -> usize {
49 self.slots().len()
50 }
51
52 pub fn is_empty(&self) -> bool {
54 self.slots().is_empty()
55 }
56}
57
58impl<'q, Q> Iterator for Chunk<'q, Q>
59where
60 Q: PreparedFetch<'q>,
61{
62 type Item = Q::Item;
63
64 fn next(&mut self) -> Option<Q::Item> {
65 if self.pos == self.end {
66 None
67 } else {
68 let item = unsafe { Q::fetch_next(&mut self.fetch) };
70 self.pos += 1;
71 Some(item)
72 }
73 }
74}
75
76impl<'q, Q> Chunk<'q, Q>
77where
78 Q: PreparedFetch<'q>,
79{
80 pub(crate) fn next_with_id(&mut self) -> Option<(Entity, Q::Item)> {
81 if self.pos == self.end {
82 None
83 } else {
84 let item = unsafe { Q::fetch_next(&mut self.fetch) };
85 let id = self.arch.entities[self.pos];
86 self.pos += 1;
87 Some((id, item))
88 }
89 }
90
91 pub(crate) fn next_full(&mut self) -> Option<(Slot, Entity, Q::Item)> {
92 if self.pos == self.end {
93 None
94 } else {
95 let slot = self.pos;
96 let item = unsafe { Q::fetch_next(&mut self.fetch) };
97 let id = self.arch.entities[slot];
98 self.pos += 1;
99
100 Some((slot, id, item))
101 }
102 }
103}
104
105pub struct ArchetypeChunks<'q, Q, F> {
109 pub(crate) arch: &'q Archetype,
110 pub(crate) fetch: *mut Filtered<Q, F>,
111 pub(crate) slots: Slice,
112}
113
114unsafe impl<'q, Q: 'q, F: 'q> Sync for ArchetypeChunks<'q, Q, F> where &'q mut Filtered<Q, F>: Sync {}
115unsafe impl<'q, Q: 'q, F: 'q> Send for ArchetypeChunks<'q, Q, F> where &'q mut Filtered<Q, F>: Send {}
116
117impl<'q, Q, F> Iterator for ArchetypeChunks<'q, Q, F>
118where
119 Q: 'q + PreparedFetch<'q>,
120 F: 'q + PreparedFetch<'q>,
121{
122 type Item = Chunk<'q, Q>;
123
124 #[inline]
125 fn next(&mut self) -> Option<Self::Item> {
126 let fetch = unsafe { &mut *self.fetch };
128
129 let slots = next_slice(&mut self.slots, fetch)?;
131
132 let chunk = unsafe { fetch.create_chunk(slots) };
134 let chunk = Chunk::new(self.arch, chunk, slots);
135
136 Some(chunk)
137 }
138}