@@ -482,9 +482,20 @@ fn topological_order(
482482/// Returns vector containing all pairs of indices of systems with ambiguous execution order.
483483/// Systems must be topologically sorted beforehand.
484484fn 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 ( ) ) ;
485491 let mut all_dependencies = Vec :: < FixedBitSet > :: with_capacity ( systems. len ( ) ) ;
486492 let mut all_dependants = Vec :: < FixedBitSet > :: with_capacity ( systems. len ( ) ) ;
487493 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) ;
488499 let mut dependencies = FixedBitSet :: with_capacity ( systems. len ( ) ) ;
489500 for & dependency in container. dependencies ( ) {
490501 dependencies. union_with ( & all_dependencies[ dependency] ) ;
@@ -522,7 +533,10 @@ fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize)> {
522533 for index_b in full_bitset. difference ( & relations)
523534 /*.take(index_a)*/
524535 {
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+ {
526540 ambiguities. push ( ( index_a, index_b) ) ;
527541 }
528542 }
@@ -1207,6 +1221,27 @@ mod tests {
12071221 ) ;
12081222 assert_eq ! ( ambiguities. len( ) , 2 ) ;
12091223
1224+ let mut stage = SystemStage :: parallel ( )
1225+ . with_system ( component. system ( ) . label ( "0" ) )
1226+ . with_system (
1227+ resource
1228+ . system ( )
1229+ . label ( "1" )
1230+ . after ( "0" )
1231+ . in_ambiguity_set ( "a" ) ,
1232+ )
1233+ . with_system ( empty. system ( ) . label ( "2" ) )
1234+ . with_system ( component. system ( ) . label ( "3" ) . after ( "2" ) . before ( "4" ) )
1235+ . with_system ( resource. system ( ) . label ( "4" ) . in_ambiguity_set ( "a" ) ) ;
1236+ stage. initialize_systems ( & mut world, & mut resources) ;
1237+ stage. rebuild_orders_and_dependencies ( ) ;
1238+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1239+ assert ! (
1240+ ambiguities. contains( & ( Box :: new( "0" ) , Box :: new( "3" ) ) )
1241+ || ambiguities. contains( & ( Box :: new( "3" ) , Box :: new( "0" ) ) )
1242+ ) ;
1243+ assert_eq ! ( ambiguities. len( ) , 1 ) ;
1244+
12101245 let mut stage = SystemStage :: parallel ( )
12111246 . with_system ( component. system ( ) . label ( "0" ) . before ( "2" ) )
12121247 . with_system ( component. system ( ) . label ( "1" ) . before ( "2" ) )
@@ -1247,6 +1282,30 @@ mod tests {
12471282 ) ;
12481283 assert_eq ! ( ambiguities. len( ) , 1 ) ;
12491284
1285+ let mut stage = SystemStage :: parallel ( )
1286+ . with_system ( component. system ( ) . label ( "0" ) . before ( "1" ) . before ( "2" ) )
1287+ . with_system ( component. system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1288+ . with_system ( component. system ( ) . label ( "2" ) . in_ambiguity_set ( "a" ) )
1289+ . with_system ( component. system ( ) . label ( "3" ) . after ( "1" ) . after ( "2" ) ) ;
1290+ stage. initialize_systems ( & mut world, & mut resources) ;
1291+ stage. rebuild_orders_and_dependencies ( ) ;
1292+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1293+ assert_eq ! ( ambiguities. len( ) , 0 ) ;
1294+
1295+ let mut stage = SystemStage :: parallel ( )
1296+ . with_system ( component. system ( ) . label ( "0" ) . before ( "1" ) . before ( "2" ) )
1297+ . with_system ( component. system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1298+ . with_system ( component. system ( ) . label ( "2" ) . in_ambiguity_set ( "b" ) )
1299+ . with_system ( component. system ( ) . label ( "3" ) . after ( "1" ) . after ( "2" ) ) ;
1300+ stage. initialize_systems ( & mut world, & mut resources) ;
1301+ stage. rebuild_orders_and_dependencies ( ) ;
1302+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1303+ assert ! (
1304+ ambiguities. contains( & ( Box :: new( "1" ) , Box :: new( "2" ) ) )
1305+ || ambiguities. contains( & ( Box :: new( "2" ) , Box :: new( "1" ) ) )
1306+ ) ;
1307+ assert_eq ! ( ambiguities. len( ) , 1 ) ;
1308+
12501309 let mut stage = SystemStage :: parallel ( )
12511310 . with_system (
12521311 component
@@ -1299,6 +1358,76 @@ mod tests {
12991358 ) ;
13001359 assert_eq ! ( ambiguities. len( ) , 6 ) ;
13011360
1361+ let mut stage = SystemStage :: parallel ( )
1362+ . with_system (
1363+ component
1364+ . system ( )
1365+ . label ( "0" )
1366+ . before ( "1" )
1367+ . before ( "2" )
1368+ . before ( "3" )
1369+ . before ( "4" ) ,
1370+ )
1371+ . with_system ( component. system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1372+ . with_system ( component. system ( ) . label ( "2" ) . in_ambiguity_set ( "a" ) )
1373+ . with_system ( component. system ( ) . label ( "3" ) . in_ambiguity_set ( "a" ) )
1374+ . with_system ( component. system ( ) . label ( "4" ) . in_ambiguity_set ( "a" ) )
1375+ . with_system (
1376+ component
1377+ . system ( )
1378+ . label ( "5" )
1379+ . after ( "1" )
1380+ . after ( "2" )
1381+ . after ( "3" )
1382+ . after ( "4" ) ,
1383+ ) ;
1384+ stage. initialize_systems ( & mut world, & mut resources) ;
1385+ stage. rebuild_orders_and_dependencies ( ) ;
1386+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1387+ assert_eq ! ( ambiguities. len( ) , 0 ) ;
1388+
1389+ let mut stage = SystemStage :: parallel ( )
1390+ . with_system (
1391+ component
1392+ . system ( )
1393+ . label ( "0" )
1394+ . before ( "1" )
1395+ . before ( "2" )
1396+ . before ( "3" )
1397+ . before ( "4" ) ,
1398+ )
1399+ . with_system ( component. system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1400+ . with_system ( component. system ( ) . label ( "2" ) . in_ambiguity_set ( "a" ) )
1401+ . with_system (
1402+ component
1403+ . system ( )
1404+ . label ( "3" )
1405+ . in_ambiguity_set ( "a" )
1406+ . in_ambiguity_set ( "b" ) ,
1407+ )
1408+ . with_system ( component. system ( ) . label ( "4" ) . in_ambiguity_set ( "b" ) )
1409+ . with_system (
1410+ component
1411+ . system ( )
1412+ . label ( "5" )
1413+ . after ( "1" )
1414+ . after ( "2" )
1415+ . after ( "3" )
1416+ . after ( "4" ) ,
1417+ ) ;
1418+ stage. initialize_systems ( & mut world, & mut resources) ;
1419+ stage. rebuild_orders_and_dependencies ( ) ;
1420+ let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1421+ assert ! (
1422+ ambiguities. contains( & ( Box :: new( "1" ) , Box :: new( "4" ) ) )
1423+ || ambiguities. contains( & ( Box :: new( "4" ) , Box :: new( "1" ) ) )
1424+ ) ;
1425+ assert ! (
1426+ ambiguities. contains( & ( Box :: new( "2" ) , Box :: new( "4" ) ) )
1427+ || ambiguities. contains( & ( Box :: new( "4" ) , Box :: new( "2" ) ) )
1428+ ) ;
1429+ assert_eq ! ( ambiguities. len( ) , 2 ) ;
1430+
13021431 let mut stage = SystemStage :: parallel ( )
13031432 . with_system ( empty. exclusive_system ( ) . label ( "0" ) )
13041433 . with_system ( empty. exclusive_system ( ) . label ( "1" ) . after ( "0" ) )
@@ -1348,5 +1477,44 @@ mod tests {
13481477 || ambiguities. contains( & ( Box :: new( "5" ) , Box :: new( "2" ) ) )
13491478 ) ;
13501479 assert_eq ! ( ambiguities. len( ) , 6 ) ;
1480+
1481+ let mut stage = SystemStage :: parallel ( )
1482+ . with_system ( empty. exclusive_system ( ) . label ( "0" ) . before ( "1" ) . before ( "3" ) )
1483+ . with_system ( empty. exclusive_system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1484+ . with_system ( empty. exclusive_system ( ) . label ( "2" ) . after ( "1" ) )
1485+ . with_system ( empty. exclusive_system ( ) . label ( "3" ) . in_ambiguity_set ( "a" ) )
1486+ . with_system ( empty. exclusive_system ( ) . label ( "4" ) . after ( "3" ) . before ( "5" ) )
1487+ . with_system ( empty. exclusive_system ( ) . label ( "5" ) . in_ambiguity_set ( "a" ) )
1488+ . with_system ( empty. exclusive_system ( ) . label ( "6" ) . after ( "2" ) . after ( "5" ) ) ;
1489+ stage. initialize_systems ( & mut world, & mut resources) ;
1490+ stage. rebuild_orders_and_dependencies ( ) ;
1491+ let ambiguities = find_ambiguities_labels ( & stage. exclusive_at_start ) ;
1492+ assert ! (
1493+ ambiguities. contains( & ( Box :: new( "2" ) , Box :: new( "3" ) ) )
1494+ || ambiguities. contains( & ( Box :: new( "3" ) , Box :: new( "2" ) ) )
1495+ ) ;
1496+ assert ! (
1497+ ambiguities. contains( & ( Box :: new( "1" ) , Box :: new( "4" ) ) )
1498+ || ambiguities. contains( & ( Box :: new( "4" ) , Box :: new( "1" ) ) )
1499+ ) ;
1500+ assert ! (
1501+ ambiguities. contains( & ( Box :: new( "2" ) , Box :: new( "4" ) ) )
1502+ || ambiguities. contains( & ( Box :: new( "4" ) , Box :: new( "2" ) ) )
1503+ ) ;
1504+ assert ! (
1505+ ambiguities. contains( & ( Box :: new( "2" ) , Box :: new( "5" ) ) )
1506+ || ambiguities. contains( & ( Box :: new( "5" ) , Box :: new( "2" ) ) )
1507+ ) ;
1508+ assert_eq ! ( ambiguities. len( ) , 4 ) ;
1509+
1510+ let mut stage = SystemStage :: parallel ( )
1511+ . with_system ( empty. exclusive_system ( ) . label ( "0" ) . in_ambiguity_set ( "a" ) )
1512+ . with_system ( empty. exclusive_system ( ) . label ( "1" ) . in_ambiguity_set ( "a" ) )
1513+ . with_system ( empty. exclusive_system ( ) . label ( "2" ) . in_ambiguity_set ( "a" ) )
1514+ . with_system ( empty. exclusive_system ( ) . label ( "3" ) . in_ambiguity_set ( "a" ) ) ;
1515+ stage. initialize_systems ( & mut world, & mut resources) ;
1516+ stage. rebuild_orders_and_dependencies ( ) ;
1517+ let ambiguities = find_ambiguities_labels ( & stage. exclusive_at_start ) ;
1518+ assert_eq ! ( ambiguities. len( ) , 0 ) ;
13511519 }
13521520}
0 commit comments