@@ -482,9 +482,20 @@ fn topological_order(
482
482
/// Returns vector containing all pairs of indices of systems with ambiguous execution order.
483
483
/// Systems must be topologically sorted beforehand.
484
484
fn find_ambiguities ( systems : & [ impl SystemContainer ] ) -> Vec < ( usize , usize ) > {
485
+ let mut ambiguity_set_labels = HashMap :: default ( ) ;
486
+ for set in systems. iter ( ) . flat_map ( |c| c. ambiguity_sets ( ) ) {
487
+ let len = ambiguity_set_labels. len ( ) ;
488
+ ambiguity_set_labels. entry ( set) . or_insert ( len) ;
489
+ }
490
+ let mut all_ambiguity_sets = Vec :: < FixedBitSet > :: with_capacity ( systems. len ( ) ) ;
485
491
let mut all_dependencies = Vec :: < FixedBitSet > :: with_capacity ( systems. len ( ) ) ;
486
492
let mut all_dependants = Vec :: < FixedBitSet > :: with_capacity ( systems. len ( ) ) ;
487
493
for ( index, container) in systems. iter ( ) . enumerate ( ) {
494
+ let mut ambiguity_sets = FixedBitSet :: with_capacity ( ambiguity_set_labels. len ( ) ) ;
495
+ for set in container. ambiguity_sets ( ) {
496
+ ambiguity_sets. insert ( ambiguity_set_labels[ set] ) ;
497
+ }
498
+ all_ambiguity_sets. push ( ambiguity_sets) ;
488
499
let mut dependencies = FixedBitSet :: with_capacity ( systems. len ( ) ) ;
489
500
for & dependency in container. dependencies ( ) {
490
501
dependencies. union_with ( & all_dependencies[ dependency] ) ;
@@ -522,7 +533,10 @@ fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize)> {
522
533
for index_b in full_bitset. difference ( & relations)
523
534
/*.take(index_a)*/
524
535
{
525
- if !processed. contains ( index_b) && !systems[ index_a] . is_compatible ( & systems[ index_b] ) {
536
+ if !processed. contains ( index_b)
537
+ && all_ambiguity_sets[ index_a] . is_disjoint ( & all_ambiguity_sets[ index_b] )
538
+ && !systems[ index_a] . is_compatible ( & systems[ index_b] )
539
+ {
526
540
ambiguities. push ( ( index_a, index_b) ) ;
527
541
}
528
542
}
@@ -1208,6 +1222,27 @@ mod tests {
1208
1222
) ;
1209
1223
assert_eq ! ( ambiguities. len( ) , 2 ) ;
1210
1224
1225
+ let mut stage = SystemStage :: parallel ( )
1226
+ . with_system ( component. system ( ) . label ( "0" ) )
1227
+ . with_system (
1228
+ resource
1229
+ . system ( )
1230
+ . label ( "1" )
1231
+ . after ( "0" )
1232
+ . in_ambiguity_set ( "a" ) ,
1233
+ )
1234
+ . with_system ( empty. system ( ) . label ( "2" ) )
1235
+ . with_system ( component. system ( ) . label ( "3" ) . after ( "2" ) . before ( "4" ) )
1236
+ . with_system ( resource. system ( ) . label ( "4" ) . in_ambiguity_set ( "a" ) ) ;
1237
+ stage. initialize_systems ( & mut world, & mut resources) ;
1238
+ stage. rebuild_orders_and_dependencies ( ) ;
1239
+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1240
+ assert ! (
1241
+ ambiguities. contains( & ( "0" . into( ) , "3" . into( ) ) )
1242
+ || ambiguities. contains( & ( "3" . into( ) , "0" . into( ) ) )
1243
+ ) ;
1244
+ assert_eq ! ( ambiguities. len( ) , 1 ) ;
1245
+
1211
1246
let mut stage = SystemStage :: parallel ( )
1212
1247
. with_system ( component. system ( ) . label ( "0" ) . before ( "2" ) )
1213
1248
. with_system ( component. system ( ) . label ( "1" ) . before ( "2" ) )
@@ -1248,6 +1283,30 @@ mod tests {
1248
1283
) ;
1249
1284
assert_eq ! ( ambiguities. len( ) , 1 ) ;
1250
1285
1286
+ let mut stage = SystemStage :: parallel ( )
1287
+ . with_system ( component. system ( ) . label ( "0" ) . before ( "1" ) . before ( "2" ) )
1288
+ . with_system ( component. system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1289
+ . with_system ( component. system ( ) . label ( "2" ) . in_ambiguity_set ( "a" ) )
1290
+ . with_system ( component. system ( ) . label ( "3" ) . after ( "1" ) . after ( "2" ) ) ;
1291
+ stage. initialize_systems ( & mut world, & mut resources) ;
1292
+ stage. rebuild_orders_and_dependencies ( ) ;
1293
+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1294
+ assert_eq ! ( ambiguities. len( ) , 0 ) ;
1295
+
1296
+ let mut stage = SystemStage :: parallel ( )
1297
+ . with_system ( component. system ( ) . label ( "0" ) . before ( "1" ) . before ( "2" ) )
1298
+ . with_system ( component. system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1299
+ . with_system ( component. system ( ) . label ( "2" ) . in_ambiguity_set ( "b" ) )
1300
+ . with_system ( component. system ( ) . label ( "3" ) . after ( "1" ) . after ( "2" ) ) ;
1301
+ stage. initialize_systems ( & mut world, & mut resources) ;
1302
+ stage. rebuild_orders_and_dependencies ( ) ;
1303
+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1304
+ assert ! (
1305
+ ambiguities. contains( & ( "1" . into( ) , "2" . into( ) ) )
1306
+ || ambiguities. contains( & ( "2" . into( ) , "1" . into( ) ) )
1307
+ ) ;
1308
+ assert_eq ! ( ambiguities. len( ) , 1 ) ;
1309
+
1251
1310
let mut stage = SystemStage :: parallel ( )
1252
1311
. with_system (
1253
1312
component
@@ -1300,6 +1359,76 @@ mod tests {
1300
1359
) ;
1301
1360
assert_eq ! ( ambiguities. len( ) , 6 ) ;
1302
1361
1362
+ let mut stage = SystemStage :: parallel ( )
1363
+ . with_system (
1364
+ component
1365
+ . system ( )
1366
+ . label ( "0" )
1367
+ . before ( "1" )
1368
+ . before ( "2" )
1369
+ . before ( "3" )
1370
+ . before ( "4" ) ,
1371
+ )
1372
+ . with_system ( component. system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1373
+ . with_system ( component. system ( ) . label ( "2" ) . in_ambiguity_set ( "a" ) )
1374
+ . with_system ( component. system ( ) . label ( "3" ) . in_ambiguity_set ( "a" ) )
1375
+ . with_system ( component. system ( ) . label ( "4" ) . in_ambiguity_set ( "a" ) )
1376
+ . with_system (
1377
+ component
1378
+ . system ( )
1379
+ . label ( "5" )
1380
+ . after ( "1" )
1381
+ . after ( "2" )
1382
+ . after ( "3" )
1383
+ . after ( "4" ) ,
1384
+ ) ;
1385
+ stage. initialize_systems ( & mut world, & mut resources) ;
1386
+ stage. rebuild_orders_and_dependencies ( ) ;
1387
+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1388
+ assert_eq ! ( ambiguities. len( ) , 0 ) ;
1389
+
1390
+ let mut stage = SystemStage :: parallel ( )
1391
+ . with_system (
1392
+ component
1393
+ . system ( )
1394
+ . label ( "0" )
1395
+ . before ( "1" )
1396
+ . before ( "2" )
1397
+ . before ( "3" )
1398
+ . before ( "4" ) ,
1399
+ )
1400
+ . with_system ( component. system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1401
+ . with_system ( component. system ( ) . label ( "2" ) . in_ambiguity_set ( "a" ) )
1402
+ . with_system (
1403
+ component
1404
+ . system ( )
1405
+ . label ( "3" )
1406
+ . in_ambiguity_set ( "a" )
1407
+ . in_ambiguity_set ( "b" ) ,
1408
+ )
1409
+ . with_system ( component. system ( ) . label ( "4" ) . in_ambiguity_set ( "b" ) )
1410
+ . with_system (
1411
+ component
1412
+ . system ( )
1413
+ . label ( "5" )
1414
+ . after ( "1" )
1415
+ . after ( "2" )
1416
+ . after ( "3" )
1417
+ . after ( "4" ) ,
1418
+ ) ;
1419
+ stage. initialize_systems ( & mut world, & mut resources) ;
1420
+ stage. rebuild_orders_and_dependencies ( ) ;
1421
+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1422
+ assert ! (
1423
+ ambiguities. contains( & ( "1" . into( ) , "4" . into( ) ) )
1424
+ || ambiguities. contains( & ( "4" . into( ) , "1" . into( ) ) )
1425
+ ) ;
1426
+ assert ! (
1427
+ ambiguities. contains( & ( "2" . into( ) , "4" . into( ) ) )
1428
+ || ambiguities. contains( & ( "4" . into( ) , "2" . into( ) ) )
1429
+ ) ;
1430
+ assert_eq ! ( ambiguities. len( ) , 2 ) ;
1431
+
1303
1432
let mut stage = SystemStage :: parallel ( )
1304
1433
. with_system ( empty. exclusive_system ( ) . label ( "0" ) )
1305
1434
. with_system ( empty. exclusive_system ( ) . label ( "1" ) . after ( "0" ) )
@@ -1349,5 +1478,44 @@ mod tests {
1349
1478
|| ambiguities. contains( & ( "5" . into( ) , "2" . into( ) ) )
1350
1479
) ;
1351
1480
assert_eq ! ( ambiguities. len( ) , 6 ) ;
1481
+
1482
+ let mut stage = SystemStage :: parallel ( )
1483
+ . with_system ( empty. exclusive_system ( ) . label ( "0" ) . before ( "1" ) . before ( "3" ) )
1484
+ . with_system ( empty. exclusive_system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1485
+ . with_system ( empty. exclusive_system ( ) . label ( "2" ) . after ( "1" ) )
1486
+ . with_system ( empty. exclusive_system ( ) . label ( "3" ) . in_ambiguity_set ( "a" ) )
1487
+ . with_system ( empty. exclusive_system ( ) . label ( "4" ) . after ( "3" ) . before ( "5" ) )
1488
+ . with_system ( empty. exclusive_system ( ) . label ( "5" ) . in_ambiguity_set ( "a" ) )
1489
+ . with_system ( empty. exclusive_system ( ) . label ( "6" ) . after ( "2" ) . after ( "5" ) ) ;
1490
+ stage. initialize_systems ( & mut world, & mut resources) ;
1491
+ stage. rebuild_orders_and_dependencies ( ) ;
1492
+ let ambiguities = find_ambiguities_labels ( & stage. exclusive_at_start ) ;
1493
+ assert ! (
1494
+ ambiguities. contains( & ( "2" . into( ) , "3" . into( ) ) )
1495
+ || ambiguities. contains( & ( "3" . into( ) , "2" . into( ) ) )
1496
+ ) ;
1497
+ assert ! (
1498
+ ambiguities. contains( & ( "1" . into( ) , "4" . into( ) ) )
1499
+ || ambiguities. contains( & ( "4" . into( ) , "1" . into( ) ) )
1500
+ ) ;
1501
+ assert ! (
1502
+ ambiguities. contains( & ( "2" . into( ) , "4" . into( ) ) )
1503
+ || ambiguities. contains( & ( "4" . into( ) , "2" . into( ) ) )
1504
+ ) ;
1505
+ assert ! (
1506
+ ambiguities. contains( & ( "2" . into( ) , "5" . into( ) ) )
1507
+ || ambiguities. contains( & ( "5" . into( ) , "2" . into( ) ) )
1508
+ ) ;
1509
+ assert_eq ! ( ambiguities. len( ) , 4 ) ;
1510
+
1511
+ let mut stage = SystemStage :: parallel ( )
1512
+ . with_system ( empty. exclusive_system ( ) . label ( "0" ) . in_ambiguity_set ( "a" ) )
1513
+ . with_system ( empty. exclusive_system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1514
+ . with_system ( empty. exclusive_system ( ) . label ( "2" ) . in_ambiguity_set ( "a" ) )
1515
+ . with_system ( empty. exclusive_system ( ) . label ( "3" ) . in_ambiguity_set ( "a" ) ) ;
1516
+ stage. initialize_systems ( & mut world, & mut resources) ;
1517
+ stage. rebuild_orders_and_dependencies ( ) ;
1518
+ let ambiguities = find_ambiguities_labels ( & stage. exclusive_at_start ) ;
1519
+ assert_eq ! ( ambiguities. len( ) , 0 ) ;
1352
1520
}
1353
1521
}
0 commit comments