bevy/crates
Daniel McNab 7b2cf98896 Make RenderStage::Extract run on the render world (#4402)
# Objective

- Currently, the `Extract` `RenderStage` is executed on the main world, with the render world available as a resource.
- However, when needing access to resources in the render world (e.g. to mutate them), the only way to do so was to get exclusive access to the whole `RenderWorld` resource.
- This meant that effectively only one extract which wrote to resources could run at a time.
- We didn't previously make `Extract`ing writing to the world a non-happy path, even though we want to discourage that.

## Solution

- Move the extract stage to run on the render world.
- Add the main world as a `MainWorld` resource.
- Add an `Extract` `SystemParam` as a convenience to access a (read only) `SystemParam` in the main world during `Extract`.

## Future work

It should be possible to avoid needing to use `get_or_spawn` for the render commands, since now the `Commands`' `Entities` matches up with the world being executed on.
We need to determine how this interacts with https://github.com/bevyengine/bevy/pull/3519
It's theoretically possible to remove the need for the `value` method on `Extract`. However, that requires slightly changing the `SystemParam` interface, which would make it more complicated. That would probably mess up the `SystemState` api too.

## Todo
I still need to add doc comments to `Extract`.

---

## Changelog

### Changed
- The `Extract` `RenderStage` now runs on the render world (instead of the main world as before).
   You must use the `Extract` `SystemParam` to access the main world during the extract phase.
   Resources on the render world can now be accessed using `ResMut` during extract.

### Removed
- `Commands::spawn_and_forget`. Use `Commands::get_or_spawn(e).insert_bundle(bundle)` instead

## Migration Guide

The `Extract` `RenderStage` now runs on the render world (instead of the main world as before).
You must use the `Extract` `SystemParam` to access the main world during the extract phase. `Extract` takes a single type parameter, which is any system parameter (such as `Res`, `Query` etc.). It will extract this from the main world, and returns the result of this extraction when `value` is called on it.

For example, if previously your extract system looked like:
```rust
fn extract_clouds(mut commands: Commands, clouds: Query<Entity, With<Cloud>>) {
    for cloud in clouds.iter() {
        commands.get_or_spawn(cloud).insert(Cloud);
    }
}
```
the new version would be:
```rust
fn extract_clouds(mut commands: Commands, mut clouds: Extract<Query<Entity, With<Cloud>>>) {
    for cloud in clouds.value().iter() {
        commands.get_or_spawn(cloud).insert(Cloud);
    }
}
```
The diff is:
```diff
--- a/src/clouds.rs
+++ b/src/clouds.rs
@@ -1,5 +1,5 @@
-fn extract_clouds(mut commands: Commands, clouds: Query<Entity, With<Cloud>>) {
-    for cloud in clouds.iter() {
+fn extract_clouds(mut commands: Commands, mut clouds: Extract<Query<Entity, With<Cloud>>>) {
+    for cloud in clouds.value().iter() {
         commands.get_or_spawn(cloud).insert(Cloud);
     }
 }
```
You can now also access resources from the render world using the normal system parameters during `Extract`:
```rust
fn extract_assets(mut render_assets: ResMut<MyAssets>, source_assets: Extract<Res<MyAssets>>) {
     *render_assets = source_assets.clone();
}
```
Please note that all existing extract systems need to be updated to match this new style; even if they currently compile they will not run as expected. A warning will be emitted on a best-effort basis if this is not met.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-08 23:56:33 +00:00
..
bevy_animation Add helper methods for rotating Transforms (#5151) 2022-07-01 03:58:54 +00:00
bevy_app Remove the dependency cycles (#5171) 2022-07-04 13:04:18 +00:00
bevy_asset Derive default for enums where possible (#5158) 2022-07-01 03:42:15 +00:00
bevy_audio Remove the dependency cycles (#5171) 2022-07-04 13:04:18 +00:00
bevy_core Add global init and get accessors for all newtyped TaskPools (#2250) 2022-06-09 02:43:24 +00:00
bevy_core_pipeline Make RenderStage::Extract run on the render world (#4402) 2022-07-08 23:56:33 +00:00
bevy_derive android - fix issues other than the rendering (#5130) 2022-06-30 19:42:45 +00:00
bevy_diagnostic Cleanups in diagnostics (#3871) 2022-06-20 17:02:25 +00:00
bevy_dylib Bump Bevy to 0.8.0-dev (#4505) 2022-04-17 23:04:52 +00:00
bevy_dynamic_plugin Bump Bevy to 0.8.0-dev (#4505) 2022-04-17 23:04:52 +00:00
bevy_ecs Make RenderStage::Extract run on the render world (#4402) 2022-07-08 23:56:33 +00:00
bevy_ecs_compile_fail_tests Fix rust 1.62 changes (#5154) 2022-06-30 19:24:28 +00:00
bevy_encase_derive Updated glam to 0.21. (#5142) 2022-07-03 19:55:33 +00:00
bevy_gilrs Update gilrs to v0.9 (#4848) 2022-05-30 17:26:23 +00:00
bevy_gltf Allow rendering meshes without UV coordinate data. (#5222) 2022-07-08 20:55:08 +00:00
bevy_hierarchy add more SAFETY comments and lint for missing ones in bevy_ecs (#4835) 2022-07-04 14:44:24 +00:00
bevy_input Updated glam to 0.21. (#5142) 2022-07-03 19:55:33 +00:00
bevy_internal enable optional dependencies to stay optional (#5023) 2022-06-20 10:32:43 +00:00
bevy_log Remove the dependency cycles (#5171) 2022-07-04 13:04:18 +00:00
bevy_macro_utils bevy_reflect_derive: Tidying up the code (#4712) 2022-05-12 19:43:23 +00:00
bevy_math Updated glam to 0.21. (#5142) 2022-07-03 19:55:33 +00:00
bevy_mikktspace Updated glam to 0.21. (#5142) 2022-07-03 19:55:33 +00:00
bevy_pbr Make RenderStage::Extract run on the render world (#4402) 2022-07-08 23:56:33 +00:00
bevy_ptr add more SAFETY comments and lint for missing ones in bevy_ecs (#4835) 2022-07-04 14:44:24 +00:00
bevy_reflect Make reflect_partial_eq return more accurate results (#5210) 2022-07-05 17:41:54 +00:00
bevy_render Make RenderStage::Extract run on the render world (#4402) 2022-07-08 23:56:33 +00:00
bevy_scene remove component and resource suffixes from reflect structs (#5219) 2022-07-06 02:59:51 +00:00
bevy_sprite Make RenderStage::Extract run on the render world (#4402) 2022-07-08 23:56:33 +00:00
bevy_tasks Miri can set thread names now (#5108) 2022-06-26 21:28:00 +00:00
bevy_text Make RenderStage::Extract run on the render world (#4402) 2022-07-08 23:56:33 +00:00
bevy_time add more SAFETY comments and lint for missing ones in bevy_ecs (#4835) 2022-07-04 14:44:24 +00:00
bevy_transform Updated glam to 0.21. (#5142) 2022-07-03 19:55:33 +00:00
bevy_ui Make RenderStage::Extract run on the render world (#4402) 2022-07-08 23:56:33 +00:00
bevy_utils add more SAFETY comments and lint for missing ones in bevy_ecs (#4835) 2022-07-04 14:44:24 +00:00
bevy_window Move the configuration of the WindowPlugin to a resource (#5227) 2022-07-08 01:14:23 +00:00
bevy_winit Add option to center a window (#4999) 2022-07-04 13:04:14 +00:00