bevy/crates/bevy_render/src
Alice Cecile 6caa1782d6 Define system param validation on a per-system parameter basis (#18504)
# Objective

When introduced, `Single` was intended to simply be silently skipped,
allowing for graceful and efficient handling of systems during invalid
game states (such as when the player is dead).

However, this also caused missing resources to *also* be silently
skipped, leading to confusing and very hard to debug failures. In
0.15.1, this behavior was reverted to a panic, making missing resources
easier to debug, but largely making `Single` (and `Populated`)
worthless, as they would panic during expected game states.

Ultimately, the consensus is that this behavior should differ on a
per-system-param basis. However, there was no sensible way to *do* that
before this PR.

## Solution

Swap `SystemParam::validate_param` from a `bool` to:

```rust
/// The outcome of system / system param validation,
/// used by system executors to determine what to do with a system.
pub enum ValidationOutcome {
    /// All system parameters were validated successfully and the system can be run.
    Valid,
    /// At least one system parameter failed validation, and an error must be handled.
    /// By default, this will result in1 a panic. See [crate::error] for more information.
    ///
    /// This is the default behavior, and is suitable for system params that should *always* be valid,
    /// either because sensible fallback behavior exists (like [`Query`] or because
    /// failures in validation should be considered a bug in the user's logic that must be immediately addressed (like [`Res`]).
    Invalid,
    /// At least one system parameter failed validation, but the system should be skipped due to [`ValidationBehavior::Skip`].
    /// This is suitable for system params that are intended to only operate in certain application states, such as [`Single`].
    Skipped,
}
```
Then, inside of each `SystemParam` implementation, return either Valid,
Invalid or Skipped.

Currently, only `Single`, `Option<Single>` and `Populated` use the
`Skipped` behavior. Other params (like resources) retain their current
failing

## Testing

Messed around with the fallible_params example. Added a pair of tests:
one for panicking when resources are missing, and another for properly
skipping `Single` and `Populated` system params.

## To do

- [x] get https://github.com/bevyengine/bevy/pull/18454 merged
- [x] fix the todo!() in the macro-powered tuple implementation (please
help 🥺)
- [x] test
- [x] write a migration guide
- [x] update the example comments

## Migration Guide

Various system and system parameter validation methods
(`SystemParam::validate_param`, `System::validate_param` and
`System::validate_param_unsafe`) now return and accept a
`ValidationOutcome` enum, rather than a `bool`. The previous `true`
values map to `ValidationOutcome::Valid`, while `false` maps to
`ValidationOutcome::Invalid`.

However, if you wrote a custom schedule executor, you should now respect
the new `ValidationOutcome::Skipped` parameter, skipping any systems
whose validation was skipped. By contrast, `ValidationOutcome::Invalid`
systems should also be skipped, but you should call the
`default_error_handler` on them first, which by default will result in a
panic.

If you are implementing a custom `SystemParam`, you should consider
whether failing system param validation is an error or an expected
state, and choose between `Invalid` and `Skipped` accordingly. In Bevy
itself, `Single` and `Populated` now once again skip the system when
their conditions are not met. This is the 0.15.0 behavior, but stands in
contrast to the 0.15.1 behavior, where they would panic.

---------

Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
Co-authored-by: Dmytro Banin <banind@cs.washington.edu>
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
2025-03-25 22:59:04 +01:00
..
batching Generic system config (#17962) 2025-03-12 00:12:30 +00:00
camera bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
diagnostic Move hashbrown and foldhash out of bevy_utils (#17460) 2025-01-23 16:46:08 +00:00
experimental bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
mesh bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
primitives bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
render_graph Implement experimental GPU two-phase occlusion culling for the standard 3D mesh pipeline. (#17413) 2025-01-27 05:02:46 +00:00
render_phase Cache opaque deferred entities so we don't have to continuously re-queue them. (#18007) 2025-02-24 21:44:24 +00:00
render_resource Fixes for WESL on Windows (#18373) 2025-03-17 22:29:29 +00:00
renderer Force serial command encoding on Linux/amdvlk (#18368) 2025-03-18 03:16:38 +00:00
texture Allowed creating uninitialized images (for use as storage textures) (#17760) 2025-02-10 22:22:07 +00:00
view bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
alpha.rs bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
bindless.wgsl Use global binding arrays for bindless resources. (#17898) 2025-02-21 05:55:36 +00:00
color_operations.wgsl
extract_component.rs Replace internal uses of insert_or_spawn_batch (#18035) 2025-03-06 16:16:36 +00:00
extract_instances.rs
extract_param.rs Define system param validation on a per-system parameter basis (#18504) 2025-03-25 22:59:04 +01:00
extract_resource.rs
globals.rs bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
globals.wgsl
gpu_component_array_buffer.rs Generic system config (#17962) 2025-03-12 00:12:30 +00:00
gpu_readback.rs Generic system config (#17962) 2025-03-12 00:12:30 +00:00
lib.rs Parallelize prepare_assets::<T> systems (#17914) 2025-03-10 05:01:12 +00:00
maths.wgsl Atmosphere LUT parameterization improvements (#17555) 2025-02-03 21:52:11 +00:00
pipelined_rendering.rs Upgrade to Rust Edition 2024 (#17967) 2025-02-24 03:54:47 +00:00
render_asset.rs Generic system config (#17962) 2025-03-12 00:12:30 +00:00
settings.rs Upgrade to wgpu v24 (#17542) 2025-02-09 19:40:53 +00:00
storage.rs bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00
sync_component.rs
sync_world.rs bevy_reflect: Add clone registrations project-wide (#18307) 2025-03-17 18:32:35 +00:00