-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvements to execution order ambiguity reporting #4299
Improvements to execution order ambiguity reporting #4299
Conversation
Comments
EDIT: I took a look, and it's not going to be nice. We need this information at SystemStage, but those are constructed from a
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Thanks for following up on my request in the original PR. I also like that the resource is enabled and set to minimal by default.
Just a small nit about wording.
Would it be interesting for CI purposes to have a way to exit the app with the number of conflicts as the status code? Or at least not 0 if there are conflicts |
IMO the way to do this is to allow users to forbid ambiguities, at both a plugin and app level. This is fundamentally what we need for determinism. I think that's very much worth pursuing, but out of scope for this. |
1705039
to
c01cd76
Compare
Is there a way to un-ignore the internal plugins? |
Yes. Change the ignore_crates field of That said, this whole design is eh... I'm going to see if I can come up with a more reasonable design for this. |
I took a pass at this, and it's not going to be triviak. Current problems:
Blockers:
I think I can make this work though, and I think that hard-coding a list internally is the least bad solution. |
d841f38
to
870f3e8
Compare
@@ -1574,393 +1415,6 @@ mod tests { | |||
stage.run(&mut world); | |||
} | |||
|
|||
#[test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is very fragile and hard to use due to the elaborate "label" reporting strategy.
I've done my best to replace the functionality over in the tests in ambiguity_detection.rs
.
self.executor.rebuild_cached_data(&self.parallel); | ||
self.executor_modified = false; | ||
} | ||
self.initialize(world); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This functionality is useful to the public, so I refactored it out into its own method.
In the long-term I'd prefer a type-safe pattern for this sort of initialized vs uninitailized state, but that's way out of scope.
debug_assert!(!self.systems_modified); | ||
|
||
// TODO: remove all internal ambiguities and remove this logic | ||
let ignored_crates = if report_level != ReportExecutionOrderAmbiguities::ReportInternal { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alternative strategy, of making this a configurable field on a per plugin basis or otherwise enabling this resulted in a much more complex, less ergonomic API.
The hard-coded list still existed, it was just scattered across a dozen different files.
} | ||
|
||
/// Collapses a name returned by std::any::type_name to remove its module path | ||
fn format_type_name(raw_name: &str) -> String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably be done with a single gnarly regex, but I'm not actually sure that would be more readable or maintainable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a function TypeRegistration::get_short_name
that does something very similar to this function. Not sure if it matches exactly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an exact match. I've refactored this out into bevy_utils and reused it.
Thanks!
Since you're using |
Probably. I'd like to use |
79466fd
to
1720cf5
Compare
…tils` (bevyengine#5174) # Summary This method strips a long type name like `bevy::render::camera::PerspectiveCameraBundle` down into the bare type name (`PerspectiveCameraBundle`). This is generally useful utility method, needed by bevyengine#4299 and bevyengine#5121. As a result: - This method was moved to `bevy_utils` for easier reuse. - The legibility and robustness of this method has been significantly improved. - Harder test cases have been added. This change was split out of bevyengine#4299 to unblock it and make merging / reviewing the rest of those changes easier. ## Changelog - added `bevy_utils::get_short_name`, which strips the path from a type name for convenient display. - removed the `TypeRegistry::get_short_name` method. Use the function in `bevy_utils` instead.
Going to carve this up for easier reviewing and less rebasing hell. Based on the original PR description, let's carve this up as follows. Foundational:
Disjoint improvements:
Incremental:
Yeet (fixed by 2 of foundational work):
|
# 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.
# 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 bevyengine#4299, we're removing them. ## Migration Guide Ambiguity sets have been removed.
# Objective This code is very disjoint, and the `stage.rs` file that it's in is already very long. All I've done is move the code and clean up the compiler errors that result. Followup to bevyengine#5916, split out from bevyengine#4299.
# Objective - Add unit tests for ambiguity detection reporting. - Incremental implementation of #4299. ## Solution - Refactor ambiguity detection internals to make it testable. As a bonus, this should make it easier to extend in the future. ## Notes * This code was copy-pasted from #4299 and modified. Credit goes to @alice-i-cecile and @afonsolage, though I'm not sure who wrote what at this point.
# Objective - Add unit tests for ambiguity detection reporting. - Incremental implementation of #4299. ## Solution - Refactor ambiguity detection internals to make it testable. As a bonus, this should make it easier to extend in the future. ## Notes * This code was copy-pasted from #4299 and modified. Credit goes to @alice-i-cecile and @afonsolage, though I'm not sure who wrote what at this point.
# Background Incremental implementation of #4299. The code is heavily borrowed from that PR. # Objective The execution order ambiguity checker often emits false positives, since bevy is not aware of invariants upheld by the user. ## Solution Title --- ## Changelog + Added methods `SystemDescriptor::ignore_all_ambiguities` and `::ambiguous_with`. These allow you to silence warnings for specific system-order ambiguities. ## Migration Guide ***Note for maintainers**: This should replace the migration guide for #5916* Ambiguity sets have been replaced with a simpler API. ```rust // These systems technically conflict, but we don't care which order they run in. fn jump_on_click(mouse: Res<Input<MouseButton>>, mut transforms: Query<&mut Transform>) { ... } fn jump_on_spacebar(keys: Res<Input<KeyCode>>, mut transforms: Query<&mut Transform>) { ... } // // Before #[derive(AmbiguitySetLabel)] struct JumpSystems; app .add_system(jump_on_click.in_ambiguity_set(JumpSystems)) .add_system(jump_on_spacebar.in_ambiguity_set(JumpSystems)); // // After app .add_system(jump_on_click.ambiguous_with(jump_on_spacebar)) .add_system(jump_on_spacebar); ```
# Objective - Add unit tests for ambiguity detection reporting. - Incremental implementation of bevyengine#4299. ## Solution - Refactor ambiguity detection internals to make it testable. As a bonus, this should make it easier to extend in the future. ## Notes * This code was copy-pasted from bevyengine#4299 and modified. Credit goes to @alice-i-cecile and @afonsolage, though I'm not sure who wrote what at this point.
…#6158) # Background Incremental implementation of bevyengine#4299. The code is heavily borrowed from that PR. # Objective The execution order ambiguity checker often emits false positives, since bevy is not aware of invariants upheld by the user. ## Solution Title --- ## Changelog + Added methods `SystemDescriptor::ignore_all_ambiguities` and `::ambiguous_with`. These allow you to silence warnings for specific system-order ambiguities. ## Migration Guide ***Note for maintainers**: This should replace the migration guide for bevyengine#5916* Ambiguity sets have been replaced with a simpler API. ```rust // These systems technically conflict, but we don't care which order they run in. fn jump_on_click(mouse: Res<Input<MouseButton>>, mut transforms: Query<&mut Transform>) { ... } fn jump_on_spacebar(keys: Res<Input<KeyCode>>, mut transforms: Query<&mut Transform>) { ... } // // Before #[derive(AmbiguitySetLabel)] struct JumpSystems; app .add_system(jump_on_click.in_ambiguity_set(JumpSystems)) .add_system(jump_on_spacebar.in_ambiguity_set(JumpSystems)); // // After app .add_system(jump_on_click.ambiguous_with(jump_on_spacebar)) .add_system(jump_on_spacebar); ```
…tils` (bevyengine#5174) # Summary This method strips a long type name like `bevy::render::camera::PerspectiveCameraBundle` down into the bare type name (`PerspectiveCameraBundle`). This is generally useful utility method, needed by bevyengine#4299 and bevyengine#5121. As a result: - This method was moved to `bevy_utils` for easier reuse. - The legibility and robustness of this method has been significantly improved. - Harder test cases have been added. This change was split out of bevyengine#4299 to unblock it and make merging / reviewing the rest of those changes easier. ## Changelog - added `bevy_utils::get_short_name`, which strips the path from a type name for convenient display. - removed the `TypeRegistry::get_short_name` method. Use the function in `bevy_utils` instead.
# 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 bevyengine#4299, we're removing them. ## Migration Guide Ambiguity sets have been removed.
# Objective This code is very disjoint, and the `stage.rs` file that it's in is already very long. All I've done is move the code and clean up the compiler errors that result. Followup to bevyengine#5916, split out from bevyengine#4299.
# Objective - Add unit tests for ambiguity detection reporting. - Incremental implementation of bevyengine#4299. ## Solution - Refactor ambiguity detection internals to make it testable. As a bonus, this should make it easier to extend in the future. ## Notes * This code was copy-pasted from bevyengine#4299 and modified. Credit goes to @alice-i-cecile and @afonsolage, though I'm not sure who wrote what at this point.
…#6158) # Background Incremental implementation of bevyengine#4299. The code is heavily borrowed from that PR. # Objective The execution order ambiguity checker often emits false positives, since bevy is not aware of invariants upheld by the user. ## Solution Title --- ## Changelog + Added methods `SystemDescriptor::ignore_all_ambiguities` and `::ambiguous_with`. These allow you to silence warnings for specific system-order ambiguities. ## Migration Guide ***Note for maintainers**: This should replace the migration guide for bevyengine#5916* Ambiguity sets have been replaced with a simpler API. ```rust // These systems technically conflict, but we don't care which order they run in. fn jump_on_click(mouse: Res<Input<MouseButton>>, mut transforms: Query<&mut Transform>) { ... } fn jump_on_spacebar(keys: Res<Input<KeyCode>>, mut transforms: Query<&mut Transform>) { ... } // // Before #[derive(AmbiguitySetLabel)] struct JumpSystems; app .add_system(jump_on_click.in_ambiguity_set(JumpSystems)) .add_system(jump_on_spacebar.in_ambiguity_set(JumpSystems)); // // After app .add_system(jump_on_click.ambiguous_with(jump_on_spacebar)) .add_system(jump_on_spacebar); ```
…#6158) # Background Incremental implementation of bevyengine#4299. The code is heavily borrowed from that PR. # Objective The execution order ambiguity checker often emits false positives, since bevy is not aware of invariants upheld by the user. ## Solution Title --- ## Changelog + Added methods `SystemDescriptor::ignore_all_ambiguities` and `::ambiguous_with`. These allow you to silence warnings for specific system-order ambiguities. ## Migration Guide ***Note for maintainers**: This should replace the migration guide for bevyengine#5916* Ambiguity sets have been replaced with a simpler API. ```rust // These systems technically conflict, but we don't care which order they run in. fn jump_on_click(mouse: Res<Input<MouseButton>>, mut transforms: Query<&mut Transform>) { ... } fn jump_on_spacebar(keys: Res<Input<KeyCode>>, mut transforms: Query<&mut Transform>) { ... } // // Before #[derive(AmbiguitySetLabel)] struct JumpSystems; app .add_system(jump_on_click.in_ambiguity_set(JumpSystems)) .add_system(jump_on_spacebar.in_ambiguity_set(JumpSystems)); // // After app .add_system(jump_on_click.ambiguous_with(jump_on_spacebar)) .add_system(jump_on_spacebar); ```
…tils` (bevyengine#5174) # Summary This method strips a long type name like `bevy::render::camera::PerspectiveCameraBundle` down into the bare type name (`PerspectiveCameraBundle`). This is generally useful utility method, needed by bevyengine#4299 and bevyengine#5121. As a result: - This method was moved to `bevy_utils` for easier reuse. - The legibility and robustness of this method has been significantly improved. - Harder test cases have been added. This change was split out of bevyengine#4299 to unblock it and make merging / reviewing the rest of those changes easier. ## Changelog - added `bevy_utils::get_short_name`, which strips the path from a type name for convenient display. - removed the `TypeRegistry::get_short_name` method. Use the function in `bevy_utils` instead.
# 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 bevyengine#4299, we're removing them. ## Migration Guide Ambiguity sets have been removed.
# Objective This code is very disjoint, and the `stage.rs` file that it's in is already very long. All I've done is move the code and clean up the compiler errors that result. Followup to bevyengine#5916, split out from bevyengine#4299.
# Objective - Add unit tests for ambiguity detection reporting. - Incremental implementation of bevyengine#4299. ## Solution - Refactor ambiguity detection internals to make it testable. As a bonus, this should make it easier to extend in the future. ## Notes * This code was copy-pasted from bevyengine#4299 and modified. Credit goes to @alice-i-cecile and @afonsolage, though I'm not sure who wrote what at this point.
…#6158) # Background Incremental implementation of bevyengine#4299. The code is heavily borrowed from that PR. # Objective The execution order ambiguity checker often emits false positives, since bevy is not aware of invariants upheld by the user. ## Solution Title --- ## Changelog + Added methods `SystemDescriptor::ignore_all_ambiguities` and `::ambiguous_with`. These allow you to silence warnings for specific system-order ambiguities. ## Migration Guide ***Note for maintainers**: This should replace the migration guide for bevyengine#5916* Ambiguity sets have been replaced with a simpler API. ```rust // These systems technically conflict, but we don't care which order they run in. fn jump_on_click(mouse: Res<Input<MouseButton>>, mut transforms: Query<&mut Transform>) { ... } fn jump_on_spacebar(keys: Res<Input<KeyCode>>, mut transforms: Query<&mut Transform>) { ... } // // Before #[derive(AmbiguitySetLabel)] struct JumpSystems; app .add_system(jump_on_click.in_ambiguity_set(JumpSystems)) .add_system(jump_on_spacebar.in_ambiguity_set(JumpSystems)); // // After app .add_system(jump_on_click.ambiguous_with(jump_on_spacebar)) .add_system(jump_on_spacebar); ```
# Objective - This test was mysteriously commented out ## Solution - Re-enable it - Also done in bevyengine#4299, but this is better as its own PR.
Context
This PR was largely completed by @alfonsolage in #2766. I've simply rebased it and put a few finishing touches on it to get it over the finish line.
Massive thanks and full credit for all his hard work.
Objective
Solution
WarnInternal
reporting level, and included an example to thetools
folder that reports all of the Bevy-internal ambiguities. Should be helpful for developers until we quash the last few.Forbid
reporting level, for developers who prefer to force themselves to fix ambiguities ASAP.Deny
reporting level, which reports literally every ambiguity and panics, for applications that need true determinism.tracing
'swarn
anderror
macros, rather thanprintln
.Changelog
Execution order ambiguity reporting has been significantly improved and a minimal report informing you of the number of ambiguous system pairs present in your schedule is now on by default.
It is now much easier to disable false positive ordering ambiguities, bevy-internal ambiguities are silenced by default and the output is much easier to read and act on.
Sample output:
Migration Guide
The
ReportExecutionOrderAmbiguities
resource is nowExecutionOrderAmbiguities
: you can adjust the level of the enum to match your preferred strictness level.The concept of "ambiguity sets" has been simplified away: simply use
.label(SharedLabel).ambiguous_with(SharedLabel)
with a standardSystemLabel
instead.Status
Rebasing this is proving to be a disaster; I'm going to remake this, ideally in a series of small PRs.
Future work
If you think any of these are dealbreakers, do let me know. For now though, this PR is already way too large.
ReportInternal
enum variant (Tracking issue: eliminate or explicitly silence all Bevy-internal execution order ambiguities #4377)