@@ -197,6 +197,8 @@ mod tests {
197
197
}
198
198
199
199
mod conditions {
200
+ use crate :: change_detection:: DetectChanges ;
201
+
200
202
use super :: * ;
201
203
202
204
#[ test]
@@ -294,6 +296,155 @@ mod tests {
294
296
schedule. run ( & mut world) ;
295
297
assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
296
298
}
299
+
300
+ #[ test]
301
+ fn system_conditions_and_change_detection ( ) {
302
+ #[ derive( Resource , Default ) ]
303
+ struct Bool2 ( pub bool ) ;
304
+
305
+ let mut world = World :: default ( ) ;
306
+ world. init_resource :: < Counter > ( ) ;
307
+ world. init_resource :: < RunConditionBool > ( ) ;
308
+ world. init_resource :: < Bool2 > ( ) ;
309
+ let mut schedule = Schedule :: default ( ) ;
310
+
311
+ schedule. add_system (
312
+ counting_system
313
+ . run_if ( |res1 : Res < RunConditionBool > | res1. is_changed ( ) )
314
+ . run_if ( |res2 : Res < Bool2 > | res2. is_changed ( ) ) ,
315
+ ) ;
316
+
317
+ // both resource were just added.
318
+ schedule. run ( & mut world) ;
319
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
320
+
321
+ // nothing has changed
322
+ schedule. run ( & mut world) ;
323
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
324
+
325
+ // RunConditionBool has changed, but counting_system did not run
326
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
327
+ schedule. run ( & mut world) ;
328
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
329
+
330
+ // internal state for the bool2 run criteria was updated in the
331
+ // previous run, so system still does not run
332
+ world. get_resource_mut :: < Bool2 > ( ) . unwrap ( ) . 0 = false ;
333
+ schedule. run ( & mut world) ;
334
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
335
+
336
+ // internal state for bool2 was updated, so system still does not run
337
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
338
+ schedule. run ( & mut world) ;
339
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
340
+
341
+ // now check that it works correctly changing Bool2 first and then RunConditionBool
342
+ world. get_resource_mut :: < Bool2 > ( ) . unwrap ( ) . 0 = false ;
343
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
344
+ schedule. run ( & mut world) ;
345
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 2 ) ;
346
+ }
347
+
348
+ #[ test]
349
+ fn system_set_conditions_and_change_detection ( ) {
350
+ #[ derive( Resource , Default ) ]
351
+ struct Bool2 ( pub bool ) ;
352
+
353
+ let mut world = World :: default ( ) ;
354
+ world. init_resource :: < Counter > ( ) ;
355
+ world. init_resource :: < RunConditionBool > ( ) ;
356
+ world. init_resource :: < Bool2 > ( ) ;
357
+ let mut schedule = Schedule :: default ( ) ;
358
+
359
+ schedule. configure_set (
360
+ TestSet :: A
361
+ . run_if ( |res1 : Res < RunConditionBool > | res1. is_changed ( ) )
362
+ . run_if ( |res2 : Res < Bool2 > | res2. is_changed ( ) ) ,
363
+ ) ;
364
+
365
+ schedule. add_system ( counting_system. in_set ( TestSet :: A ) ) ;
366
+
367
+ // both resource were just added.
368
+ schedule. run ( & mut world) ;
369
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
370
+
371
+ // nothing has changed
372
+ schedule. run ( & mut world) ;
373
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
374
+
375
+ // RunConditionBool has changed, but counting_system did not run
376
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
377
+ schedule. run ( & mut world) ;
378
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
379
+
380
+ // internal state for the bool2 run criteria was updated in the
381
+ // previous run, so system still does not run
382
+ world. get_resource_mut :: < Bool2 > ( ) . unwrap ( ) . 0 = false ;
383
+ schedule. run ( & mut world) ;
384
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
385
+
386
+ // internal state for bool2 was updated, so system still does not run
387
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
388
+ schedule. run ( & mut world) ;
389
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
390
+
391
+ // the system only runs when both are changed on the same run
392
+ world. get_resource_mut :: < Bool2 > ( ) . unwrap ( ) . 0 = false ;
393
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
394
+ schedule. run ( & mut world) ;
395
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 2 ) ;
396
+ }
397
+
398
+ #[ test]
399
+ fn mixed_conditions_and_change_detection ( ) {
400
+ #[ derive( Resource , Default ) ]
401
+ struct Bool2 ( pub bool ) ;
402
+
403
+ let mut world = World :: default ( ) ;
404
+ world. init_resource :: < Counter > ( ) ;
405
+ world. init_resource :: < RunConditionBool > ( ) ;
406
+ world. init_resource :: < Bool2 > ( ) ;
407
+ let mut schedule = Schedule :: default ( ) ;
408
+
409
+ schedule
410
+ . configure_set ( TestSet :: A . run_if ( |res1 : Res < RunConditionBool > | res1. is_changed ( ) ) ) ;
411
+
412
+ schedule. add_system (
413
+ counting_system
414
+ . run_if ( |res2 : Res < Bool2 > | res2. is_changed ( ) )
415
+ . in_set ( TestSet :: A ) ,
416
+ ) ;
417
+
418
+ // both resource were just added.
419
+ schedule. run ( & mut world) ;
420
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
421
+
422
+ // nothing has changed
423
+ schedule. run ( & mut world) ;
424
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
425
+
426
+ // RunConditionBool has changed, but counting_system did not run
427
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
428
+ schedule. run ( & mut world) ;
429
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
430
+
431
+ // we now only change bool2 and the system also should not run
432
+ world. get_resource_mut :: < Bool2 > ( ) . unwrap ( ) . 0 = false ;
433
+ schedule. run ( & mut world) ;
434
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
435
+
436
+ // internal state for the bool2 run criteria was updated in the
437
+ // previous run, so system still does not run
438
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
439
+ schedule. run ( & mut world) ;
440
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 1 ) ;
441
+
442
+ // the system only runs when both are changed on the same run
443
+ world. get_resource_mut :: < Bool2 > ( ) . unwrap ( ) . 0 = false ;
444
+ world. get_resource_mut :: < RunConditionBool > ( ) . unwrap ( ) . 0 = false ;
445
+ schedule. run ( & mut world) ;
446
+ assert_eq ! ( world. resource:: <Counter >( ) . 0 . load( Ordering :: Relaxed ) , 2 ) ;
447
+ }
297
448
}
298
449
299
450
mod schedule_build_errors {
0 commit comments