Remove ambiguity sets (#5916)

# Objective

Ambiguity sets are used to ignore system order ambiguities between groups of systems. However, they are not very useful: they are clunky, poorly integrated, and generally hampered by the difficulty using (or discovering) the ambiguity detector.

As a first step to the work in #4299, we're removing them.

## Migration Guide

Ambiguity sets have been removed.
This commit is contained in:
Alice Cecile 2022-09-09 17:21:50 +00:00
parent 54e32ee681
commit c96b7ffb50
7 changed files with 12 additions and 496 deletions

View file

@ -462,21 +462,6 @@ pub fn derive_stage_label(input: TokenStream) -> TokenStream {
derive_label(input, &trait_path, "stage_label") derive_label(input, &trait_path, "stage_label")
} }
/// Generates an impl of the `AmbiguitySetLabel` trait.
///
/// This works only for unit structs, or enums with only unit variants.
/// You may force a struct or variant to behave as if it were fieldless with `#[ambiguity_set_label(ignore_fields)]`.
#[proc_macro_derive(AmbiguitySetLabel, attributes(ambiguity_set_label))]
pub fn derive_ambiguity_set_label(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let mut trait_path = bevy_ecs_path();
trait_path.segments.push(format_ident!("schedule").into());
trait_path
.segments
.push(format_ident!("AmbiguitySetLabel").into());
derive_label(input, &trait_path, "ambiguity_set_label")
}
/// Generates an impl of the `RunCriteriaLabel` trait. /// Generates an impl of the `RunCriteriaLabel` trait.
/// ///
/// This works only for unit structs, or enums with only unit variants. /// This works only for unit structs, or enums with only unit variants.

View file

@ -34,9 +34,9 @@ pub mod prelude {
event::{EventReader, EventWriter, Events}, event::{EventReader, EventWriter, Events},
query::{Added, AnyOf, ChangeTrackers, Changed, Or, QueryState, With, Without}, query::{Added, AnyOf, ChangeTrackers, Changed, Or, QueryState, With, Without},
schedule::{ schedule::{
AmbiguitySetLabel, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion, RunCriteria,
RunCriteria, RunCriteriaDescriptorCoercion, RunCriteriaLabel, Schedule, Stage, RunCriteriaDescriptorCoercion, RunCriteriaLabel, Schedule, Stage, StageLabel, State,
StageLabel, State, SystemLabel, SystemSet, SystemStage, SystemLabel, SystemSet, SystemStage,
}, },
system::{ system::{
adapter as system_adapter, Commands, In, IntoChainSystem, IntoExclusiveSystem, adapter as system_adapter, Commands, In, IntoChainSystem, IntoExclusiveSystem,

View file

@ -1,4 +1,4 @@
pub use bevy_ecs_macros::{AmbiguitySetLabel, RunCriteriaLabel, StageLabel, SystemLabel}; pub use bevy_ecs_macros::{RunCriteriaLabel, StageLabel, SystemLabel};
use bevy_utils::define_label; use bevy_utils::define_label;
define_label!( define_label!(
@ -13,12 +13,6 @@ define_label!(
/// Strongly-typed identifier for a [`SystemLabel`]. /// Strongly-typed identifier for a [`SystemLabel`].
SystemLabelId, SystemLabelId,
); );
define_label!(
/// A strongly-typed class of labels used to identify sets of systems with intentionally ambiguous execution order.
AmbiguitySetLabel,
/// Strongly-typed identifier for an [`AmbiguitySetLabel`].
AmbiguitySetLabelId,
);
define_label!( define_label!(
/// A strongly-typed class of labels used to identify [run criteria](crate::schedule::RunCriteria). /// A strongly-typed class of labels used to identify [run criteria](crate::schedule::RunCriteria).
RunCriteriaLabel, RunCriteriaLabel,

View file

@ -713,20 +713,9 @@ fn process_systems(
/// along with specific components that have triggered the warning. /// along with specific components that have triggered the warning.
/// Systems must be topologically sorted beforehand. /// Systems must be topologically sorted beforehand.
fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize, Vec<ComponentId>)> { fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize, Vec<ComponentId>)> {
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_dependencies = Vec::<FixedBitSet>::with_capacity(systems.len());
let mut all_dependants = Vec::<FixedBitSet>::with_capacity(systems.len()); let mut all_dependants = Vec::<FixedBitSet>::with_capacity(systems.len());
for (index, container) in systems.iter().enumerate() { 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()); let mut dependencies = FixedBitSet::with_capacity(systems.len());
for &dependency in container.dependencies() { for &dependency in container.dependencies() {
dependencies.union_with(&all_dependencies[dependency]); dependencies.union_with(&all_dependencies[dependency]);
@ -765,9 +754,7 @@ fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize, Vec<
for index_b in full_bitset.difference(&relations) for index_b in full_bitset.difference(&relations)
// .take(index_a) // .take(index_a)
{ {
if !processed.contains(index_b) if !processed.contains(index_b) {
&& all_ambiguity_sets[index_a].is_disjoint(&all_ambiguity_sets[index_b])
{
let a_access = systems[index_a].component_access(); let a_access = systems[index_a].component_access();
let b_access = systems[index_b].component_access(); let b_access = systems[index_b].component_access();
if let (Some(a), Some(b)) = (a_access, b_access) { if let (Some(a), Some(b)) = (a_access, b_access) {
@ -972,13 +959,13 @@ impl Stage for SystemStage {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use bevy_ecs_macros::{AmbiguitySetLabel, RunCriteriaLabel}; use bevy_ecs_macros::RunCriteriaLabel;
use crate::{ use crate::{
schedule::{ schedule::{
ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion, RunCriteria, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion, RunCriteria,
RunCriteriaDescriptorCoercion, ShouldRun, SingleThreadedExecutor, Stage, SystemLabel, RunCriteriaDescriptorCoercion, ShouldRun, SingleThreadedExecutor, Stage, SystemLabel,
SystemLabelId, SystemSet, SystemStage, SystemSet, SystemStage,
}, },
system::{In, IntoExclusiveSystem, Local, Query, ResMut}, system::{In, IntoExclusiveSystem, Local, Query, ResMut},
world::World, world::World,
@ -1607,392 +1594,6 @@ mod tests {
stage.run(&mut world); stage.run(&mut world);
} }
#[test]
fn ambiguity_detection() {
use super::{find_ambiguities, SystemContainer};
// these labels must all be the same type in order for
// `find_ambiguities_first_labels` to work
#[derive(SystemLabel)]
enum Labels {
A0,
A1,
A2,
A3,
A4,
A5,
A6,
A7,
}
use Labels::*;
#[derive(AmbiguitySetLabel)]
enum SetLabels {
SetA,
SetB,
}
use SetLabels::*;
fn find_ambiguities_first_labels(
systems: &[impl SystemContainer],
) -> Vec<(SystemLabelId, SystemLabelId)> {
find_ambiguities(systems)
.drain(..)
.map(|(index_a, index_b, _conflicts)| {
(
*systems[index_a]
.labels()
.iter()
.find(|a| a.type_id() == std::any::TypeId::of::<Labels>())
.unwrap(),
*systems[index_b]
.labels()
.iter()
.find(|a| a.type_id() == std::any::TypeId::of::<Labels>())
.unwrap(),
)
})
.collect()
}
fn empty() {}
fn resource(_: ResMut<R>) {}
fn component(_: Query<&mut W<f32>>) {}
let mut world = World::new();
let mut stage = SystemStage::parallel()
.with_system(empty.label(A0))
.with_system(empty.label(A1).after(A0))
.with_system(empty.label(A2))
.with_system(empty.label(A3).after(A2).before(A4))
.with_system(empty.label(A4));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
assert_eq!(find_ambiguities(&stage.parallel).len(), 0);
let mut stage = SystemStage::parallel()
.with_system(empty.label(A0))
.with_system(component.label(A1).after(A0))
.with_system(empty.label(A2))
.with_system(empty.label(A3).after(A2).before(A4))
.with_system(component.label(A4));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A1.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A1.as_label()))
);
assert_eq!(ambiguities.len(), 1);
let mut stage = SystemStage::parallel()
.with_system(empty.label(A0))
.with_system(resource.label(A1).after(A0))
.with_system(empty.label(A2))
.with_system(empty.label(A3).after(A2).before(A4))
.with_system(resource.label(A4));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A1.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A1.as_label()))
);
assert_eq!(ambiguities.len(), 1);
let mut stage = SystemStage::parallel()
.with_system(empty.label(A0))
.with_system(resource.label(A1).after(A0))
.with_system(empty.label(A2))
.with_system(empty.label(A3).after(A2).before(A4))
.with_system(component.label(A4));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
assert_eq!(find_ambiguities(&stage.parallel).len(), 0);
let mut stage = SystemStage::parallel()
.with_system(component.label(A0))
.with_system(resource.label(A1).after(A0))
.with_system(empty.label(A2))
.with_system(component.label(A3).after(A2).before(A4))
.with_system(resource.label(A4));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A0.as_label(), A3.as_label()))
|| ambiguities.contains(&(A3.as_label(), A0.as_label()))
);
assert!(
ambiguities.contains(&(A1.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A1.as_label()))
);
assert_eq!(ambiguities.len(), 2);
let mut stage = SystemStage::parallel()
.with_system(component.label(A0))
.with_system(resource.label(A1).after(A0).in_ambiguity_set(SetA))
.with_system(empty.label(A2))
.with_system(component.label(A3).after(A2).before(A4))
.with_system(resource.label(A4).in_ambiguity_set(SetA));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A0.as_label(), A3.as_label()))
|| ambiguities.contains(&(A3.as_label(), A0.as_label()))
);
assert_eq!(ambiguities.len(), 1);
let mut stage = SystemStage::parallel()
.with_system(component.label(A0).before(A2))
.with_system(component.label(A1).before(A2))
.with_system(component.label(A2));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A0.as_label(), A1.as_label()))
|| ambiguities.contains(&(A1.as_label(), A0.as_label()))
);
assert_eq!(ambiguities.len(), 1);
let mut stage = SystemStage::parallel()
.with_system(component.label(A0))
.with_system(component.label(A1).after(A0))
.with_system(component.label(A2).after(A0));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A1.as_label(), A2.as_label()))
|| ambiguities.contains(&(A2.as_label(), A1.as_label()))
);
assert_eq!(ambiguities.len(), 1);
let mut stage = SystemStage::parallel()
.with_system(component.label(A0).before(A1).before(A2))
.with_system(component.label(A1))
.with_system(component.label(A2))
.with_system(component.label(A3).after(A1).after(A2));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A1.as_label(), A2.as_label()))
|| ambiguities.contains(&(A2.as_label(), A1.as_label()))
);
assert_eq!(ambiguities.len(), 1);
let mut stage = SystemStage::parallel()
.with_system(component.label(A0).before(A1).before(A2))
.with_system(component.label(A1).in_ambiguity_set(SetA))
.with_system(component.label(A2).in_ambiguity_set(SetA))
.with_system(component.label(A3).after(A1).after(A2));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert_eq!(ambiguities.len(), 0);
let mut stage = SystemStage::parallel()
.with_system(component.label(A0).before(A1).before(A2))
.with_system(component.label(A1).in_ambiguity_set(SetA))
.with_system(component.label(A2).in_ambiguity_set(SetB))
.with_system(component.label(A3).after(A1).after(A2));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A1.as_label(), A2.as_label()))
|| ambiguities.contains(&(A2.as_label(), A1.as_label()))
);
assert_eq!(ambiguities.len(), 1);
let mut stage = SystemStage::parallel()
.with_system(
component
.label(A0)
.before(A1)
.before(A2)
.before(A3)
.before(A4),
)
.with_system(component.label(A1))
.with_system(component.label(A2))
.with_system(component.label(A3))
.with_system(component.label(A4))
.with_system(component.label(A5).after(A1).after(A2).after(A3).after(A4));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A1.as_label(), A2.as_label()))
|| ambiguities.contains(&(A2.as_label(), A1.as_label()))
);
assert!(
ambiguities.contains(&(A1.as_label(), A3.as_label()))
|| ambiguities.contains(&(A3.as_label(), A1.as_label()))
);
assert!(
ambiguities.contains(&(A1.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A1.as_label()))
);
assert!(
ambiguities.contains(&(A2.as_label(), A3.as_label()))
|| ambiguities.contains(&(A3.as_label(), A2.as_label()))
);
assert!(
ambiguities.contains(&(A2.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A2.as_label()))
);
assert!(
ambiguities.contains(&(A3.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A3.as_label()))
);
assert_eq!(ambiguities.len(), 6);
let mut stage = SystemStage::parallel()
.with_system(
component
.label(A0)
.before(A1)
.before(A2)
.before(A3)
.before(A4),
)
.with_system(component.label(A1).in_ambiguity_set(SetA))
.with_system(component.label(A2).in_ambiguity_set(SetA))
.with_system(component.label(A3).in_ambiguity_set(SetA))
.with_system(component.label(A4).in_ambiguity_set(SetA))
.with_system(component.label(A5).after(A1).after(A2).after(A3).after(A4));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert_eq!(ambiguities.len(), 0);
let mut stage = SystemStage::parallel()
.with_system(
component
.label(A0)
.before(A1)
.before(A2)
.before(A3)
.before(A4),
)
.with_system(component.label(A1).in_ambiguity_set(SetA))
.with_system(component.label(A2).in_ambiguity_set(SetA))
.with_system(
component
.label(A3)
.in_ambiguity_set(SetA)
.in_ambiguity_set(SetB),
)
.with_system(component.label(A4).in_ambiguity_set(SetB))
.with_system(component.label(A5).after(A1).after(A2).after(A3).after(A4));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.parallel);
assert!(
ambiguities.contains(&(A1.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A1.as_label()))
);
assert!(
ambiguities.contains(&(A2.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A2.as_label()))
);
assert_eq!(ambiguities.len(), 2);
let mut stage = SystemStage::parallel()
.with_system(empty.exclusive_system().label(A0))
.with_system(empty.exclusive_system().label(A1).after(A0))
.with_system(empty.exclusive_system().label(A2).after(A1))
.with_system(empty.exclusive_system().label(A3).after(A2))
.with_system(empty.exclusive_system().label(A4).after(A3))
.with_system(empty.exclusive_system().label(A5).after(A4))
.with_system(empty.exclusive_system().label(A6).after(A5))
.with_system(empty.exclusive_system().label(A7).after(A6));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
assert_eq!(find_ambiguities(&stage.exclusive_at_start).len(), 0);
let mut stage = SystemStage::parallel()
.with_system(empty.exclusive_system().label(A0).before(A1).before(A3))
.with_system(empty.exclusive_system().label(A1))
.with_system(empty.exclusive_system().label(A2).after(A1))
.with_system(empty.exclusive_system().label(A3))
.with_system(empty.exclusive_system().label(A4).after(A3).before(A5))
.with_system(empty.exclusive_system().label(A5))
.with_system(empty.exclusive_system().label(A6).after(A2).after(A5));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.exclusive_at_start);
assert!(
ambiguities.contains(&(A1.as_label(), A3.as_label()))
|| ambiguities.contains(&(A3.as_label(), A1.as_label()))
);
assert!(
ambiguities.contains(&(A2.as_label(), A3.as_label()))
|| ambiguities.contains(&(A3.as_label(), A2.as_label()))
);
assert!(
ambiguities.contains(&(A1.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A1.as_label()))
);
assert!(
ambiguities.contains(&(A2.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A2.as_label()))
);
assert!(
ambiguities.contains(&(A1.as_label(), A5.as_label()))
|| ambiguities.contains(&(A5.as_label(), A1.as_label()))
);
assert!(
ambiguities.contains(&(A2.as_label(), A5.as_label()))
|| ambiguities.contains(&(A5.as_label(), A2.as_label()))
);
assert_eq!(ambiguities.len(), 6);
let mut stage = SystemStage::parallel()
.with_system(empty.exclusive_system().label(A0).before(A1).before(A3))
.with_system(empty.exclusive_system().label(A1).in_ambiguity_set(SetA))
.with_system(empty.exclusive_system().label(A2).after(A1))
.with_system(empty.exclusive_system().label(A3).in_ambiguity_set(SetA))
.with_system(empty.exclusive_system().label(A4).after(A3).before(A5))
.with_system(empty.exclusive_system().label(A5).in_ambiguity_set(SetA))
.with_system(empty.exclusive_system().label(A6).after(A2).after(A5));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.exclusive_at_start);
assert!(
ambiguities.contains(&(A2.as_label(), A3.as_label()))
|| ambiguities.contains(&(A3.as_label(), A2.as_label()))
);
assert!(
ambiguities.contains(&(A1.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A1.as_label()))
);
assert!(
ambiguities.contains(&(A2.as_label(), A4.as_label()))
|| ambiguities.contains(&(A4.as_label(), A2.as_label()))
);
assert!(
ambiguities.contains(&(A2.as_label(), A5.as_label()))
|| ambiguities.contains(&(A5.as_label(), A2.as_label()))
);
assert_eq!(ambiguities.len(), 4);
let mut stage = SystemStage::parallel()
.with_system(empty.exclusive_system().label(A0).in_ambiguity_set(SetA))
.with_system(empty.exclusive_system().label(A1).in_ambiguity_set(SetA))
.with_system(empty.exclusive_system().label(A2).in_ambiguity_set(SetA))
.with_system(empty.exclusive_system().label(A3).in_ambiguity_set(SetA));
stage.initialize_systems(&mut world);
stage.rebuild_orders_and_dependencies();
let ambiguities = find_ambiguities_first_labels(&stage.exclusive_at_start);
assert_eq!(ambiguities.len(), 0);
}
#[test] #[test]
#[should_panic] #[should_panic]
fn multiple_worlds_same_stage() { fn multiple_worlds_same_stage() {

View file

@ -2,8 +2,8 @@ use crate::{
component::ComponentId, component::ComponentId,
query::Access, query::Access,
schedule::{ schedule::{
AmbiguitySetLabelId, ExclusiveSystemDescriptor, GraphNode, ParallelSystemDescriptor, ExclusiveSystemDescriptor, GraphNode, ParallelSystemDescriptor, RunCriteriaLabelId,
RunCriteriaLabelId, SystemLabelId, SystemLabelId,
}, },
system::{ExclusiveSystem, System}, system::{ExclusiveSystem, System},
}; };
@ -20,7 +20,6 @@ pub trait SystemContainer: GraphNode<Label = SystemLabelId> {
#[doc(hidden)] #[doc(hidden)]
fn set_run_criteria(&mut self, index: usize); fn set_run_criteria(&mut self, index: usize);
fn run_criteria_label(&self) -> Option<&RunCriteriaLabelId>; fn run_criteria_label(&self) -> Option<&RunCriteriaLabelId>;
fn ambiguity_sets(&self) -> &[AmbiguitySetLabelId];
fn component_access(&self) -> Option<&Access<ComponentId>>; fn component_access(&self) -> Option<&Access<ComponentId>>;
} }
@ -32,7 +31,6 @@ pub(super) struct ExclusiveSystemContainer {
labels: Vec<SystemLabelId>, labels: Vec<SystemLabelId>,
before: Vec<SystemLabelId>, before: Vec<SystemLabelId>,
after: Vec<SystemLabelId>, after: Vec<SystemLabelId>,
ambiguity_sets: Vec<AmbiguitySetLabelId>,
} }
impl ExclusiveSystemContainer { impl ExclusiveSystemContainer {
@ -45,7 +43,6 @@ impl ExclusiveSystemContainer {
labels: descriptor.labels, labels: descriptor.labels,
before: descriptor.before, before: descriptor.before,
after: descriptor.after, after: descriptor.after,
ambiguity_sets: descriptor.ambiguity_sets,
} }
} }
@ -96,10 +93,6 @@ impl SystemContainer for ExclusiveSystemContainer {
self.run_criteria_label.as_ref() self.run_criteria_label.as_ref()
} }
fn ambiguity_sets(&self) -> &[AmbiguitySetLabelId] {
&self.ambiguity_sets
}
fn component_access(&self) -> Option<&Access<ComponentId>> { fn component_access(&self) -> Option<&Access<ComponentId>> {
None None
} }
@ -114,7 +107,6 @@ pub struct ParallelSystemContainer {
labels: Vec<SystemLabelId>, labels: Vec<SystemLabelId>,
before: Vec<SystemLabelId>, before: Vec<SystemLabelId>,
after: Vec<SystemLabelId>, after: Vec<SystemLabelId>,
ambiguity_sets: Vec<AmbiguitySetLabelId>,
} }
impl ParallelSystemContainer { impl ParallelSystemContainer {
@ -128,7 +120,6 @@ impl ParallelSystemContainer {
labels: descriptor.labels, labels: descriptor.labels,
before: descriptor.before, before: descriptor.before,
after: descriptor.after, after: descriptor.after,
ambiguity_sets: descriptor.ambiguity_sets,
} }
} }
@ -195,10 +186,6 @@ impl SystemContainer for ParallelSystemContainer {
self.run_criteria_label.as_ref() self.run_criteria_label.as_ref()
} }
fn ambiguity_sets(&self) -> &[AmbiguitySetLabelId] {
&self.ambiguity_sets
}
fn component_access(&self) -> Option<&Access<ComponentId>> { fn component_access(&self) -> Option<&Access<ComponentId>> {
Some(self.system().component_access()) Some(self.system().component_access())
} }

View file

@ -1,8 +1,5 @@
use crate::{ use crate::{
schedule::{ schedule::{IntoRunCriteria, RunCriteriaDescriptorOrLabel, SystemLabel, SystemLabelId},
AmbiguitySetLabel, AmbiguitySetLabelId, IntoRunCriteria, RunCriteriaDescriptorOrLabel,
SystemLabel, SystemLabelId,
},
system::{ system::{
AsSystemLabel, BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, AsSystemLabel, BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn,
IntoSystem, IntoSystem,
@ -101,7 +98,6 @@ pub struct ParallelSystemDescriptor {
pub(crate) labels: Vec<SystemLabelId>, pub(crate) labels: Vec<SystemLabelId>,
pub(crate) before: Vec<SystemLabelId>, pub(crate) before: Vec<SystemLabelId>,
pub(crate) after: Vec<SystemLabelId>, pub(crate) after: Vec<SystemLabelId>,
pub(crate) ambiguity_sets: Vec<AmbiguitySetLabelId>,
} }
fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescriptor { fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescriptor {
@ -111,7 +107,6 @@ fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescrip
run_criteria: None, run_criteria: None,
before: Vec::new(), before: Vec::new(),
after: Vec::new(), after: Vec::new(),
ambiguity_sets: Vec::new(),
} }
} }
@ -131,10 +126,6 @@ pub trait ParallelSystemDescriptorCoercion<Params> {
/// Specifies that the system should run after systems with the given label. /// Specifies that the system should run after systems with the given label.
fn after<Marker>(self, label: impl AsSystemLabel<Marker>) -> ParallelSystemDescriptor; fn after<Marker>(self, label: impl AsSystemLabel<Marker>) -> ParallelSystemDescriptor;
/// Specifies that the system is exempt from execution order ambiguity detection
/// with other systems in this set.
fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ParallelSystemDescriptor;
} }
impl ParallelSystemDescriptorCoercion<()> for ParallelSystemDescriptor { impl ParallelSystemDescriptorCoercion<()> for ParallelSystemDescriptor {
@ -160,11 +151,6 @@ impl ParallelSystemDescriptorCoercion<()> for ParallelSystemDescriptor {
self.after.push(label.as_system_label().as_label()); self.after.push(label.as_system_label().as_label());
self self
} }
fn in_ambiguity_set(mut self, set: impl AmbiguitySetLabel) -> ParallelSystemDescriptor {
self.ambiguity_sets.push(set.as_label());
self
}
} }
impl<S, Params> ParallelSystemDescriptorCoercion<Params> for S impl<S, Params> ParallelSystemDescriptorCoercion<Params> for S
@ -190,10 +176,6 @@ where
fn after<Marker>(self, label: impl AsSystemLabel<Marker>) -> ParallelSystemDescriptor { fn after<Marker>(self, label: impl AsSystemLabel<Marker>) -> ParallelSystemDescriptor {
new_parallel_descriptor(Box::new(IntoSystem::into_system(self))).after(label) new_parallel_descriptor(Box::new(IntoSystem::into_system(self))).after(label)
} }
fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ParallelSystemDescriptor {
new_parallel_descriptor(Box::new(IntoSystem::into_system(self))).in_ambiguity_set(set)
}
} }
impl ParallelSystemDescriptorCoercion<()> for BoxedSystem<(), ()> { impl ParallelSystemDescriptorCoercion<()> for BoxedSystem<(), ()> {
@ -215,10 +197,6 @@ impl ParallelSystemDescriptorCoercion<()> for BoxedSystem<(), ()> {
fn after<Marker>(self, label: impl AsSystemLabel<Marker>) -> ParallelSystemDescriptor { fn after<Marker>(self, label: impl AsSystemLabel<Marker>) -> ParallelSystemDescriptor {
new_parallel_descriptor(self).after(label) new_parallel_descriptor(self).after(label)
} }
fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ParallelSystemDescriptor {
new_parallel_descriptor(self).in_ambiguity_set(set)
}
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -235,7 +213,6 @@ pub struct ExclusiveSystemDescriptor {
pub(crate) labels: Vec<SystemLabelId>, pub(crate) labels: Vec<SystemLabelId>,
pub(crate) before: Vec<SystemLabelId>, pub(crate) before: Vec<SystemLabelId>,
pub(crate) after: Vec<SystemLabelId>, pub(crate) after: Vec<SystemLabelId>,
pub(crate) ambiguity_sets: Vec<AmbiguitySetLabelId>,
pub(crate) insertion_point: InsertionPoint, pub(crate) insertion_point: InsertionPoint,
} }
@ -246,7 +223,6 @@ fn new_exclusive_descriptor(system: Box<dyn ExclusiveSystem>) -> ExclusiveSystem
labels: Vec::new(), labels: Vec::new(),
before: Vec::new(), before: Vec::new(),
after: Vec::new(), after: Vec::new(),
ambiguity_sets: Vec::new(),
insertion_point: InsertionPoint::AtStart, insertion_point: InsertionPoint::AtStart,
} }
} }
@ -268,10 +244,6 @@ pub trait ExclusiveSystemDescriptorCoercion {
/// Specifies that the system should run after systems with the given label. /// Specifies that the system should run after systems with the given label.
fn after(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor; fn after(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor;
/// Specifies that the system is exempt from execution order ambiguity detection
/// with other systems in this set.
fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ExclusiveSystemDescriptor;
/// Specifies that the system should run with other exclusive systems at the start of stage. /// Specifies that the system should run with other exclusive systems at the start of stage.
fn at_start(self) -> ExclusiveSystemDescriptor; fn at_start(self) -> ExclusiveSystemDescriptor;
@ -307,11 +279,6 @@ impl ExclusiveSystemDescriptorCoercion for ExclusiveSystemDescriptor {
self self
} }
fn in_ambiguity_set(mut self, set: impl AmbiguitySetLabel) -> ExclusiveSystemDescriptor {
self.ambiguity_sets.push(set.as_label());
self
}
fn at_start(mut self) -> ExclusiveSystemDescriptor { fn at_start(mut self) -> ExclusiveSystemDescriptor {
self.insertion_point = InsertionPoint::AtStart; self.insertion_point = InsertionPoint::AtStart;
self self
@ -351,10 +318,6 @@ where
new_exclusive_descriptor(Box::new(self)).after(label) new_exclusive_descriptor(Box::new(self)).after(label)
} }
fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ExclusiveSystemDescriptor {
new_exclusive_descriptor(Box::new(self)).in_ambiguity_set(set)
}
fn at_start(self) -> ExclusiveSystemDescriptor { fn at_start(self) -> ExclusiveSystemDescriptor {
new_exclusive_descriptor(Box::new(self)).at_start() new_exclusive_descriptor(Box::new(self)).at_start()
} }

View file

@ -1,6 +1,6 @@
use crate::schedule::{ use crate::schedule::{
AmbiguitySetLabel, AmbiguitySetLabelId, IntoRunCriteria, IntoSystemDescriptor, IntoRunCriteria, IntoSystemDescriptor, RunCriteriaDescriptorOrLabel, State, StateData,
RunCriteriaDescriptorOrLabel, State, StateData, SystemDescriptor, SystemLabel, SystemLabelId, SystemDescriptor, SystemLabel, SystemLabelId,
}; };
use crate::system::AsSystemLabel; use crate::system::AsSystemLabel;
@ -12,7 +12,6 @@ pub struct SystemSet {
pub(crate) labels: Vec<SystemLabelId>, pub(crate) labels: Vec<SystemLabelId>,
pub(crate) before: Vec<SystemLabelId>, pub(crate) before: Vec<SystemLabelId>,
pub(crate) after: Vec<SystemLabelId>, pub(crate) after: Vec<SystemLabelId>,
pub(crate) ambiguity_sets: Vec<AmbiguitySetLabelId>,
} }
impl SystemSet { impl SystemSet {
@ -69,12 +68,6 @@ impl SystemSet {
Self::new().with_run_criteria(State::<T>::on_resume(s)) Self::new().with_run_criteria(State::<T>::on_resume(s))
} }
#[must_use]
pub fn in_ambiguity_set(mut self, set: impl AmbiguitySetLabel) -> Self {
self.ambiguity_sets.push(set.as_label());
self
}
#[must_use] #[must_use]
pub fn with_system<Params>(mut self, system: impl IntoSystemDescriptor<Params>) -> Self { pub fn with_system<Params>(mut self, system: impl IntoSystemDescriptor<Params>) -> Self {
self.systems.push(system.into_descriptor()); self.systems.push(system.into_descriptor());
@ -112,7 +105,6 @@ impl SystemSet {
labels, labels,
before, before,
after, after,
ambiguity_sets,
} = self; } = self;
for descriptor in &mut systems { for descriptor in &mut systems {
match descriptor { match descriptor {
@ -120,17 +112,11 @@ impl SystemSet {
descriptor.labels.extend(labels.iter().cloned()); descriptor.labels.extend(labels.iter().cloned());
descriptor.before.extend(before.iter().cloned()); descriptor.before.extend(before.iter().cloned());
descriptor.after.extend(after.iter().cloned()); descriptor.after.extend(after.iter().cloned());
descriptor
.ambiguity_sets
.extend(ambiguity_sets.iter().cloned());
} }
SystemDescriptor::Exclusive(descriptor) => { SystemDescriptor::Exclusive(descriptor) => {
descriptor.labels.extend(labels.iter().cloned()); descriptor.labels.extend(labels.iter().cloned());
descriptor.before.extend(before.iter().cloned()); descriptor.before.extend(before.iter().cloned());
descriptor.after.extend(after.iter().cloned()); descriptor.after.extend(after.iter().cloned());
descriptor
.ambiguity_sets
.extend(ambiguity_sets.iter().cloned());
} }
} }
} }