Skip to content

Commit

Permalink
Resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
Ratysz authored Feb 18, 2021
1 parent ea539b0 commit 3f0d074
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 6 deletions.
6 changes: 6 additions & 0 deletions crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,12 @@ pub fn derive_stage_label(input: TokenStream) -> TokenStream {
derive_label(input, Ident::new("StageLabel", Span::call_site())).into()
}

#[proc_macro_derive(AmbiguitySetLabel)]
pub fn derive_ambiguity_set_label(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
derive_label(input, Ident::new("AmbiguitySetLabel", Span::call_site())).into()
}

fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 {
let ident = input.ident;

Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_ecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ pub mod prelude {
SystemSet, SystemStage,
},
system::{Commands, ExclusiveSystem, IntoExclusiveSystem, IntoSystem, Query, System},
Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Mut, Mutated, Or,
QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, World,
Added, AmbiguitySetLabel, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem,
Mut, Mutated, Or, QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without,
World,
};
}
7 changes: 7 additions & 0 deletions crates/bevy_ecs/src/schedule/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ pub trait SystemLabel: DynHash + Debug + Send + Sync + 'static {
}
pub(crate) type BoxedSystemLabel = Box<dyn SystemLabel>;

pub trait AmbiguitySetLabel: DynHash + Debug + Send + Sync + 'static {
#[doc(hidden)]
fn dyn_clone(&self) -> Box<dyn AmbiguitySetLabel>;
}
pub(crate) type BoxedAmbiguitySetLabel = Box<dyn AmbiguitySetLabel>;

macro_rules! impl_label {
($trait_name:ident) => {
impl PartialEq for dyn $trait_name {
Expand Down Expand Up @@ -97,3 +103,4 @@ macro_rules! impl_label {

impl_label!(StageLabel);
impl_label!(SystemLabel);
impl_label!(AmbiguitySetLabel);
170 changes: 169 additions & 1 deletion crates/bevy_ecs/src/schedule/stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,9 +482,20 @@ fn topological_order(
/// Returns vector containing all pairs of indices of systems with ambiguous execution order.
/// Systems must be topologically sorted beforehand.
fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize)> {
let mut ambiguity_set_labels = HashMap::default();
for set in systems.iter().flat_map(|c| c.ambiguity_sets()) {
let len = ambiguity_set_labels.len();
ambiguity_set_labels.entry(set).or_insert(len);
}
let mut all_ambiguity_sets = Vec::<FixedBitSet>::with_capacity(systems.len());
let mut all_dependencies = Vec::<FixedBitSet>::with_capacity(systems.len());
let mut all_dependants = Vec::<FixedBitSet>::with_capacity(systems.len());
for (index, container) in systems.iter().enumerate() {
let mut ambiguity_sets = FixedBitSet::with_capacity(ambiguity_set_labels.len());
for set in container.ambiguity_sets() {
ambiguity_sets.insert(ambiguity_set_labels[set]);
}
all_ambiguity_sets.push(ambiguity_sets);
let mut dependencies = FixedBitSet::with_capacity(systems.len());
for &dependency in container.dependencies() {
dependencies.union_with(&all_dependencies[dependency]);
Expand Down Expand Up @@ -522,7 +533,10 @@ fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize)> {
for index_b in full_bitset.difference(&relations)
/*.take(index_a)*/
{
if !processed.contains(index_b) && !systems[index_a].is_compatible(&systems[index_b]) {
if !processed.contains(index_b)
&& all_ambiguity_sets[index_a].is_disjoint(&all_ambiguity_sets[index_b])
&& !systems[index_a].is_compatible(&systems[index_b])
{
ambiguities.push((index_a, index_b));
}
}
Expand Down Expand Up @@ -1207,6 +1221,27 @@ mod tests {
);
assert_eq!(ambiguities.len(), 2);

let mut stage = SystemStage::parallel()
.with_system(component.system().label("0"))
.with_system(
resource
.system()
.label("1")
.after("0")
.in_ambiguity_set("a"),
)
.with_system(empty.system().label("2"))
.with_system(component.system().label("3").after("2").before("4"))
.with_system(resource.system().label("4").in_ambiguity_set("a"));
stage.initialize_systems(&mut world, &mut resources);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_labels(&stage.parallel);
assert!(
ambiguities.contains(&(Box::new("0"), Box::new("3")))
|| ambiguities.contains(&(Box::new("3"), Box::new("0")))
);
assert_eq!(ambiguities.len(), 1);

let mut stage = SystemStage::parallel()
.with_system(component.system().label("0").before("2"))
.with_system(component.system().label("1").before("2"))
Expand Down Expand Up @@ -1247,6 +1282,30 @@ mod tests {
);
assert_eq!(ambiguities.len(), 1);

let mut stage = SystemStage::parallel()
.with_system(component.system().label("0").before("1").before("2"))
.with_system(component.system().label("1").in_ambiguity_set("a"))
.with_system(component.system().label("2").in_ambiguity_set("a"))
.with_system(component.system().label("3").after("1").after("2"));
stage.initialize_systems(&mut world, &mut resources);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_labels(&stage.parallel);
assert_eq!(ambiguities.len(), 0);

let mut stage = SystemStage::parallel()
.with_system(component.system().label("0").before("1").before("2"))
.with_system(component.system().label("1").in_ambiguity_set("a"))
.with_system(component.system().label("2").in_ambiguity_set("b"))
.with_system(component.system().label("3").after("1").after("2"));
stage.initialize_systems(&mut world, &mut resources);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_labels(&stage.parallel);
assert!(
ambiguities.contains(&(Box::new("1"), Box::new("2")))
|| ambiguities.contains(&(Box::new("2"), Box::new("1")))
);
assert_eq!(ambiguities.len(), 1);

let mut stage = SystemStage::parallel()
.with_system(
component
Expand Down Expand Up @@ -1299,6 +1358,76 @@ mod tests {
);
assert_eq!(ambiguities.len(), 6);

let mut stage = SystemStage::parallel()
.with_system(
component
.system()
.label("0")
.before("1")
.before("2")
.before("3")
.before("4"),
)
.with_system(component.system().label("1").in_ambiguity_set("a"))
.with_system(component.system().label("2").in_ambiguity_set("a"))
.with_system(component.system().label("3").in_ambiguity_set("a"))
.with_system(component.system().label("4").in_ambiguity_set("a"))
.with_system(
component
.system()
.label("5")
.after("1")
.after("2")
.after("3")
.after("4"),
);
stage.initialize_systems(&mut world, &mut resources);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_labels(&stage.parallel);
assert_eq!(ambiguities.len(), 0);

let mut stage = SystemStage::parallel()
.with_system(
component
.system()
.label("0")
.before("1")
.before("2")
.before("3")
.before("4"),
)
.with_system(component.system().label("1").in_ambiguity_set("a"))
.with_system(component.system().label("2").in_ambiguity_set("a"))
.with_system(
component
.system()
.label("3")
.in_ambiguity_set("a")
.in_ambiguity_set("b"),
)
.with_system(component.system().label("4").in_ambiguity_set("b"))
.with_system(
component
.system()
.label("5")
.after("1")
.after("2")
.after("3")
.after("4"),
);
stage.initialize_systems(&mut world, &mut resources);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_labels(&stage.parallel);
assert!(
ambiguities.contains(&(Box::new("1"), Box::new("4")))
|| ambiguities.contains(&(Box::new("4"), Box::new("1")))
);
assert!(
ambiguities.contains(&(Box::new("2"), Box::new("4")))
|| ambiguities.contains(&(Box::new("4"), Box::new("2")))
);
assert_eq!(ambiguities.len(), 2);

let mut stage = SystemStage::parallel()
.with_system(empty.exclusive_system().label("0"))
.with_system(empty.exclusive_system().label("1").after("0"))
Expand Down Expand Up @@ -1348,5 +1477,44 @@ mod tests {
|| ambiguities.contains(&(Box::new("5"), Box::new("2")))
);
assert_eq!(ambiguities.len(), 6);

let mut stage = SystemStage::parallel()
.with_system(empty.exclusive_system().label("0").before("1").before("3"))
.with_system(empty.exclusive_system().label("1").in_ambiguity_set("a"))
.with_system(empty.exclusive_system().label("2").after("1"))
.with_system(empty.exclusive_system().label("3").in_ambiguity_set("a"))
.with_system(empty.exclusive_system().label("4").after("3").before("5"))
.with_system(empty.exclusive_system().label("5").in_ambiguity_set("a"))
.with_system(empty.exclusive_system().label("6").after("2").after("5"));
stage.initialize_systems(&mut world, &mut resources);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_labels(&stage.exclusive_at_start);
assert!(
ambiguities.contains(&(Box::new("2"), Box::new("3")))
|| ambiguities.contains(&(Box::new("3"), Box::new("2")))
);
assert!(
ambiguities.contains(&(Box::new("1"), Box::new("4")))
|| ambiguities.contains(&(Box::new("4"), Box::new("1")))
);
assert!(
ambiguities.contains(&(Box::new("2"), Box::new("4")))
|| ambiguities.contains(&(Box::new("4"), Box::new("2")))
);
assert!(
ambiguities.contains(&(Box::new("2"), Box::new("5")))
|| ambiguities.contains(&(Box::new("5"), Box::new("2")))
);
assert_eq!(ambiguities.len(), 4);

let mut stage = SystemStage::parallel()
.with_system(empty.exclusive_system().label("0").in_ambiguity_set("a"))
.with_system(empty.exclusive_system().label("1").in_ambiguity_set("a"))
.with_system(empty.exclusive_system().label("2").in_ambiguity_set("a"))
.with_system(empty.exclusive_system().label("3").in_ambiguity_set("a"));
stage.initialize_systems(&mut world, &mut resources);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_labels(&stage.exclusive_at_start);
assert_eq!(ambiguities.len(), 0);
}
}
16 changes: 15 additions & 1 deletion crates/bevy_ecs/src/schedule/system_container.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::{borrow::Cow, ptr::NonNull};

use crate::{
BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System,
BoxedAmbiguitySetLabel, BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemDescriptor,
ParallelSystemDescriptor, System,
};

pub(super) trait SystemContainer {
Expand All @@ -12,6 +13,7 @@ pub(super) trait SystemContainer {
fn label(&self) -> &Option<BoxedSystemLabel>;
fn before(&self) -> &[BoxedSystemLabel];
fn after(&self) -> &[BoxedSystemLabel];
fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel];
fn is_compatible(&self, other: &Self) -> bool;
}

Expand All @@ -22,6 +24,7 @@ pub(super) struct ExclusiveSystemContainer {
label: Option<BoxedSystemLabel>,
before: Vec<BoxedSystemLabel>,
after: Vec<BoxedSystemLabel>,
ambiguity_sets: Vec<BoxedAmbiguitySetLabel>,
}

impl ExclusiveSystemContainer {
Expand All @@ -33,6 +36,7 @@ impl ExclusiveSystemContainer {
label: descriptor.label,
before: descriptor.before,
after: descriptor.after,
ambiguity_sets: descriptor.ambiguity_sets,
}
}

Expand Down Expand Up @@ -74,6 +78,10 @@ impl SystemContainer for ExclusiveSystemContainer {
&self.after
}

fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel] {
&self.ambiguity_sets
}

fn is_compatible(&self, _: &Self) -> bool {
false
}
Expand All @@ -87,6 +95,7 @@ pub struct ParallelSystemContainer {
label: Option<BoxedSystemLabel>,
before: Vec<BoxedSystemLabel>,
after: Vec<BoxedSystemLabel>,
ambiguity_sets: Vec<BoxedAmbiguitySetLabel>,
}

impl SystemContainer for ParallelSystemContainer {
Expand Down Expand Up @@ -122,6 +131,10 @@ impl SystemContainer for ParallelSystemContainer {
&self.after
}

fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel] {
&self.ambiguity_sets
}

fn is_compatible(&self, other: &Self) -> bool {
self.system()
.component_access()
Expand All @@ -146,6 +159,7 @@ impl ParallelSystemContainer {
label: descriptor.label,
before: descriptor.before,
after: descriptor.after,
ambiguity_sets: descriptor.ambiguity_sets,
}
}

Expand Down
Loading

0 comments on commit 3f0d074

Please sign in to comment.