Skip to content

Commit 091f5a8

Browse files
Implement State sets
1 parent d5a7330 commit 091f5a8

File tree

3 files changed

+404
-215
lines changed

3 files changed

+404
-215
lines changed

crates/bevy_ecs/src/schedule/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod state;
55
mod system_container;
66
mod system_descriptor;
77
mod system_set;
8+
mod state_set;
89

910
pub use executor::*;
1011
pub use executor_parallel::*;
@@ -13,6 +14,7 @@ pub use state::*;
1314
pub use system_container::*;
1415
pub use system_descriptor::*;
1516
pub use system_set::*;
17+
pub use state_set::*;
1618

1719
use crate::{
1820
ArchetypeComponent, BoxedSystem, IntoSystem, Resources, System, SystemId, TypeAccess, World,

crates/bevy_ecs/src/schedule/stage.rs

Lines changed: 30 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
471471
fn 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

Comments
 (0)