-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Better warnings about invalid parameters #15500
Better warnings about invalid parameters #15500
Conversation
cd2fe8d
to
0bd22bb
Compare
I've noticed some problems with this approach, I'll be reworking it |
d217110
to
8e2c754
Compare
…15526) # Objective Fixes #15394 ## Solution Observers now validate params. System registry has a new error variant for when system running fails due to invalid parameters. Run once now returns a `Result<Out, RunOnceError>` instead of `Out`. This is more inline with system registry, which also returns a result. I'll address warning messages in #15500. ## Testing Added one test for each case. --- ## Migration Guide - `RunSystemOnce::run_system_once` and `RunSystemOnce::run_system_once_with` now return a `Result<Out>` instead of just `Out` --------- Co-authored-by: Alice Cecile <[email protected]> Co-authored-by: Zachary Harrold <[email protected]>
c12cb04
to
5f1cdb5
Compare
5bdad58
to
6e8e8c5
Compare
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 approach looks good.
Added a new bevy_ecs default feature flag bevy_warn_invalid_param which enables the warnings.
Disabling it can slightly improve performance due to reduced checks when running each system.
Have you benchmarked this? Two not taken (predictable) if
s per system invocation probably aren't measurable and not worth adding a system flag.
I'm not convinced we need WarnPolicy::Always
, but I don't have much of an opinion on it.
I do however think it makes sense to rename WarnPolicy
to ParamWarnPolicy
, as it is about param validation and doesn't affect bevy::log::warn
.
Not benchmarked, I'll see if next reviewer agrees or if we'll need benchmarks. |
Trying to construct a worst-case benchmark, where the systems do no work and there are no parameters to validate or extract: let mut world = World::new();
let mut schedule = Schedule::default();
for _ in 0..1000 {
schedule.add_systems(|| ());
}
for _ in 0..1000000 {
schedule.run(&mut world);
}
So there's about a standard deviation difference. But if these numbers were precise, the feature flag would allow removing 0.178ns per system. I don't think that's worth it. |
Thank you for your work, I'll remove the flag when im home :) |
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.
So the warning is now emitted from the param itself, which lets you include the param type in the message. And the warning state is stored on the system, which saves space and is easier to configure. As a consequence, if a system has multiple failing parameters, it only warns on the first one, right? That all seems reasonable, although the final result is a little surprising.
The policy update of a (function) system happens after param validation fails. While we can remove the short circuit, this won't patch a hole where missing parameters can change over time and we'll still only get warning about the first one (time-wise). I guess we could store the warning per system param?? |
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 to me, love the idea of giving more meaningful feedback to the user without spamming them needlessly. I have a note about a possible future PR, but definitely doesn't need to be in this PR.
/// No warning should ever be emitted. | ||
Never, | ||
/// The warning will be emitted once and status will update to [`Self::Never`]. | ||
Once, |
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.
Future PR: Seems reasonable to add an Always
policy as well:
/// State machine for emitting warnings when [system params are invalid](System::validate_param).
#[derive(Clone, Copy)]
pub enum ParamWarnPolicy {
/// No warning should ever be emitted.
Never,
/// The warning will be emitted once and status will update to [`Self::Never`].
Once,
/// The warning will be emitted each time the system is run.
Always,
}
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.
I had it but removed it as per previous feedback.
I think Always
will be a bit too annoying, but we could certainly use more complex policies:
- system just stopped running (prev frame valid, this frame invalid)
- invalid params changed
If we get some higher level logging with editor, we can do stuff like:
- system X stopped running at frame N because of invalid param P and is still not running till frame M
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.
Hm, I don't think we have a good way to test whether the right things get logged?
btw the PR description still mentions bevy_param_warn
Anyway, the implementation is looking good to me!
Co-authored-by: SpecificProtagonist <[email protected]>
Objective
System param validation warnings should be configurable and default to "warn once" (per system).
Fixes: #15391
Solution
SystemMeta
is given a newParamWarnPolicy
field.The policy decides whether warnings will be emitted by each system param when it fails validation.
The policy is updated by the system after param validation fails.
Example warning:
Currently, only the first invalid parameter is displayed.
Warnings can be disabled on function systems using
.param_never_warn()
.(there is also
.with_param_warn_policy(policy)
)Testing
Ran
fallible_params
example.