Skip to content

Commit 3f0d074

Browse files
authored
Resolve conflicts
1 parent ea539b0 commit 3f0d074

File tree

6 files changed

+236
-6
lines changed

6 files changed

+236
-6
lines changed

crates/bevy_ecs/macros/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,12 @@ pub fn derive_stage_label(input: TokenStream) -> TokenStream {
479479
derive_label(input, Ident::new("StageLabel", Span::call_site())).into()
480480
}
481481

482+
#[proc_macro_derive(AmbiguitySetLabel)]
483+
pub fn derive_ambiguity_set_label(input: TokenStream) -> TokenStream {
484+
let input = parse_macro_input!(input as DeriveInput);
485+
derive_label(input, Ident::new("AmbiguitySetLabel", Span::call_site())).into()
486+
}
487+
482488
fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 {
483489
let ident = input.ident;
484490

crates/bevy_ecs/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ pub mod prelude {
2020
SystemSet, SystemStage,
2121
},
2222
system::{Commands, ExclusiveSystem, IntoExclusiveSystem, IntoSystem, Query, System},
23-
Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Mut, Mutated, Or,
24-
QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, World,
23+
Added, AmbiguitySetLabel, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem,
24+
Mut, Mutated, Or, QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without,
25+
World,
2526
};
2627
}

crates/bevy_ecs/src/schedule/label.rs

+7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ pub trait SystemLabel: DynHash + Debug + Send + Sync + 'static {
5959
}
6060
pub(crate) type BoxedSystemLabel = Box<dyn SystemLabel>;
6161

62+
pub trait AmbiguitySetLabel: DynHash + Debug + Send + Sync + 'static {
63+
#[doc(hidden)]
64+
fn dyn_clone(&self) -> Box<dyn AmbiguitySetLabel>;
65+
}
66+
pub(crate) type BoxedAmbiguitySetLabel = Box<dyn AmbiguitySetLabel>;
67+
6268
macro_rules! impl_label {
6369
($trait_name:ident) => {
6470
impl PartialEq for dyn $trait_name {
@@ -97,3 +103,4 @@ macro_rules! impl_label {
97103

98104
impl_label!(StageLabel);
99105
impl_label!(SystemLabel);
106+
impl_label!(AmbiguitySetLabel);

crates/bevy_ecs/src/schedule/stage.rs

+169-1
Original file line numberDiff line numberDiff line change
@@ -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.
484484
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());
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
}

crates/bevy_ecs/src/schedule/system_container.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::{borrow::Cow, ptr::NonNull};
22

33
use crate::{
4-
BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System,
4+
BoxedAmbiguitySetLabel, BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemDescriptor,
5+
ParallelSystemDescriptor, System,
56
};
67

78
pub(super) trait SystemContainer {
@@ -12,6 +13,7 @@ pub(super) trait SystemContainer {
1213
fn label(&self) -> &Option<BoxedSystemLabel>;
1314
fn before(&self) -> &[BoxedSystemLabel];
1415
fn after(&self) -> &[BoxedSystemLabel];
16+
fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel];
1517
fn is_compatible(&self, other: &Self) -> bool;
1618
}
1719

@@ -22,6 +24,7 @@ pub(super) struct ExclusiveSystemContainer {
2224
label: Option<BoxedSystemLabel>,
2325
before: Vec<BoxedSystemLabel>,
2426
after: Vec<BoxedSystemLabel>,
27+
ambiguity_sets: Vec<BoxedAmbiguitySetLabel>,
2528
}
2629

2730
impl ExclusiveSystemContainer {
@@ -33,6 +36,7 @@ impl ExclusiveSystemContainer {
3336
label: descriptor.label,
3437
before: descriptor.before,
3538
after: descriptor.after,
39+
ambiguity_sets: descriptor.ambiguity_sets,
3640
}
3741
}
3842

@@ -74,6 +78,10 @@ impl SystemContainer for ExclusiveSystemContainer {
7478
&self.after
7579
}
7680

81+
fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel] {
82+
&self.ambiguity_sets
83+
}
84+
7785
fn is_compatible(&self, _: &Self) -> bool {
7886
false
7987
}
@@ -87,6 +95,7 @@ pub struct ParallelSystemContainer {
8795
label: Option<BoxedSystemLabel>,
8896
before: Vec<BoxedSystemLabel>,
8997
after: Vec<BoxedSystemLabel>,
98+
ambiguity_sets: Vec<BoxedAmbiguitySetLabel>,
9099
}
91100

92101
impl SystemContainer for ParallelSystemContainer {
@@ -122,6 +131,10 @@ impl SystemContainer for ParallelSystemContainer {
122131
&self.after
123132
}
124133

134+
fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel] {
135+
&self.ambiguity_sets
136+
}
137+
125138
fn is_compatible(&self, other: &Self) -> bool {
126139
self.system()
127140
.component_access()
@@ -146,6 +159,7 @@ impl ParallelSystemContainer {
146159
label: descriptor.label,
147160
before: descriptor.before,
148161
after: descriptor.after,
162+
ambiguity_sets: descriptor.ambiguity_sets,
149163
}
150164
}
151165

0 commit comments

Comments
 (0)