Skip to content

Immediately apply deferred system params in System::run #11823

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

Merged
merged 14 commits into from
Feb 24, 2024

Conversation

james7132
Copy link
Member

@james7132 james7132 commented Feb 11, 2024

Objective

Fixes #11821.

Solution

  • Run System::apply_deferred in System::run after executing the system.
  • Switch to using System::run_unsafe in SingleThreadedExecutor to preserve the current behavior.
  • Remove the System::apply_deferred in SimpleExecutor as it's now redundant.
  • Remove the System::apply_deferred when running one-shot systems, as it's now redundant.

Changelog

Changed: System::run will now immediately apply deferred system params after running the system.

Migration Guide

System::run will now always run System::apply_deferred immediately after running the system now. If you were running systems and then applying their deferred buffers at a later point in time, you can eliminate the latter.

// in 0.13
system.run(world);
// .. sometime later ...
system.apply_deferred(world);

// in 0.14
system.run(world);

@james7132 james7132 added A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide labels Feb 11, 2024
@alice-i-cecile alice-i-cecile added this to the 0.14 milestone Feb 12, 2024
@joseph-gio joseph-gio requested a review from hymm February 20, 2024 07:40
@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Feb 20, 2024
@alice-i-cecile
Copy link
Member

Much simpler. Feel free to merge once you get CI passing.

@james7132 james7132 enabled auto-merge February 20, 2024 17:13
@hymm
Copy link
Contributor

hymm commented Feb 20, 2024

Is this going to mess up pipelined rendering extract schedule if you run all the schedules single threaded? i.e. that schedule needs to skip applying it's buffers until it's moved to the render thread.

@james7132
Copy link
Member Author

That would likely be a performance regression. That said I'm not sure why one would be running pipelined rendering with a single threaded executor. It seems counter intuitive.

@hymm
Copy link
Contributor

hymm commented Feb 21, 2024

For lower core systems like quest or switch that only have 3 cores available. The perf you get from pipelining will be worth it. But the overhead from running your schedule multi threaded won't be

@james7132 james7132 disabled auto-merge February 21, 2024 20:26
@james7132
Copy link
Member Author

@JoJoJet I think that's good enough justification to not deprecate the SimpleExecutor and retain the behavior in the single threaded executor. Thoughts?

@james7132 james7132 enabled auto-merge February 22, 2024 06:55
@alice-i-cecile alice-i-cecile added the M-Needs-Release-Note Work that should be called out in the blog due to impact label Feb 22, 2024
@james7132 james7132 added this pull request to the merge queue Feb 24, 2024
Merged via the queue into bevyengine:main with commit 42e6155 Feb 24, 2024
msvbg pushed a commit to msvbg/bevy that referenced this pull request Feb 26, 2024
…1823)

# Objective
Fixes bevyengine#11821. 

## Solution
* Run `System::apply_deferred` in `System::run` after executing the
system.
* Switch to using `System::run_unsafe` in `SingleThreadedExecutor` to
preserve the current behavior.
* Remove the `System::apply_deferred` in `SimpleExecutor` as it's now
redundant.
* Remove the `System::apply_deferred` when running one-shot systems, as
it's now redundant.

---

## Changelog
Changed: `System::run` will now immediately apply deferred system params
after running the system.

## Migration Guide
`System::run` will now always run `System::apply_deferred` immediately
after running the system now. If you were running systems and then
applying their deferred buffers at a later point in time, you can
eliminate the latter.

```rust
// in 0.13
system.run(world);
// .. sometime later ...
system.apply_deferred(world);

// in 0.14
system.run(world);
```

---------

Co-authored-by: Alice Cecile <[email protected]>
msvbg pushed a commit to msvbg/bevy that referenced this pull request Feb 26, 2024
…1823)

# Objective
Fixes bevyengine#11821. 

## Solution
* Run `System::apply_deferred` in `System::run` after executing the
system.
* Switch to using `System::run_unsafe` in `SingleThreadedExecutor` to
preserve the current behavior.
* Remove the `System::apply_deferred` in `SimpleExecutor` as it's now
redundant.
* Remove the `System::apply_deferred` when running one-shot systems, as
it's now redundant.

---

## Changelog
Changed: `System::run` will now immediately apply deferred system params
after running the system.

## Migration Guide
`System::run` will now always run `System::apply_deferred` immediately
after running the system now. If you were running systems and then
applying their deferred buffers at a later point in time, you can
eliminate the latter.

```rust
// in 0.13
system.run(world);
// .. sometime later ...
system.apply_deferred(world);

// in 0.14
system.run(world);
```

---------

Co-authored-by: Alice Cecile <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Mar 26, 2025
# Objective

Fix panic in `run_system` when running an exclusive system wrapped in a
`PipeSystem` or `AdapterSystem`.

#18076 introduced a `System::run_without_applying_deferred` method. It
normally calls `System::run_unsafe`, but
`ExclusiveFunctionSystem::run_unsafe` panics, so it was overridden for
that type. Unfortunately, `PipeSystem::run_without_applying_deferred`
still calls `PipeSystem::run_unsafe`, which can then call
`ExclusiveFunctionSystem::run_unsafe` and panic.

## Solution

Make `ExclusiveFunctionSystem::run_unsafe` work instead of panicking.
Clarify the safety requirements that make this sound.

The alternative is to override `run_without_applying_deferred` in
`PipeSystem`, `CombinatorSystem`, `AdapterSystem`,
`InfallibleSystemWrapper`, and `InfallibleObserverWrapper`. That seems
like a lot of extra code just to preserve a confusing special case!

Remove some implementations of `System::run` that are no longer
necessary with this change. This slightly changes the behavior of
`PipeSystem` and `CombinatorSystem`: Currently `run` will call
`apply_deferred` on the first system before running the second, but
after this change it will only call it after *both* systems have run.
The new behavior is consistent with `run_unsafe` and
`run_without_applying_deferred`, and restores the behavior prior to
#11823.

The panic was originally necessary because [`run_unsafe` took
`&World`](https://github.com/bevyengine/bevy/pull/6083/files#diff-708dfc60ec5eef432b20a6f471357a7ea9bfb254dc2f918d5ed4a66deb0e85baR90).
Now that it takes `UnsafeWorldCell`, it is possible to make it work. See
also Cart's concerns at
#4166 (comment),
although those also predate `UnsafeWorldCell`.

And see #6698 for a previous bug caused by this panic.
mockersf pushed a commit that referenced this pull request Mar 26, 2025
# Objective

Fix panic in `run_system` when running an exclusive system wrapped in a
`PipeSystem` or `AdapterSystem`.

#18076 introduced a `System::run_without_applying_deferred` method. It
normally calls `System::run_unsafe`, but
`ExclusiveFunctionSystem::run_unsafe` panics, so it was overridden for
that type. Unfortunately, `PipeSystem::run_without_applying_deferred`
still calls `PipeSystem::run_unsafe`, which can then call
`ExclusiveFunctionSystem::run_unsafe` and panic.

## Solution

Make `ExclusiveFunctionSystem::run_unsafe` work instead of panicking.
Clarify the safety requirements that make this sound.

The alternative is to override `run_without_applying_deferred` in
`PipeSystem`, `CombinatorSystem`, `AdapterSystem`,
`InfallibleSystemWrapper`, and `InfallibleObserverWrapper`. That seems
like a lot of extra code just to preserve a confusing special case!

Remove some implementations of `System::run` that are no longer
necessary with this change. This slightly changes the behavior of
`PipeSystem` and `CombinatorSystem`: Currently `run` will call
`apply_deferred` on the first system before running the second, but
after this change it will only call it after *both* systems have run.
The new behavior is consistent with `run_unsafe` and
`run_without_applying_deferred`, and restores the behavior prior to
#11823.

The panic was originally necessary because [`run_unsafe` took
`&World`](https://github.com/bevyengine/bevy/pull/6083/files#diff-708dfc60ec5eef432b20a6f471357a7ea9bfb254dc2f918d5ed4a66deb0e85baR90).
Now that it takes `UnsafeWorldCell`, it is possible to make it work. See
also Cart's concerns at
#4166 (comment),
although those also predate `UnsafeWorldCell`.

And see #6698 for a previous bug caused by this panic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide M-Needs-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

System::run should call System::apply_deferred
4 participants