@@ -11,6 +11,7 @@ use std::marker::PhantomData;
1111pub struct Query < ' a , Q : HecsQuery > {
1212 pub ( crate ) world : & ' a World ,
1313 pub ( crate ) archetype_access : & ' a ArchetypeAccess ,
14+ state : & ' static ( ) ,
1415 _marker : PhantomData < Q > ,
1516}
1617
@@ -23,19 +24,23 @@ pub enum QueryError {
2324 NoSuchEntity ,
2425}
2526
26- impl < ' a , Q : HecsQuery > Query < ' a , Q > {
27+ impl < ' w , Q : HecsQuery > Query < ' w , Q >
28+ where
29+ Q :: Fetch : for < ' a > Fetch < ' a , State = ( ) > ,
30+ {
2731 #[ inline]
28- pub fn new ( world : & ' a World , archetype_access : & ' a ArchetypeAccess ) -> Self {
32+ pub fn new ( world : & ' w World , archetype_access : & ' w ArchetypeAccess ) -> Self {
2933 Self {
3034 world,
3135 archetype_access,
36+ state : & ( ) ,
3237 _marker : PhantomData :: default ( ) ,
3338 }
3439 }
3540
3641 #[ inline]
37- pub fn iter ( & mut self ) -> QueryBorrowChecked < ' _ , Q > {
38- QueryBorrowChecked :: new ( & self . world . archetypes , self . archetype_access )
42+ pub fn iter ( & mut self ) -> QueryBorrowChecked < ' w , ' static , ( ) , Q :: Fetch > {
43+ QueryBorrowChecked :: new ( & self . world . archetypes , self . archetype_access , & self . state )
3944 }
4045
4146 // TODO: find a way to make `iter`, `get`, `get_mut`, and `entity` safe without using tracking pointers with global locks
@@ -133,19 +138,27 @@ impl<'a, Q: HecsQuery> Query<'a, Q> {
133138/// A borrow of a `World` sufficient to execute the query `Q`
134139///
135140/// Note that borrows are not released until this object is dropped.
136- pub struct QueryBorrowChecked < ' w , Q : HecsQuery > {
141+ pub struct QueryBorrowChecked < ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > {
137142 archetypes : & ' w [ Archetype ] ,
138143 archetype_access : & ' w ArchetypeAccess ,
144+ state : & ' s S ,
139145 borrowed : bool ,
140- _marker : PhantomData < Q > ,
146+ _marker : PhantomData < F > ,
141147}
142148
143- impl < ' w , Q : HecsQuery > QueryBorrowChecked < ' w , Q > {
144- pub ( crate ) fn new ( archetypes : & ' w [ Archetype ] , archetype_access : & ' w ArchetypeAccess ) -> Self {
149+ impl < ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > >
150+ QueryBorrowChecked < ' w , ' s , S , F >
151+ {
152+ pub ( crate ) fn new (
153+ archetypes : & ' w [ Archetype ] ,
154+ archetype_access : & ' w ArchetypeAccess ,
155+ state : & ' s S ,
156+ ) -> Self {
145157 Self {
146158 archetypes,
147159 borrowed : false ,
148160 archetype_access,
161+ state,
149162 _marker : PhantomData ,
150163 }
151164 }
@@ -154,7 +167,7 @@ impl<'w, Q: HecsQuery> QueryBorrowChecked<'w, Q> {
154167 ///
155168 /// Must be called only once per query.
156169 #[ inline]
157- pub fn iter < ' q > ( & ' q mut self ) -> QueryIter < ' q , ' w , Q > {
170+ pub fn iter < ' q > ( & ' q mut self ) -> QueryIter < ' q , ' w , ' s , S , F > {
158171 self . borrow ( ) ;
159172 QueryIter {
160173 borrow : self ,
@@ -177,7 +190,7 @@ impl<'w, Q: HecsQuery> QueryBorrowChecked<'w, Q> {
177190 /// each batch could take longer than running the batch. On the other
178191 /// hand, a too large batch size risks that one batch is still running
179192 /// long after the rest have finished.
180- pub fn par_iter < ' q > ( & ' q mut self , batch_size : usize ) -> ParIter < ' q , ' w , Q > {
193+ pub fn par_iter < ' q > ( & ' q mut self , batch_size : usize ) -> ParIter < ' q , ' w , ' s , S , F > {
181194 self . borrow ( ) ;
182195 ParIter {
183196 borrow : self ,
@@ -195,38 +208,50 @@ impl<'w, Q: HecsQuery> QueryBorrowChecked<'w, Q> {
195208 }
196209
197210 for index in self . archetype_access . immutable . ones ( ) {
198- Q :: Fetch :: borrow ( & self . archetypes [ index] , & Default :: default ( ) ) ;
211+ F :: borrow ( & self . archetypes [ index] , self . state ) ;
199212 }
200213
201214 for index in self . archetype_access . mutable . ones ( ) {
202- Q :: Fetch :: borrow ( & self . archetypes [ index] , & Default :: default ( ) ) ;
215+ F :: borrow ( & self . archetypes [ index] , self . state ) ;
203216 }
204217
205218 self . borrowed = true ;
206219 }
207220}
208221
209- unsafe impl < ' w , Q : HecsQuery > Send for QueryBorrowChecked < ' w , Q > { }
210- unsafe impl < ' w , Q : HecsQuery > Sync for QueryBorrowChecked < ' w , Q > { }
222+ unsafe impl < ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > Send
223+ for QueryBorrowChecked < ' w , ' s , S , F >
224+ {
225+ }
226+ unsafe impl < ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > Sync
227+ for QueryBorrowChecked < ' w , ' s , S , F >
228+ {
229+ }
211230
212- impl < ' w , Q : HecsQuery > Drop for QueryBorrowChecked < ' w , Q > {
231+ impl < ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > Drop
232+ for QueryBorrowChecked < ' w , ' s , S , F >
233+ {
213234 #[ inline]
214235 fn drop ( & mut self ) {
215236 if self . borrowed {
216237 for index in self . archetype_access . immutable . ones ( ) {
217- Q :: Fetch :: release ( & self . archetypes [ index] , & Default :: default ( ) ) ;
238+ F :: release ( & self . archetypes [ index] , self . state ) ;
218239 }
219240
220241 for index in self . archetype_access . mutable . ones ( ) {
221- Q :: Fetch :: release ( & self . archetypes [ index] , & Default :: default ( ) ) ;
242+ F :: release ( & self . archetypes [ index] , self . state ) ;
222243 }
223244 }
224245 }
225246}
226247
227- impl < ' q , ' w , Q : HecsQuery > IntoIterator for & ' q mut QueryBorrowChecked < ' w , Q > {
228- type IntoIter = QueryIter < ' q , ' w , Q > ;
229- type Item = <Q :: Fetch as Fetch < ' q > >:: Item ;
248+ impl < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > IntoIterator
249+ for & ' q mut QueryBorrowChecked < ' w , ' s , S , F >
250+ {
251+ type IntoIter = QueryIter < ' q , ' w , ' s , S , F > ;
252+ // FIXME: do I specify the concrete 'w? I tried to kind of avoid that a little with the `for<'a>
253+ // Fetch<'a>` trait bound.
254+ type Item = <F as Fetch < ' q > >:: Item ;
230255
231256 #[ inline]
232257 fn into_iter ( self ) -> Self :: IntoIter {
@@ -235,17 +260,25 @@ impl<'q, 'w, Q: HecsQuery> IntoIterator for &'q mut QueryBorrowChecked<'w, Q> {
235260}
236261
237262/// Iterator over the set of entities with the components in `Q`
238- pub struct QueryIter < ' q , ' w , Q : HecsQuery > {
239- borrow : & ' q mut QueryBorrowChecked < ' w , Q > ,
263+ pub struct QueryIter < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > {
264+ borrow : & ' q mut QueryBorrowChecked < ' w , ' s , S , F > ,
240265 archetype_index : usize ,
241- iter : Option < ChunkIter < Q > > ,
266+ iter : Option < ChunkIter < ' s , S , F > > ,
242267}
243268
244- unsafe impl < ' q , ' w , Q : HecsQuery > Send for QueryIter < ' q , ' w , Q > { }
245- unsafe impl < ' q , ' w , Q : HecsQuery > Sync for QueryIter < ' q , ' w , Q > { }
269+ unsafe impl < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > Send
270+ for QueryIter < ' q , ' w , ' s , S , F >
271+ {
272+ }
273+ unsafe impl < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > Sync
274+ for QueryIter < ' q , ' w , ' s , S , F >
275+ {
276+ }
246277
247- impl < ' q , ' w , Q : HecsQuery > Iterator for QueryIter < ' q , ' w , Q > {
248- type Item = <Q :: Fetch as Fetch < ' q > >:: Item ;
278+ impl < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > Iterator
279+ for QueryIter < ' q , ' w , ' s , S , F >
280+ {
281+ type Item = <F as Fetch < ' q > >:: Item ;
249282
250283 #[ inline]
251284 fn next ( & mut self ) -> Option < Self :: Item > {
@@ -255,11 +288,10 @@ impl<'q, 'w, Q: HecsQuery> Iterator for QueryIter<'q, 'w, Q> {
255288 let archetype = self . borrow . archetypes . get ( self . archetype_index as usize ) ?;
256289 self . archetype_index += 1 ;
257290 unsafe {
258- self . iter = Q :: Fetch :: get ( archetype, 0 , & Default :: default ( ) ) . map ( |fetch| {
259- ChunkIter {
260- fetch,
261- len : archetype. len ( ) ,
262- }
291+ self . iter = F :: get ( archetype, 0 , self . borrow . state ) . map ( |fetch| ChunkIter {
292+ fetch,
293+ len : archetype. len ( ) ,
294+ state : self . borrow . state ,
263295 } ) ;
264296 }
265297 }
@@ -282,54 +314,59 @@ impl<'q, 'w, Q: HecsQuery> Iterator for QueryIter<'q, 'w, Q> {
282314 }
283315}
284316
285- impl < ' q , ' w , Q : HecsQuery > ExactSizeIterator for QueryIter < ' q , ' w , Q > {
317+ impl < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > ExactSizeIterator
318+ for QueryIter < ' q , ' w , ' s , S , F >
319+ {
286320 fn len ( & self ) -> usize {
287321 self . borrow
288322 . archetypes
289323 . iter ( )
290- . filter ( |& x| Q :: Fetch :: access ( x, & Default :: default ( ) ) . is_some ( ) )
324+ . filter ( |& x| F :: access ( x, self . borrow . state ) . is_some ( ) )
291325 . map ( |x| x. len ( ) )
292326 . sum ( )
293327 }
294328}
295329
296- struct ChunkIter < Q : HecsQuery > {
297- fetch : Q :: Fetch ,
330+ struct ChunkIter < ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > {
331+ fetch : F ,
298332 len : usize ,
333+ state : & ' s S ,
299334}
300335
301- impl < Q : HecsQuery > ChunkIter < Q > {
336+ impl < ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > ChunkIter < ' s , S , F > {
302337 #[ inline]
303- unsafe fn next < ' a > ( & mut self ) -> Option < <Q :: Fetch as Fetch < ' a > >:: Item > {
338+ unsafe fn next < ' a > ( & mut self ) -> Option < <F as Fetch < ' a > >:: Item > {
304339 loop {
305340 if self . len == 0 {
306341 return None ;
307342 }
308343
309344 self . len -= 1 ;
310- if self . fetch . should_skip ( & Default :: default ( ) ) {
345+ if self . fetch . should_skip ( self . state ) {
311346 // we still need to progress the iterator
312- let _ = self . fetch . next ( & Default :: default ( ) ) ;
347+ let _ = self . fetch . next ( self . state ) ;
313348 continue ;
314349 }
315350
316- break Some ( self . fetch . next ( & Default :: default ( ) ) ) ;
351+ break Some ( self . fetch . next ( self . state ) ) ;
317352 }
318353 }
319354}
320355
321356/// Batched version of `QueryIter`
322- pub struct ParIter < ' q , ' w , Q : HecsQuery > {
323- borrow : & ' q mut QueryBorrowChecked < ' w , Q > ,
357+ pub struct ParIter < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > {
358+ borrow : & ' q mut QueryBorrowChecked < ' w , ' s , S , F > ,
324359 archetype_index : usize ,
325360 batch_size : usize ,
326361 batch : usize ,
327362}
328363
329- impl < ' q , ' w , Q : HecsQuery > ParallelIterator < Batch < ' q , Q > > for ParIter < ' q , ' w , Q > {
330- type Item = <Q :: Fetch as Fetch < ' q > >:: Item ;
364+ impl < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > >
365+ ParallelIterator < Batch < ' q , ' s , S , F > > for ParIter < ' q , ' w , ' s , S , F >
366+ {
367+ type Item = <F as Fetch < ' q > >:: Item ;
331368
332- fn next_batch ( & mut self ) -> Option < Batch < ' q , Q > > {
369+ fn next_batch ( & mut self ) -> Option < Batch < ' q , ' s , S , F > > {
333370 loop {
334371 let archetype = self . borrow . archetypes . get ( self . archetype_index ) ?;
335372 let offset = self . batch_size * self . batch ;
@@ -338,15 +375,14 @@ impl<'q, 'w, Q: HecsQuery> ParallelIterator<Batch<'q, Q>> for ParIter<'q, 'w, Q>
338375 self . batch = 0 ;
339376 continue ;
340377 }
341- if let Some ( fetch) =
342- unsafe { Q :: Fetch :: get ( archetype, offset as usize , & Default :: default ( ) ) }
343- {
378+ if let Some ( fetch) = unsafe { F :: get ( archetype, offset as usize , self . borrow . state ) } {
344379 self . batch += 1 ;
345380 return Some ( Batch {
346381 _marker : PhantomData ,
347382 state : ChunkIter {
348383 fetch,
349384 len : self . batch_size . min ( archetype. len ( ) - offset) ,
385+ state : self . borrow . state ,
350386 } ,
351387 } ) ;
352388 } else {
@@ -362,21 +398,26 @@ impl<'q, 'w, Q: HecsQuery> ParallelIterator<Batch<'q, Q>> for ParIter<'q, 'w, Q>
362398}
363399
364400/// A sequence of entities yielded by `ParIter`
365- pub struct Batch < ' q , Q : HecsQuery > {
401+ pub struct Batch < ' q , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > {
366402 _marker : PhantomData < & ' q ( ) > ,
367- state : ChunkIter < Q > ,
403+ state : ChunkIter < ' s , S , F > ,
368404}
369405
370- impl < ' q , ' w , Q : HecsQuery > Iterator for Batch < ' q , Q > {
371- type Item = <Q :: Fetch as Fetch < ' q > >:: Item ;
406+ impl < ' q , ' w , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > Iterator
407+ for Batch < ' q , ' s , S , F >
408+ {
409+ type Item = <F as Fetch < ' q > >:: Item ;
372410
373411 fn next ( & mut self ) -> Option < Self :: Item > {
374412 let components = unsafe { self . state . next ( ) ? } ;
375413 Some ( components)
376414 }
377415}
378416
379- unsafe impl < ' q , Q : HecsQuery > Send for Batch < ' q , Q > { }
417+ unsafe impl < ' q , ' s , S : Default + Sync + Send , F : for < ' a > Fetch < ' a , State = S > > Send
418+ for Batch < ' q , ' s , S , F >
419+ {
420+ }
380421
381422/// A borrow of a `World` sufficient to execute the query `Q` on a single entity
382423pub struct QueryOneChecked < ' a , Q : HecsQuery > {
0 commit comments