@@ -469,51 +469,34 @@ fn topological_order(
469469/// Returns vector containing all pairs of indices of systems with ambiguous execution order.
470470/// Systems must be topologically sorted beforehand.
471471fn find_ambiguities ( systems : & [ impl SystemContainer ] ) -> Vec < ( usize , usize ) > {
472- let mut all_dependencies = Vec :: < FixedBitSet > :: with_capacity ( systems. len ( ) ) ;
473- let mut all_dependants = Vec :: < FixedBitSet > :: with_capacity ( systems. len ( ) ) ;
472+ let mut all_relations = Vec :: < FixedBitSet > :: with_capacity ( systems. len ( ) ) ;
474473 for ( index, container) in systems. iter ( ) . enumerate ( ) {
475- let mut dependencies = FixedBitSet :: with_capacity ( systems. len ( ) ) ;
476- for & dependency in container . dependencies ( ) {
477- dependencies . union_with ( & all_dependencies [ dependency ] ) ;
478- dependencies . insert ( dependency) ;
479- all_dependants [ dependency ] . insert ( index ) ;
474+ let mut relations = FixedBitSet :: with_capacity ( systems. len ( ) ) ;
475+ relations . insert ( index ) ;
476+ for dependency in container . dependencies ( ) {
477+ relations . union_with ( & all_relations [ * dependency] ) ;
478+ relations . insert ( * dependency ) ;
480479 }
481- all_dependants. push ( FixedBitSet :: with_capacity ( systems. len ( ) ) ) ;
482- all_dependencies. push ( dependencies) ;
480+ all_relations. push ( relations) ;
483481 }
484- for index in ( 0 ..systems. len ( ) ) . rev ( ) {
485- let mut dependants = FixedBitSet :: with_capacity ( systems. len ( ) ) ;
486- for dependant in all_dependants[ index] . ones ( ) {
487- dependants. union_with ( & all_dependants[ dependant] ) ;
488- dependants. insert ( dependant) ;
482+ for ( index, container) in systems. iter ( ) . enumerate ( ) . rev ( ) {
483+ let relations = all_relations[ index] . clone ( ) ;
484+ for dependency in container. dependencies ( ) {
485+ all_relations[ * dependency] . union_with ( & relations) ;
489486 }
490- all_dependants[ index] = dependants;
491487 }
492- let mut all_relations = all_dependencies
493- . drain ( ..)
494- . zip ( all_dependants. drain ( ..) )
495- . enumerate ( )
496- . map ( |( index, ( dependencies, dependants) ) | {
497- let mut relations = FixedBitSet :: with_capacity ( systems. len ( ) ) ;
498- relations. union_with ( & dependencies) ;
499- relations. union_with ( & dependants) ;
500- relations. insert ( index) ;
501- relations
502- } )
503- . collect :: < Vec < FixedBitSet > > ( ) ;
488+ // TODO: There is enough data to group ambiguity pairs into OR blocks,
489+ // as in, "you might want to add a relation to at least one of these pairs".
504490 let mut ambiguities = Vec :: new ( ) ;
505491 let full_bitset: FixedBitSet = ( 0 ..systems. len ( ) ) . collect ( ) ;
506- let mut processed = FixedBitSet :: with_capacity ( systems. len ( ) ) ;
507492 for ( index_a, relations) in all_relations. drain ( ..) . enumerate ( ) {
508- // TODO: prove that `.take(index_a)` would be correct here, and uncomment it if so.
509- for index_b in full_bitset. difference ( & relations)
510- /*.take(index_a)*/
511- {
512- if !processed. contains ( index_b) && !systems[ index_a] . is_compatible ( & systems[ index_b] ) {
493+ for index_b in full_bitset. difference ( & relations) {
494+ if !systems[ index_a] . is_compatible ( & systems[ index_b] )
495+ && !ambiguities. contains ( & ( index_b, index_a) )
496+ {
513497 ambiguities. push ( ( index_a, index_b) ) ;
514498 }
515499 }
516- processed. insert ( index_a) ;
517500 }
518501 ambiguities
519502}
@@ -1102,35 +1085,18 @@ mod tests {
11021085
11031086 #[ test]
11041087 fn ambiguity_detection ( ) {
1105- use super :: { find_ambiguities, SystemContainer } ;
1106- use std:: borrow:: Cow ;
1107-
1108- fn find_ambiguities_labels (
1109- systems : & [ impl SystemContainer ] ,
1110- ) -> Vec < ( Cow < ' static , str > , Cow < ' static , str > ) > {
1111- find_ambiguities ( systems)
1112- . drain ( ..)
1113- . map ( |( index_a, index_b) | {
1114- (
1115- systems[ index_a] . display_name ( ) ,
1116- systems[ index_b] . display_name ( ) ,
1117- )
1118- } )
1119- . collect ( )
1120- }
1121-
1088+ use super :: find_ambiguities;
11221089 fn empty ( ) { }
11231090 fn resource ( _: ResMut < usize > ) { }
11241091 fn component ( _: Query < & mut f32 > ) { }
1125-
11261092 let mut world = World :: new ( ) ;
11271093 let mut resources = Resources :: default ( ) ;
11281094
11291095 let mut stage = SystemStage :: parallel ( )
11301096 . with_system ( empty. system ( ) . label ( "0" ) )
11311097 . with_system ( empty. system ( ) . label ( "1" ) . after ( "0" ) )
11321098 . with_system ( empty. system ( ) . label ( "2" ) )
1133- . with_system ( empty. system ( ) . label ( "3" ) . after ( "2" ) . before ( "4" ) )
1099+ . with_system ( empty. system ( ) . after ( "2" ) . before ( "4" ) )
11341100 . with_system ( empty. system ( ) . label ( "4" ) ) ;
11351101 stage. initialize_systems ( & mut world, & mut resources) ;
11361102 stage. rebuild_orders_and_dependencies ( ) ;
@@ -1140,37 +1106,27 @@ mod tests {
11401106 . with_system ( empty. system ( ) . label ( "0" ) )
11411107 . with_system ( component. system ( ) . label ( "1" ) . after ( "0" ) )
11421108 . with_system ( empty. system ( ) . label ( "2" ) )
1143- . with_system ( empty. system ( ) . label ( "3" ) . after ( "2" ) . before ( "4" ) )
1109+ . with_system ( empty. system ( ) . after ( "2" ) . before ( "4" ) )
11441110 . with_system ( component. system ( ) . label ( "4" ) ) ;
11451111 stage. initialize_systems ( & mut world, & mut resources) ;
11461112 stage. rebuild_orders_and_dependencies ( ) ;
1147- let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1148- assert ! (
1149- ambiguities. contains( & ( "1" . into( ) , "4" . into( ) ) )
1150- || ambiguities. contains( & ( "4" . into( ) , "1" . into( ) ) )
1151- ) ;
1152- assert_eq ! ( ambiguities. len( ) , 1 ) ;
1113+ assert_eq ! ( find_ambiguities( & stage. parallel) . len( ) , 1 ) ;
11531114
11541115 let mut stage = SystemStage :: parallel ( )
11551116 . with_system ( empty. system ( ) . label ( "0" ) )
11561117 . with_system ( resource. system ( ) . label ( "1" ) . after ( "0" ) )
11571118 . with_system ( empty. system ( ) . label ( "2" ) )
1158- . with_system ( empty. system ( ) . label ( "3" ) . after ( "2" ) . before ( "4" ) )
1119+ . with_system ( empty. system ( ) . after ( "2" ) . before ( "4" ) )
11591120 . with_system ( resource. system ( ) . label ( "4" ) ) ;
11601121 stage. initialize_systems ( & mut world, & mut resources) ;
11611122 stage. rebuild_orders_and_dependencies ( ) ;
1162- let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1163- assert ! (
1164- ambiguities. contains( & ( "1" . into( ) , "4" . into( ) ) )
1165- || ambiguities. contains( & ( "4" . into( ) , "1" . into( ) ) )
1166- ) ;
1167- assert_eq ! ( ambiguities. len( ) , 1 ) ;
1123+ assert_eq ! ( find_ambiguities( & stage. parallel) . len( ) , 1 ) ;
11681124
11691125 let mut stage = SystemStage :: parallel ( )
11701126 . with_system ( empty. system ( ) . label ( "0" ) )
11711127 . with_system ( resource. system ( ) . label ( "1" ) . after ( "0" ) )
11721128 . with_system ( empty. system ( ) . label ( "2" ) )
1173- . with_system ( empty. system ( ) . label ( "3" ) . after ( "2" ) . before ( "4" ) )
1129+ . with_system ( empty. system ( ) . after ( "2" ) . before ( "4" ) )
11741130 . with_system ( component. system ( ) . label ( "4" ) ) ;
11751131 stage. initialize_systems ( & mut world, & mut resources) ;
11761132 stage. rebuild_orders_and_dependencies ( ) ;
@@ -1180,161 +1136,20 @@ mod tests {
11801136 . with_system ( component. system ( ) . label ( "0" ) )
11811137 . with_system ( resource. system ( ) . label ( "1" ) . after ( "0" ) )
11821138 . with_system ( empty. system ( ) . label ( "2" ) )
1183- . with_system ( component. system ( ) . label ( "3" ) . after ( "2" ) . before ( "4" ) )
1139+ . with_system ( component. system ( ) . after ( "2" ) . before ( "4" ) )
11841140 . with_system ( resource. system ( ) . label ( "4" ) ) ;
11851141 stage. initialize_systems ( & mut world, & mut resources) ;
11861142 stage. rebuild_orders_and_dependencies ( ) ;
1187- let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1188- assert ! (
1189- ambiguities. contains( & ( "0" . into( ) , "3" . into( ) ) )
1190- || ambiguities. contains( & ( "3" . into( ) , "0" . into( ) ) )
1191- ) ;
1192- assert ! (
1193- ambiguities. contains( & ( "1" . into( ) , "4" . into( ) ) )
1194- || ambiguities. contains( & ( "4" . into( ) , "1" . into( ) ) )
1195- ) ;
1196- assert_eq ! ( ambiguities. len( ) , 2 ) ;
1197-
1198- let mut stage = SystemStage :: parallel ( )
1199- . with_system ( component. system ( ) . label ( "0" ) . before ( "2" ) )
1200- . with_system ( component. system ( ) . label ( "1" ) . before ( "2" ) )
1201- . with_system ( component. system ( ) . label ( "2" ) ) ;
1202- stage. initialize_systems ( & mut world, & mut resources) ;
1203- stage. rebuild_orders_and_dependencies ( ) ;
1204- let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1205- assert ! (
1206- ambiguities. contains( & ( "0" . into( ) , "1" . into( ) ) )
1207- || ambiguities. contains( & ( "1" . into( ) , "0" . into( ) ) )
1208- ) ;
1209- assert_eq ! ( ambiguities. len( ) , 1 ) ;
1210-
1211- let mut stage = SystemStage :: parallel ( )
1212- . with_system ( component. system ( ) . label ( "0" ) )
1213- . with_system ( component. system ( ) . label ( "1" ) . after ( "0" ) )
1214- . with_system ( component. system ( ) . label ( "2" ) . after ( "0" ) ) ;
1215- stage. initialize_systems ( & mut world, & mut resources) ;
1216- stage. rebuild_orders_and_dependencies ( ) ;
1217- let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1218- assert ! (
1219- ambiguities. contains( & ( "1" . into( ) , "2" . into( ) ) )
1220- || ambiguities. contains( & ( "2" . into( ) , "1" . into( ) ) )
1221- ) ;
1222- assert_eq ! ( ambiguities. len( ) , 1 ) ;
1223-
1224- let mut stage = SystemStage :: parallel ( )
1225- . with_system ( component. system ( ) . label ( "0" ) . before ( "1" ) . before ( "2" ) )
1226- . with_system ( component. system ( ) . label ( "1" ) )
1227- . with_system ( component. system ( ) . label ( "2" ) )
1228- . with_system ( component. system ( ) . label ( "3" ) . after ( "1" ) . after ( "2" ) ) ;
1229- stage. initialize_systems ( & mut world, & mut resources) ;
1230- stage. rebuild_orders_and_dependencies ( ) ;
1231- let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1232- assert ! (
1233- ambiguities. contains( & ( "1" . into( ) , "2" . into( ) ) )
1234- || ambiguities. contains( & ( "2" . into( ) , "1" . into( ) ) )
1235- ) ;
1236- assert_eq ! ( ambiguities. len( ) , 1 ) ;
1237-
1238- let mut stage = SystemStage :: parallel ( )
1239- . with_system (
1240- component
1241- . system ( )
1242- . label ( "0" )
1243- . before ( "1" )
1244- . before ( "2" )
1245- . before ( "3" )
1246- . before ( "4" ) ,
1247- )
1248- . with_system ( component. system ( ) . label ( "1" ) )
1249- . with_system ( component. system ( ) . label ( "2" ) )
1250- . with_system ( component. system ( ) . label ( "3" ) )
1251- . with_system ( component. system ( ) . label ( "4" ) )
1252- . with_system (
1253- component
1254- . system ( )
1255- . label ( "5" )
1256- . after ( "1" )
1257- . after ( "2" )
1258- . after ( "3" )
1259- . after ( "4" ) ,
1260- ) ;
1261- stage. initialize_systems ( & mut world, & mut resources) ;
1262- stage. rebuild_orders_and_dependencies ( ) ;
1263- let ambiguities = find_ambiguities_labels ( & stage. parallel ) ;
1264- assert ! (
1265- ambiguities. contains( & ( "1" . into( ) , "2" . into( ) ) )
1266- || ambiguities. contains( & ( "2" . into( ) , "1" . into( ) ) )
1267- ) ;
1268- assert ! (
1269- ambiguities. contains( & ( "1" . into( ) , "3" . into( ) ) )
1270- || ambiguities. contains( & ( "3" . into( ) , "1" . into( ) ) )
1271- ) ;
1272- assert ! (
1273- ambiguities. contains( & ( "1" . into( ) , "4" . into( ) ) )
1274- || ambiguities. contains( & ( "4" . into( ) , "1" . into( ) ) )
1275- ) ;
1276- assert ! (
1277- ambiguities. contains( & ( "2" . into( ) , "3" . into( ) ) )
1278- || ambiguities. contains( & ( "3" . into( ) , "2" . into( ) ) )
1279- ) ;
1280- assert ! (
1281- ambiguities. contains( & ( "2" . into( ) , "4" . into( ) ) )
1282- || ambiguities. contains( & ( "4" . into( ) , "2" . into( ) ) )
1283- ) ;
1284- assert ! (
1285- ambiguities. contains( & ( "3" . into( ) , "4" . into( ) ) )
1286- || ambiguities. contains( & ( "4" . into( ) , "3" . into( ) ) )
1287- ) ;
1288- assert_eq ! ( ambiguities. len( ) , 6 ) ;
1143+ assert_eq ! ( find_ambiguities( & stage. parallel) . len( ) , 2 ) ;
12891144
12901145 let mut stage = SystemStage :: parallel ( )
12911146 . with_system ( empty. exclusive_system ( ) . label ( "0" ) )
12921147 . with_system ( empty. exclusive_system ( ) . label ( "1" ) . after ( "0" ) )
1293- . with_system ( empty. exclusive_system ( ) . label ( "2" ) . after ( "1" ) )
1294- . with_system ( empty. exclusive_system ( ) . label ( "3" ) . after ( "2" ) )
1295- . with_system ( empty. exclusive_system ( ) . label ( "4" ) . after ( "3" ) )
1296- . with_system ( empty. exclusive_system ( ) . label ( "5" ) . after ( "4" ) )
1297- . with_system ( empty. exclusive_system ( ) . label ( "6" ) . after ( "5" ) )
1298- . with_system ( empty. exclusive_system ( ) . label ( "7" ) . after ( "6" ) ) ;
1299- stage. initialize_systems ( & mut world, & mut resources) ;
1300- stage. rebuild_orders_and_dependencies ( ) ;
1301- assert_eq ! ( find_ambiguities( & stage. exclusive_at_start) . len( ) , 0 ) ;
1302-
1303- let mut stage = SystemStage :: parallel ( )
1304- . with_system ( empty. exclusive_system ( ) . label ( "0" ) . before ( "1" ) . before ( "3" ) )
1305- . with_system ( empty. exclusive_system ( ) . label ( "1" ) )
1306- . with_system ( empty. exclusive_system ( ) . label ( "2" ) . after ( "1" ) )
1307- . with_system ( empty. exclusive_system ( ) . label ( "3" ) )
1308- . with_system ( empty. exclusive_system ( ) . label ( "4" ) . after ( "3" ) . before ( "5" ) )
1309- . with_system ( empty. exclusive_system ( ) . label ( "5" ) )
1310- . with_system ( empty. exclusive_system ( ) . label ( "6" ) . after ( "2" ) . after ( "5" ) ) ;
1148+ . with_system ( empty. exclusive_system ( ) . label ( "2" ) )
1149+ . with_system ( empty. exclusive_system ( ) . after ( "2" ) . before ( "4" ) )
1150+ . with_system ( empty. exclusive_system ( ) . label ( "4" ) ) ;
13111151 stage. initialize_systems ( & mut world, & mut resources) ;
13121152 stage. rebuild_orders_and_dependencies ( ) ;
1313- let ambiguities = find_ambiguities_labels ( & stage. exclusive_at_start ) ;
1314- assert ! (
1315- ambiguities. contains( & ( "1" . into( ) , "3" . into( ) ) )
1316- || ambiguities. contains( & ( "3" . into( ) , "1" . into( ) ) )
1317- ) ;
1318- assert ! (
1319- ambiguities. contains( & ( "2" . into( ) , "3" . into( ) ) )
1320- || ambiguities. contains( & ( "3" . into( ) , "2" . into( ) ) )
1321- ) ;
1322- assert ! (
1323- ambiguities. contains( & ( "1" . into( ) , "4" . into( ) ) )
1324- || ambiguities. contains( & ( "4" . into( ) , "1" . into( ) ) )
1325- ) ;
1326- assert ! (
1327- ambiguities. contains( & ( "2" . into( ) , "4" . into( ) ) )
1328- || ambiguities. contains( & ( "4" . into( ) , "2" . into( ) ) )
1329- ) ;
1330- assert ! (
1331- ambiguities. contains( & ( "1" . into( ) , "5" . into( ) ) )
1332- || ambiguities. contains( & ( "5" . into( ) , "1" . into( ) ) )
1333- ) ;
1334- assert ! (
1335- ambiguities. contains( & ( "2" . into( ) , "5" . into( ) ) )
1336- || ambiguities. contains( & ( "5" . into( ) , "2" . into( ) ) )
1337- ) ;
1338- assert_eq ! ( ambiguities. len( ) , 6 ) ;
1153+ assert_eq ! ( find_ambiguities( & stage. exclusive_at_start) . len( ) , 6 ) ;
13391154 }
13401155}
0 commit comments