@@ -19,18 +19,19 @@ unsafe fn debug_checked_unreachable() -> ! {
19
19
20
20
#[ cfg( test) ]
21
21
mod tests {
22
- use super :: AnyOf ;
22
+ use super :: WorldQuery ;
23
+ use crate :: prelude:: { AnyOf , Entity , Or , With , Without } ;
23
24
use crate :: { self as bevy_ecs, component:: Component , world:: World } ;
24
25
use std:: collections:: HashSet ;
25
26
26
- #[ derive( Component , Debug , Hash , Eq , PartialEq ) ]
27
+ #[ derive( Component , Debug , Hash , Eq , PartialEq , Clone , Copy ) ]
27
28
struct A ( usize ) ;
28
- #[ derive( Component , Debug , Eq , PartialEq ) ]
29
+ #[ derive( Component , Debug , Eq , PartialEq , Clone , Copy ) ]
29
30
struct B ( usize ) ;
30
- #[ derive( Component , Debug , Eq , PartialEq ) ]
31
+ #[ derive( Component , Debug , Eq , PartialEq , Clone , Copy ) ]
31
32
struct C ( usize ) ;
32
33
33
- #[ derive( Component , Debug , Eq , PartialEq ) ]
34
+ #[ derive( Component , Debug , Eq , PartialEq , Clone , Copy ) ]
34
35
#[ component( storage = "SparseSet" ) ]
35
36
struct Sparse ( usize ) ;
36
37
@@ -337,4 +338,182 @@ mod tests {
337
338
vec![ ( Some ( & A ( 1 ) ) , Some ( & B ( 2 ) ) ) , ( Some ( & A ( 2 ) ) , None ) , ]
338
339
) ;
339
340
}
341
+
342
+ #[ test]
343
+ #[ should_panic = "&mut bevy_ecs::query::tests::A conflicts with a previous access in this query." ]
344
+ fn self_conflicting_worldquery ( ) {
345
+ #[ derive( WorldQuery ) ]
346
+ #[ world_query( mutable) ]
347
+ struct SelfConflicting {
348
+ a : & ' static mut A ,
349
+ b : & ' static mut A ,
350
+ }
351
+
352
+ let mut world = World :: new ( ) ;
353
+ world. query :: < SelfConflicting > ( ) ;
354
+ }
355
+
356
+ #[ test]
357
+ fn derived_worldqueries ( ) {
358
+ let mut world = World :: new ( ) ;
359
+
360
+ world. spawn ( ) . insert_bundle ( ( A ( 10 ) , B ( 18 ) , C ( 3 ) , Sparse ( 4 ) ) ) ;
361
+
362
+ world. spawn ( ) . insert_bundle ( ( A ( 101 ) , B ( 148 ) , C ( 13 ) ) ) ;
363
+ world. spawn ( ) . insert_bundle ( ( A ( 51 ) , B ( 46 ) , Sparse ( 72 ) ) ) ;
364
+ world. spawn ( ) . insert_bundle ( ( A ( 398 ) , C ( 6 ) , Sparse ( 9 ) ) ) ;
365
+ world. spawn ( ) . insert_bundle ( ( B ( 11 ) , C ( 28 ) , Sparse ( 92 ) ) ) ;
366
+
367
+ world. spawn ( ) . insert_bundle ( ( C ( 18348 ) , Sparse ( 101 ) ) ) ;
368
+ world. spawn ( ) . insert_bundle ( ( B ( 839 ) , Sparse ( 5 ) ) ) ;
369
+ world. spawn ( ) . insert_bundle ( ( B ( 6721 ) , C ( 122 ) ) ) ;
370
+ world. spawn ( ) . insert_bundle ( ( A ( 220 ) , Sparse ( 63 ) ) ) ;
371
+ world. spawn ( ) . insert_bundle ( ( A ( 1092 ) , C ( 382 ) ) ) ;
372
+ world. spawn ( ) . insert_bundle ( ( A ( 2058 ) , B ( 3019 ) ) ) ;
373
+
374
+ world. spawn ( ) . insert_bundle ( ( B ( 38 ) , C ( 8 ) , Sparse ( 100 ) ) ) ;
375
+ world. spawn ( ) . insert_bundle ( ( A ( 111 ) , C ( 52 ) , Sparse ( 1 ) ) ) ;
376
+ world. spawn ( ) . insert_bundle ( ( A ( 599 ) , B ( 39 ) , Sparse ( 13 ) ) ) ;
377
+ world. spawn ( ) . insert_bundle ( ( A ( 55 ) , B ( 66 ) , C ( 77 ) ) ) ;
378
+
379
+ world. spawn ( ) ;
380
+
381
+ {
382
+ #[ derive( WorldQuery ) ]
383
+ struct CustomAB {
384
+ a : & ' static A ,
385
+ b : & ' static B ,
386
+ }
387
+
388
+ let custom_param_data = world
389
+ . query :: < CustomAB > ( )
390
+ . iter ( & world)
391
+ . map ( |item| ( * item. a , * item. b ) )
392
+ . collect :: < Vec < _ > > ( ) ;
393
+ let normal_data = world
394
+ . query :: < ( & A , & B ) > ( )
395
+ . iter ( & world)
396
+ . map ( |( a, b) | ( * a, * b) )
397
+ . collect :: < Vec < _ > > ( ) ;
398
+ assert_eq ! ( custom_param_data, normal_data) ;
399
+ }
400
+
401
+ {
402
+ #[ derive( WorldQuery ) ]
403
+ struct FancyParam {
404
+ e : Entity ,
405
+ b : & ' static B ,
406
+ opt : Option < & ' static Sparse > ,
407
+ }
408
+
409
+ let custom_param_data = world
410
+ . query :: < FancyParam > ( )
411
+ . iter ( & world)
412
+ . map ( |fancy| ( fancy. e , * fancy. b , fancy. opt . copied ( ) ) )
413
+ . collect :: < Vec < _ > > ( ) ;
414
+ let normal_data = world
415
+ . query :: < ( Entity , & B , Option < & Sparse > ) > ( )
416
+ . iter ( & world)
417
+ . map ( |( e, b, opt) | ( e, * b, opt. copied ( ) ) )
418
+ . collect :: < Vec < _ > > ( ) ;
419
+ assert_eq ! ( custom_param_data, normal_data) ;
420
+ }
421
+
422
+ {
423
+ #[ derive( WorldQuery ) ]
424
+ struct MaybeBSparse {
425
+ blah : Option < ( & ' static B , & ' static Sparse ) > ,
426
+ }
427
+ #[ derive( WorldQuery ) ]
428
+ struct MatchEverything {
429
+ abcs : AnyOf < ( & ' static A , & ' static B , & ' static C ) > ,
430
+ opt_bsparse : MaybeBSparse ,
431
+ }
432
+
433
+ let custom_param_data = world
434
+ . query :: < MatchEverything > ( )
435
+ . iter ( & world)
436
+ . map (
437
+ |MatchEverythingItem {
438
+ abcs : ( a, b, c) ,
439
+ opt_bsparse : MaybeBSparseItem { blah : bsparse } ,
440
+ } | {
441
+ (
442
+ ( a. copied ( ) , b. copied ( ) , c. copied ( ) ) ,
443
+ bsparse. map ( |( b, sparse) | ( * b, * sparse) ) ,
444
+ )
445
+ } ,
446
+ )
447
+ . collect :: < Vec < _ > > ( ) ;
448
+ let normal_data = world
449
+ . query :: < ( AnyOf < ( & A , & B , & C ) > , Option < ( & B , & Sparse ) > ) > ( )
450
+ . iter ( & world)
451
+ . map ( |( ( a, b, c) , bsparse) | {
452
+ (
453
+ ( a. copied ( ) , b. copied ( ) , c. copied ( ) ) ,
454
+ bsparse. map ( |( b, sparse) | ( * b, * sparse) ) ,
455
+ )
456
+ } )
457
+ . collect :: < Vec < _ > > ( ) ;
458
+ assert_eq ! ( custom_param_data, normal_data)
459
+ }
460
+
461
+ {
462
+ #[ derive( WorldQuery ) ]
463
+ struct AOrBFilter {
464
+ a : Or < ( With < A > , With < B > ) > ,
465
+ }
466
+ #[ derive( WorldQuery ) ]
467
+ struct NoSparseThatsSlow {
468
+ no : Without < Sparse > ,
469
+ }
470
+
471
+ let custom_param_entities = world
472
+ . query_filtered :: < Entity , ( AOrBFilter , NoSparseThatsSlow ) > ( )
473
+ . iter ( & world)
474
+ . collect :: < Vec < _ > > ( ) ;
475
+ let normal_entities = world
476
+ . query_filtered :: < Entity , ( Or < ( With < A > , With < B > ) > , Without < Sparse > ) > ( )
477
+ . iter ( & world)
478
+ . collect :: < Vec < _ > > ( ) ;
479
+ assert_eq ! ( custom_param_entities, normal_entities) ;
480
+ }
481
+
482
+ {
483
+ #[ derive( WorldQuery ) ]
484
+ struct CSparseFilter {
485
+ tuple_structs_pls : With < C > ,
486
+ ugh : With < Sparse > ,
487
+ }
488
+
489
+ let custom_param_entities = world
490
+ . query_filtered :: < Entity , CSparseFilter > ( )
491
+ . iter ( & world)
492
+ . collect :: < Vec < _ > > ( ) ;
493
+ let normal_entities = world
494
+ . query_filtered :: < Entity , ( With < C > , With < Sparse > ) > ( )
495
+ . iter ( & world)
496
+ . collect :: < Vec < _ > > ( ) ;
497
+ assert_eq ! ( custom_param_entities, normal_entities) ;
498
+ }
499
+
500
+ {
501
+ #[ derive( WorldQuery ) ]
502
+ struct WithoutComps {
503
+ _1 : Without < A > ,
504
+ _2 : Without < B > ,
505
+ _3 : Without < C > ,
506
+ }
507
+
508
+ let custom_param_entities = world
509
+ . query_filtered :: < Entity , WithoutComps > ( )
510
+ . iter ( & world)
511
+ . collect :: < Vec < _ > > ( ) ;
512
+ let normal_entities = world
513
+ . query_filtered :: < Entity , ( Without < A > , Without < B > , Without < C > ) > ( )
514
+ . iter ( & world)
515
+ . collect :: < Vec < _ > > ( ) ;
516
+ assert_eq ! ( custom_param_entities, normal_entities) ;
517
+ }
518
+ }
340
519
}
0 commit comments