Skip to content

Commit

Permalink
Allow Bevy to start from non-main threads on supported platforms (bev…
Browse files Browse the repository at this point in the history
…yengine#10020)

# Objective

Allow Bevy apps to run without requiring to start from the main thread.
This allows other projects and applications to do things like spawning a
normal or scoped
thread and run Bevy applications there.

The current behaviour if you try this is a panic.

## Solution

Allow this by default on platforms winit supports this behaviour on
(x11, Wayland, Windows).

---

## Changelog

### Added

- Added the ability to start Bevy apps outside of the main thread on
x11, Wayland, Windows

---------

Signed-off-by: Torstein Grindvik <torstein.grindvik@nordicsemi.no>
Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: James Liu <contact@jamessliu.com>
  • Loading branch information
3 people authored and ameknite committed Nov 6, 2023
1 parent 6c5d6e7 commit d643bff
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_internal/src/default_plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl PluginGroup for DefaultPlugins {

#[cfg(feature = "bevy_winit")]
{
group = group.add(bevy_winit::WinitPlugin);
group = group.add(bevy_winit::WinitPlugin::default());
}

#[cfg(feature = "bevy_render")]
Expand Down
42 changes: 41 additions & 1 deletion crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,51 @@ pub static ANDROID_APP: std::sync::OnceLock<AndroidApp> = std::sync::OnceLock::n
/// replace the existing [`App`] runner with one that constructs an [event loop](EventLoop) to
/// receive window and input events from the OS.
#[derive(Default)]
pub struct WinitPlugin;
pub struct WinitPlugin {
/// Allows the window (and the event loop) to be created on any thread
/// instead of only the main thread.
///
/// See [`EventLoopBuilder::build`] for more information on this.
///
/// # Supported platforms
///
/// Only works on Linux (X11/Wayland) and Windows.
/// This field is ignored on other platforms.
pub run_on_any_thread: bool,
}

impl Plugin for WinitPlugin {
fn build(&self, app: &mut App) {
let mut event_loop_builder = EventLoopBuilder::<()>::with_user_event();

// This is needed because the features checked in the inner
// block might be enabled on other platforms than linux.
#[cfg(target_os = "linux")]
{
#[cfg(feature = "x11")]
{
use winit::platform::x11::EventLoopBuilderExtX11;

// This allows a Bevy app to be started and ran outside of the main thread.
// A use case for this is to allow external applications to spawn a thread
// which runs a Bevy app without requiring the Bevy app to need to reside on
// the main thread, which can be problematic.
event_loop_builder.with_any_thread(self.run_on_any_thread);
}

#[cfg(feature = "wayland")]
{
use winit::platform::wayland::EventLoopBuilderExtWayland;
event_loop_builder.with_any_thread(self.run_on_any_thread);
}
}

#[cfg(target_os = "windows")]
{
use winit::platform::windows::EventLoopBuilderExtWindows;
event_loop_builder.with_any_thread(self.run_on_any_thread);
}

#[cfg(target_os = "android")]
{
use winit::platform::android::EventLoopBuilderExtAndroid;
Expand Down

0 comments on commit d643bff

Please sign in to comment.