Use component_access_set to determine the set of conflicting accesses between two systems. (#19495)
# Objective - Fixes #4381 ## Solution - Replace `component_access` with `component_access_set` when determining conflicting systems during schedule building. - All `component_access()` impls just forward to `&component_access_set().combined_access`, so we are essentially trading `Access::is_compatible` for `FilteredAccessSet::is_compatible`. - `FilteredAccessSet::get_conflicts` internally calls `combined_access.is_compatible` as the first step, so we can remove that redundant check. ## Testing - Un-ignored a previously failing test now that it passes! - Ran the `build_schedule` benchmark and got basically no change in the results. Perhaps are benchmarks are just not targetted towards this situation. ``` $ critcmp main fix-ambiguity -f 'build_schedule' group fix-ambiguity main ----- ------------- ---- build_schedule/1000_schedule 1.00 2.9±0.02s ? ?/sec 1.01 2.9±0.05s ? ?/sec build_schedule/1000_schedule_no_constraints 1.02 48.3±1.48ms ? ?/sec 1.00 47.4±1.78ms ? ?/sec build_schedule/100_schedule 1.00 9.9±0.17ms ? ?/sec 1.06 10.5±0.32ms ? ?/sec build_schedule/100_schedule_no_constraints 1.00 804.7±21.85µs ? ?/sec 1.03 828.7±19.36µs ? ?/sec build_schedule/500_schedule 1.00 451.7±7.25ms ? ?/sec 1.04 468.9±11.70ms ? ?/sec build_schedule/500_schedule_no_constraints 1.02 12.7±0.46ms ? ?/sec 1.00 12.5±0.44ms ? ?/sec ```
This commit is contained in:
parent
064e5e48b4
commit
f163649b48
@ -874,7 +874,6 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "Known failing but fix is non-trivial: https://github.com/bevyengine/bevy/issues/4381"]
|
||||
fn filtered_components() {
|
||||
let mut world = World::new();
|
||||
world.spawn(A);
|
||||
|
@ -1418,26 +1418,24 @@ impl ScheduleGraph {
|
||||
if system_a.is_exclusive() || system_b.is_exclusive() {
|
||||
conflicting_systems.push((a, b, Vec::new()));
|
||||
} else {
|
||||
let access_a = system_a.component_access();
|
||||
let access_b = system_b.component_access();
|
||||
if !access_a.is_compatible(access_b) {
|
||||
match access_a.get_conflicts(access_b) {
|
||||
AccessConflicts::Individual(conflicts) => {
|
||||
let conflicts: Vec<_> = conflicts
|
||||
.ones()
|
||||
.map(ComponentId::get_sparse_set_index)
|
||||
.filter(|id| !ignored_ambiguities.contains(id))
|
||||
.collect();
|
||||
if !conflicts.is_empty() {
|
||||
conflicting_systems.push((a, b, conflicts));
|
||||
}
|
||||
}
|
||||
AccessConflicts::All => {
|
||||
// there is no specific component conflicting, but the systems are overall incompatible
|
||||
// for example 2 systems with `Query<EntityMut>`
|
||||
conflicting_systems.push((a, b, Vec::new()));
|
||||
let access_a = system_a.component_access_set();
|
||||
let access_b = system_b.component_access_set();
|
||||
match access_a.get_conflicts(access_b) {
|
||||
AccessConflicts::Individual(conflicts) => {
|
||||
let conflicts: Vec<_> = conflicts
|
||||
.ones()
|
||||
.map(ComponentId::get_sparse_set_index)
|
||||
.filter(|id| !ignored_ambiguities.contains(id))
|
||||
.collect();
|
||||
if !conflicts.is_empty() {
|
||||
conflicting_systems.push((a, b, conflicts));
|
||||
}
|
||||
}
|
||||
AccessConflicts::All => {
|
||||
// there is no specific component conflicting, but the systems are overall incompatible
|
||||
// for example 2 systems with `Query<EntityMut>`
|
||||
conflicting_systems.push((a, b, Vec::new()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user