bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
36.24k stars 3.58k forks source link

bevy_app::App cannot be sent between threads #14175

Closed PPakalns closed 4 months ago

PPakalns commented 4 months ago

Bevy version

bevy 0.14

What you did

bevy 0.14 doesn't allow bevy_app::App to be sent between threads anymore.

What went wrong

Looks like RunnerFn:

type RunnerFn = Box<dyn FnOnce(App) -> AppExit>;

introduces this limitation.

Compiler error:

error[E0277]: `(dyn FnOnce(App) -> AppExit + 'static)` cannot be sent between threads safely
   --> base-init/src/lib.rs:133:28
    |
133 |                     .spawn(move || manual_game_loop(game_app_handle))
    |                      ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn FnOnce(App) -> AppExit + 'static)` cannot be sent between threads safely
    |                      |
    |                      required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `(dyn FnOnce(App) -> AppExit + 'static)`, which is required by `{closure@base-init/src/lib.rs:133:28: 133:35}: Send`
    = note: required for `std::ptr::Unique<(dyn FnOnce(App) -> AppExit + 'static)>` to implement `Send`
note: required because it appears within the type `Box<(dyn FnOnce(App) -> AppExit + 'static)>`
   --> .rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:238:12
    |
238 | pub struct Box<
    |            ^^^
note: required because it appears within the type `App`
   --> .cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_app-0.14.0/src/app.rs:70:12
    |
70  | pub struct App {
    |            ^^^
    = note: required for `Mutex<App>` to implement `Sync`
    = note: 1 redundant requirement hidden
    = note: required for `Arc<Mutex<App>>` to implement `Send`

Additional information

bevy_app::App / Plugins are a very great abstractions that can be used in wide variety of situations and this limits possible use.

SkiFire13 commented 4 months ago

This was an intentional change. It's also documented in the migration guide. https://bevyengine.org/learn/migration-guides/0-13-to-0-14/#app-changes

App is not Send anymore, but SubApp still is.

See also the PR that made the change https://github.com/bevyengine/bevy/pull/9202

Moving !Send resource ownership to App will make it unambiguously !Send

and the fundamental issue that lead to this change https://github.com/bevyengine/bevy/discussions/6552