mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
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:
parent
54e32ee681
commit
c96b7ffb50
7 changed files with 12 additions and 496 deletions
|
@ -462,21 +462,6 @@ pub fn derive_stage_label(input: TokenStream) -> TokenStream {
|
|||
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.
|
||||
///
|
||||
/// This works only for unit structs, or enums with only unit variants.
|
||||
|
|
|
@ -34,9 +34,9 @@ pub mod prelude {
|
|||
event::{EventReader, EventWriter, Events},
|
||||
query::{Added, AnyOf, ChangeTrackers, Changed, Or, QueryState, With, Without},
|
||||
schedule::{
|
||||
AmbiguitySetLabel, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion,
|
||||
RunCriteria, RunCriteriaDescriptorCoercion, RunCriteriaLabel, Schedule, Stage,
|
||||
StageLabel, State, SystemLabel, SystemSet, SystemStage,
|
||||
ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion, RunCriteria,
|
||||
RunCriteriaDescriptorCoercion, RunCriteriaLabel, Schedule, Stage, StageLabel, State,
|
||||
SystemLabel, SystemSet, SystemStage,
|
||||
},
|
||||
system::{
|
||||
adapter as system_adapter, Commands, In, IntoChainSystem, IntoExclusiveSystem,
|
||||
|
|
|
@ -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;
|
||||
|
||||
define_label!(
|
||||
|
@ -13,12 +13,6 @@ define_label!(
|
|||
/// Strongly-typed identifier for a [`SystemLabel`].
|
||||
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!(
|
||||
/// A strongly-typed class of labels used to identify [run criteria](crate::schedule::RunCriteria).
|
||||
RunCriteriaLabel,
|
||||
|
|
|
@ -713,20 +713,9 @@ fn process_systems(
|
|||
/// along with specific components that have triggered the warning.
|
||||
/// Systems must be topologically sorted beforehand.
|
||||
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_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]);
|
||||
|
@ -765,9 +754,7 @@ fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize, Vec<
|
|||
for index_b in full_bitset.difference(&relations)
|
||||
// .take(index_a)
|
||||
{
|
||||
if !processed.contains(index_b)
|
||||
&& all_ambiguity_sets[index_a].is_disjoint(&all_ambiguity_sets[index_b])
|
||||
{
|
||||
if !processed.contains(index_b) {
|
||||
let a_access = systems[index_a].component_access();
|
||||
let b_access = systems[index_b].component_access();
|
||||
if let (Some(a), Some(b)) = (a_access, b_access) {
|
||||
|
@ -972,13 +959,13 @@ impl Stage for SystemStage {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use bevy_ecs_macros::{AmbiguitySetLabel, RunCriteriaLabel};
|
||||
use bevy_ecs_macros::RunCriteriaLabel;
|
||||
|
||||
use crate::{
|
||||
schedule::{
|
||||
ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion, RunCriteria,
|
||||
RunCriteriaDescriptorCoercion, ShouldRun, SingleThreadedExecutor, Stage, SystemLabel,
|
||||
SystemLabelId, SystemSet, SystemStage,
|
||||
SystemSet, SystemStage,
|
||||
},
|
||||
system::{In, IntoExclusiveSystem, Local, Query, ResMut},
|
||||
world::World,
|
||||
|
@ -1607,392 +1594,6 @@ mod tests {
|
|||
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]
|
||||
#[should_panic]
|
||||
fn multiple_worlds_same_stage() {
|
||||
|
|
|
@ -2,8 +2,8 @@ use crate::{
|
|||
component::ComponentId,
|
||||
query::Access,
|
||||
schedule::{
|
||||
AmbiguitySetLabelId, ExclusiveSystemDescriptor, GraphNode, ParallelSystemDescriptor,
|
||||
RunCriteriaLabelId, SystemLabelId,
|
||||
ExclusiveSystemDescriptor, GraphNode, ParallelSystemDescriptor, RunCriteriaLabelId,
|
||||
SystemLabelId,
|
||||
},
|
||||
system::{ExclusiveSystem, System},
|
||||
};
|
||||
|
@ -20,7 +20,6 @@ pub trait SystemContainer: GraphNode<Label = SystemLabelId> {
|
|||
#[doc(hidden)]
|
||||
fn set_run_criteria(&mut self, index: usize);
|
||||
fn run_criteria_label(&self) -> Option<&RunCriteriaLabelId>;
|
||||
fn ambiguity_sets(&self) -> &[AmbiguitySetLabelId];
|
||||
fn component_access(&self) -> Option<&Access<ComponentId>>;
|
||||
}
|
||||
|
||||
|
@ -32,7 +31,6 @@ pub(super) struct ExclusiveSystemContainer {
|
|||
labels: Vec<SystemLabelId>,
|
||||
before: Vec<SystemLabelId>,
|
||||
after: Vec<SystemLabelId>,
|
||||
ambiguity_sets: Vec<AmbiguitySetLabelId>,
|
||||
}
|
||||
|
||||
impl ExclusiveSystemContainer {
|
||||
|
@ -45,7 +43,6 @@ impl ExclusiveSystemContainer {
|
|||
labels: descriptor.labels,
|
||||
before: descriptor.before,
|
||||
after: descriptor.after,
|
||||
ambiguity_sets: descriptor.ambiguity_sets,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,10 +93,6 @@ impl SystemContainer for ExclusiveSystemContainer {
|
|||
self.run_criteria_label.as_ref()
|
||||
}
|
||||
|
||||
fn ambiguity_sets(&self) -> &[AmbiguitySetLabelId] {
|
||||
&self.ambiguity_sets
|
||||
}
|
||||
|
||||
fn component_access(&self) -> Option<&Access<ComponentId>> {
|
||||
None
|
||||
}
|
||||
|
@ -114,7 +107,6 @@ pub struct ParallelSystemContainer {
|
|||
labels: Vec<SystemLabelId>,
|
||||
before: Vec<SystemLabelId>,
|
||||
after: Vec<SystemLabelId>,
|
||||
ambiguity_sets: Vec<AmbiguitySetLabelId>,
|
||||
}
|
||||
|
||||
impl ParallelSystemContainer {
|
||||
|
@ -128,7 +120,6 @@ impl ParallelSystemContainer {
|
|||
labels: descriptor.labels,
|
||||
before: descriptor.before,
|
||||
after: descriptor.after,
|
||||
ambiguity_sets: descriptor.ambiguity_sets,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,10 +186,6 @@ impl SystemContainer for ParallelSystemContainer {
|
|||
self.run_criteria_label.as_ref()
|
||||
}
|
||||
|
||||
fn ambiguity_sets(&self) -> &[AmbiguitySetLabelId] {
|
||||
&self.ambiguity_sets
|
||||
}
|
||||
|
||||
fn component_access(&self) -> Option<&Access<ComponentId>> {
|
||||
Some(self.system().component_access())
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
use crate::{
|
||||
schedule::{
|
||||
AmbiguitySetLabel, AmbiguitySetLabelId, IntoRunCriteria, RunCriteriaDescriptorOrLabel,
|
||||
SystemLabel, SystemLabelId,
|
||||
},
|
||||
schedule::{IntoRunCriteria, RunCriteriaDescriptorOrLabel, SystemLabel, SystemLabelId},
|
||||
system::{
|
||||
AsSystemLabel, BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn,
|
||||
IntoSystem,
|
||||
|
@ -101,7 +98,6 @@ pub struct ParallelSystemDescriptor {
|
|||
pub(crate) labels: Vec<SystemLabelId>,
|
||||
pub(crate) before: Vec<SystemLabelId>,
|
||||
pub(crate) after: Vec<SystemLabelId>,
|
||||
pub(crate) ambiguity_sets: Vec<AmbiguitySetLabelId>,
|
||||
}
|
||||
|
||||
fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescriptor {
|
||||
|
@ -111,7 +107,6 @@ fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescrip
|
|||
run_criteria: None,
|
||||
before: 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.
|
||||
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 {
|
||||
|
@ -160,11 +151,6 @@ impl ParallelSystemDescriptorCoercion<()> for ParallelSystemDescriptor {
|
|||
self.after.push(label.as_system_label().as_label());
|
||||
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
|
||||
|
@ -190,10 +176,6 @@ where
|
|||
fn after<Marker>(self, label: impl AsSystemLabel<Marker>) -> ParallelSystemDescriptor {
|
||||
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<(), ()> {
|
||||
|
@ -215,10 +197,6 @@ impl ParallelSystemDescriptorCoercion<()> for BoxedSystem<(), ()> {
|
|||
fn after<Marker>(self, label: impl AsSystemLabel<Marker>) -> ParallelSystemDescriptor {
|
||||
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)]
|
||||
|
@ -235,7 +213,6 @@ pub struct ExclusiveSystemDescriptor {
|
|||
pub(crate) labels: Vec<SystemLabelId>,
|
||||
pub(crate) before: Vec<SystemLabelId>,
|
||||
pub(crate) after: Vec<SystemLabelId>,
|
||||
pub(crate) ambiguity_sets: Vec<AmbiguitySetLabelId>,
|
||||
pub(crate) insertion_point: InsertionPoint,
|
||||
}
|
||||
|
||||
|
@ -246,7 +223,6 @@ fn new_exclusive_descriptor(system: Box<dyn ExclusiveSystem>) -> ExclusiveSystem
|
|||
labels: Vec::new(),
|
||||
before: Vec::new(),
|
||||
after: Vec::new(),
|
||||
ambiguity_sets: Vec::new(),
|
||||
insertion_point: InsertionPoint::AtStart,
|
||||
}
|
||||
}
|
||||
|
@ -268,10 +244,6 @@ pub trait ExclusiveSystemDescriptorCoercion {
|
|||
/// Specifies that the system should run after systems with the given label.
|
||||
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.
|
||||
fn at_start(self) -> ExclusiveSystemDescriptor;
|
||||
|
||||
|
@ -307,11 +279,6 @@ impl ExclusiveSystemDescriptorCoercion for ExclusiveSystemDescriptor {
|
|||
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 {
|
||||
self.insertion_point = InsertionPoint::AtStart;
|
||||
self
|
||||
|
@ -351,10 +318,6 @@ where
|
|||
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 {
|
||||
new_exclusive_descriptor(Box::new(self)).at_start()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::schedule::{
|
||||
AmbiguitySetLabel, AmbiguitySetLabelId, IntoRunCriteria, IntoSystemDescriptor,
|
||||
RunCriteriaDescriptorOrLabel, State, StateData, SystemDescriptor, SystemLabel, SystemLabelId,
|
||||
IntoRunCriteria, IntoSystemDescriptor, RunCriteriaDescriptorOrLabel, State, StateData,
|
||||
SystemDescriptor, SystemLabel, SystemLabelId,
|
||||
};
|
||||
use crate::system::AsSystemLabel;
|
||||
|
||||
|
@ -12,7 +12,6 @@ pub struct SystemSet {
|
|||
pub(crate) labels: Vec<SystemLabelId>,
|
||||
pub(crate) before: Vec<SystemLabelId>,
|
||||
pub(crate) after: Vec<SystemLabelId>,
|
||||
pub(crate) ambiguity_sets: Vec<AmbiguitySetLabelId>,
|
||||
}
|
||||
|
||||
impl SystemSet {
|
||||
|
@ -69,12 +68,6 @@ impl SystemSet {
|
|||
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]
|
||||
pub fn with_system<Params>(mut self, system: impl IntoSystemDescriptor<Params>) -> Self {
|
||||
self.systems.push(system.into_descriptor());
|
||||
|
@ -112,7 +105,6 @@ impl SystemSet {
|
|||
labels,
|
||||
before,
|
||||
after,
|
||||
ambiguity_sets,
|
||||
} = self;
|
||||
for descriptor in &mut systems {
|
||||
match descriptor {
|
||||
|
@ -120,17 +112,11 @@ impl SystemSet {
|
|||
descriptor.labels.extend(labels.iter().cloned());
|
||||
descriptor.before.extend(before.iter().cloned());
|
||||
descriptor.after.extend(after.iter().cloned());
|
||||
descriptor
|
||||
.ambiguity_sets
|
||||
.extend(ambiguity_sets.iter().cloned());
|
||||
}
|
||||
SystemDescriptor::Exclusive(descriptor) => {
|
||||
descriptor.labels.extend(labels.iter().cloned());
|
||||
descriptor.before.extend(before.iter().cloned());
|
||||
descriptor.after.extend(after.iter().cloned());
|
||||
descriptor
|
||||
.ambiguity_sets
|
||||
.extend(ambiguity_sets.iter().cloned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue