@@ -4,10 +4,10 @@ use crate::{
4
4
bundle:: Bundles ,
5
5
change_detection:: { MaybeLocation , Ticks , TicksMut } ,
6
6
component:: { ComponentId , ComponentTicks , Components , Tick } ,
7
- entity:: Entities ,
7
+ entity:: { Entities , Entity } ,
8
8
query:: {
9
- Access , FilteredAccess , FilteredAccessSet , QueryData , QueryFilter , QuerySingleError ,
10
- QueryState , ReadOnlyQueryData ,
9
+ Access , DebugCheckedUnwrap , FilteredAccess , FilteredAccessSet , QueryData , QueryFilter ,
10
+ QuerySingleError , QueryState , ReadOnlyQueryData ,
11
11
} ,
12
12
resource:: Resource ,
13
13
storage:: ResourceData ,
@@ -65,7 +65,7 @@ use variadics_please::{all_tuples, all_tuples_enumerated};
65
65
/// # #[derive(SystemParam)]
66
66
/// # struct ParamsExample<'w, 's> {
67
67
/// # query:
68
- /// Query<'w, 's , Entity>,
68
+ /// Query<'w, 'w , Entity>,
69
69
/// # res:
70
70
/// Res<'w, SomeResource>,
71
71
/// # res_mut:
@@ -171,7 +171,7 @@ use variadics_please::{all_tuples, all_tuples_enumerated};
171
171
/// #[derive(SystemParam)]
172
172
/// #[system_param(builder)]
173
173
/// pub struct CustomParam<'w, 's> {
174
- /// query: Query<'w, 's , ()>,
174
+ /// query: Query<'w, 'w , ()>,
175
175
/// local: Local<'s, usize>,
176
176
/// }
177
177
///
@@ -321,13 +321,15 @@ unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> Re
321
321
// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
322
322
// this Query conflicts with any prior access, a panic will occur.
323
323
unsafe impl < D : QueryData + ' static , F : QueryFilter + ' static > SystemParam for Query < ' _ , ' _ , D , F > {
324
- type State = QueryState < D , F > ;
325
- type Item < ' w , ' s > = Query < ' w , ' s , D , F > ;
324
+ type State = ( Entity , ComponentId ) ;
325
+ type Item < ' w , ' s > = Query < ' w , ' w , D , F > ;
326
326
327
327
fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
328
- let state = QueryState :: new ( world) ;
328
+ let state: QueryState < D , F > = QueryState :: new ( world) ;
329
329
init_query_param ( world, system_meta, & state) ;
330
- state
330
+ let e = world. spawn ( state) . id ( ) ;
331
+ let id = world. register_component :: < QueryState < D , F > > ( ) ;
332
+ ( e, id)
331
333
}
332
334
333
335
#[ inline]
@@ -336,11 +338,21 @@ unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Qu
336
338
system_meta : & SystemMeta ,
337
339
world : UnsafeWorldCell < ' w > ,
338
340
change_tick : Tick ,
339
- ) -> Self :: Item < ' w , ' s > {
341
+ ) -> Self :: Item < ' w , ' w > {
342
+ let state = world
343
+ . storages ( )
344
+ . sparse_sets
345
+ . get ( state. 1 )
346
+ . debug_checked_unwrap ( )
347
+ . get ( state. 0 )
348
+ . debug_checked_unwrap ( )
349
+ . assert_unique ( )
350
+ . deref_mut :: < QueryState < D , F > > ( ) ;
340
351
// SAFETY: We have registered all of the query's world accesses,
341
352
// so the caller ensures that `world` has permission to access any
342
353
// world data that the query needs.
343
354
// The caller ensures the world matches the one used in init_state.
355
+
344
356
unsafe { state. query_unchecked_with_ticks ( world, system_meta. last_run , change_tick) }
345
357
}
346
358
}
@@ -386,11 +398,11 @@ fn assert_component_access_compatibility(
386
398
// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
387
399
// this Query conflicts with any prior access, a panic will occur.
388
400
unsafe impl < ' a , D : QueryData + ' static , F : QueryFilter + ' static > SystemParam for Single < ' a , D , F > {
389
- type State = QueryState < D , F > ;
401
+ type State = ( Entity , ComponentId ) ;
390
402
type Item < ' w , ' s > = Single < ' w , D , F > ;
391
403
392
404
fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
393
- Query :: init_state ( world, system_meta)
405
+ Query :: < D , F > :: init_state ( world, system_meta)
394
406
}
395
407
396
408
#[ inline]
@@ -400,10 +412,8 @@ unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam fo
400
412
world : UnsafeWorldCell < ' w > ,
401
413
change_tick : Tick ,
402
414
) -> Self :: Item < ' w , ' s > {
403
- // SAFETY: State ensures that the components it accesses are not accessible somewhere elsewhere.
404
- // The caller ensures the world matches the one used in init_state.
405
- let query =
406
- unsafe { state. query_unchecked_with_ticks ( world, system_meta. last_run , change_tick) } ;
415
+ let query: Query < ' _ , ' _ , D , F > = Query :: get_param ( state, system_meta, world, change_tick) ;
416
+
407
417
let single = query
408
418
. single_inner ( )
409
419
. expect ( "The query was expected to contain exactly one matching entity." ) ;
@@ -419,12 +429,9 @@ unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam fo
419
429
system_meta : & SystemMeta ,
420
430
world : UnsafeWorldCell ,
421
431
) -> Result < ( ) , SystemParamValidationError > {
422
- // SAFETY: State ensures that the components it accesses are not mutably accessible elsewhere
423
- // and the query is read only.
424
- // The caller ensures the world matches the one used in init_state.
425
- let query = unsafe {
426
- state. query_unchecked_with_ticks ( world, system_meta. last_run , world. change_tick ( ) )
427
- } ;
432
+ let query: Query < ' _ , ' _ , D , F > =
433
+ Query :: get_param ( state, system_meta, world, world. change_tick ( ) ) ;
434
+
428
435
match query. single_inner ( ) {
429
436
Ok ( _) => Ok ( ( ) ) ,
430
437
Err ( QuerySingleError :: NoEntities ( _) ) => Err (
@@ -448,11 +455,11 @@ unsafe impl<'a, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOn
448
455
unsafe impl < D : QueryData + ' static , F : QueryFilter + ' static > SystemParam
449
456
for Populated < ' _ , ' _ , D , F >
450
457
{
451
- type State = QueryState < D , F > ;
452
- type Item < ' w , ' s > = Populated < ' w , ' s , D , F > ;
458
+ type State = ( Entity , ComponentId ) ;
459
+ type Item < ' w , ' s > = Populated < ' w , ' w , D , F > ;
453
460
454
461
fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
455
- Query :: init_state ( world, system_meta)
462
+ Query :: < D , F > :: init_state ( world, system_meta)
456
463
}
457
464
458
465
#[ inline]
@@ -461,7 +468,7 @@ unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
461
468
system_meta : & SystemMeta ,
462
469
world : UnsafeWorldCell < ' w > ,
463
470
change_tick : Tick ,
464
- ) -> Self :: Item < ' w , ' s > {
471
+ ) -> Self :: Item < ' w , ' w > {
465
472
// SAFETY: Delegate to existing `SystemParam` implementations.
466
473
let query = unsafe { Query :: get_param ( state, system_meta, world, change_tick) } ;
467
474
Populated ( query)
@@ -473,12 +480,9 @@ unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
473
480
system_meta : & SystemMeta ,
474
481
world : UnsafeWorldCell ,
475
482
) -> Result < ( ) , SystemParamValidationError > {
476
- // SAFETY:
477
- // - We have read-only access to the components accessed by query.
478
- // - The caller ensures the world matches the one used in init_state.
479
- let query = unsafe {
480
- state. query_unchecked_with_ticks ( world, system_meta. last_run , world. change_tick ( ) )
481
- } ;
483
+ // SAFETY: Delegate to existing `SystemParam` implementations.
484
+ let query: Query < ' _ , ' _ , D , F > =
485
+ unsafe { Query :: get_param ( state, system_meta, world, world. change_tick ( ) ) } ;
482
486
if query. is_empty ( ) {
483
487
Err ( SystemParamValidationError :: skipped :: < Self > (
484
488
"No matching entities" ,
@@ -2573,11 +2577,10 @@ mod tests {
2573
2577
#[ derive( SystemParam ) ]
2574
2578
pub struct SpecialQuery <
2575
2579
' w ,
2576
- ' s ,
2577
2580
D : QueryData + Send + Sync + ' static ,
2578
2581
F : QueryFilter + Send + Sync + ' static = ( ) ,
2579
2582
> {
2580
- _query : Query < ' w , ' s , D , F > ,
2583
+ _query : Query < ' w , ' w , D , F > ,
2581
2584
}
2582
2585
2583
2586
fn my_system ( _: SpecialQuery < ( ) , ( ) > ) { }
@@ -2706,11 +2709,11 @@ mod tests {
2706
2709
#[ test]
2707
2710
fn system_param_where_clause ( ) {
2708
2711
#[ derive( SystemParam ) ]
2709
- pub struct WhereParam < ' w , ' s , D >
2712
+ pub struct WhereParam < ' w , D >
2710
2713
where
2711
2714
D : ' static + QueryData ,
2712
2715
{
2713
- _q : Query < ' w , ' s , D , ( ) > ,
2716
+ _q : Query < ' w , ' w , D , ( ) > ,
2714
2717
}
2715
2718
2716
2719
fn my_system ( _: WhereParam < ( ) > ) { }
0 commit comments