Skip to content
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

WebGPU support #5027

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ debug_asset_server = ["bevy_internal/debug_asset_server"]
# Enable animation support, and glTF animation loading
animation = ["bevy_internal/animation"]

spirv = ["bevy_internal/spirv"]

webgpu = ["bevy_internal/webgpu"]

[dependencies]
bevy_dylib = { path = "crates/bevy_dylib", version = "0.8.0-dev", default-features = false, optional = true }
bevy_internal = { path = "crates/bevy_internal", version = "0.8.0-dev", default-features = false }
Expand All @@ -121,6 +125,8 @@ bytemuck = "1.7"
# Needed to poll Task examples
futures-lite = "1.11.3"
crossbeam-channel = "0.5.0"
wasm-bindgen-futures = "0.4"
async-trait = "0.1"

[[example]]
name = "hello_world"
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_animation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.8.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.8.0-dev" }
bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.8.0-dev" }

# other
async-trait = "0.1"
4 changes: 3 additions & 1 deletion crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use std::ops::Deref;

use async_trait::async_trait;
use bevy_app::{App, CoreStage, Plugin};
use bevy_asset::{AddAsset, Assets, Handle};
use bevy_core::Name;
Expand Down Expand Up @@ -289,8 +290,9 @@ pub fn animation_player(
#[derive(Default)]
pub struct AnimationPlugin {}

#[async_trait]
impl Plugin for AnimationPlugin {
fn build(&self, app: &mut App) {
async fn build(&self, app: &mut App) {
app.add_asset::<AnimationClip>()
.register_type::<AnimationPlayer>()
.add_system_to_stage(
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ bevy_tasks = { path = "../bevy_tasks", version = "0.8.0-dev" }
# other
serde = { version = "1.0", features = ["derive"], optional = true }
ron = { version = "0.7.0", optional = true }
async-trait = "0.1"


[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down
24 changes: 13 additions & 11 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub struct App {
/// the application's event loop and advancing the [`Schedule`].
/// Typically, it is not configured manually, but set by one of Bevy's built-in plugins.
/// See `bevy::winit::WinitPlugin` and [`ScheduleRunnerPlugin`](crate::schedule_runner::ScheduleRunnerPlugin).
pub runner: Box<dyn Fn(App)>,
pub runner: Box<dyn Fn(App) + Send>,
/// A container of [`Stage`]s set to be run in a linear order.
pub schedule: Schedule,
sub_apps: HashMap<Box<dyn AppLabel>, SubApp>,
Expand All @@ -62,7 +62,7 @@ pub struct App {
/// Each `SubApp` has its own [`Schedule`] and [`World`], enabling a separation of concerns.
struct SubApp {
app: App,
runner: Box<dyn Fn(&mut World, &mut App)>,
runner: Box<dyn Fn(&mut World, &mut App) + Send>,
}

impl Default for App {
Expand Down Expand Up @@ -744,7 +744,7 @@ impl App {
/// App::new()
/// .set_runner(my_runner);
/// ```
pub fn set_runner(&mut self, run_fn: impl Fn(App) + 'static) -> &mut Self {
pub fn set_runner(&mut self, run_fn: impl Fn(App) + Send + 'static) -> &mut Self {
self.runner = Box::new(run_fn);
self
}
Expand All @@ -763,12 +763,12 @@ impl App {
/// #
/// App::new().add_plugin(bevy_log::LogPlugin::default());
/// ```
pub fn add_plugin<T>(&mut self, plugin: T) -> &mut Self
pub async fn add_plugin<T>(&mut self, plugin: T) -> &mut Self
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think adding plugins should ever be async. IMO they should just register things, not do any actual work until the startup systems run.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this, but that ties into the broader discussion in #1255.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current add_plugin does all the work of building the plugin immediately.
We could (and probably should) switch to a register_plugin that would actually build the plugin just before running, then only the last step would need to be async. That would open a lot of solutions for plugin ordering and dependencies

where
T: Plugin,
{
debug!("added plugin: {}", plugin.name());
plugin.build(self);
plugin.build(self).await;
self
}

Expand All @@ -795,10 +795,10 @@ impl App {
/// App::new()
/// .add_plugins(MinimalPlugins);
/// ```
pub fn add_plugins<T: PluginGroup>(&mut self, mut group: T) -> &mut Self {
pub async fn add_plugins<T: PluginGroup>(&mut self, mut group: T) -> &mut Self {
let mut plugin_group_builder = PluginGroupBuilder::default();
group.build(&mut plugin_group_builder);
plugin_group_builder.finish(self);
plugin_group_builder.finish(self).await;
self
}

Expand All @@ -813,6 +813,7 @@ impl App {
///
/// ```
/// # use bevy_app::{prelude::*, PluginGroupBuilder};
/// # use async_trait::async_trait;
/// #
/// # // Dummies created to avoid using bevy_internal which pulls in too many dependencies.
/// # struct DefaultPlugins;
Expand All @@ -823,24 +824,25 @@ impl App {
/// # }
/// #
/// # struct MyOwnPlugin;
/// # #[async_trait]
/// # impl Plugin for MyOwnPlugin {
/// # fn build(&self, app: &mut App){;}
/// # async fn build(&self, app: &mut App){;}
/// # }
/// #
/// App::new()
/// .add_plugins_with(DefaultPlugins, |group| {
/// group.add_before::<bevy_log::LogPlugin, _>(MyOwnPlugin)
/// });
/// ```
pub fn add_plugins_with<T, F>(&mut self, mut group: T, func: F) -> &mut Self
pub async fn add_plugins_with<T, F>(&mut self, mut group: T, func: F) -> &mut Self
where
T: PluginGroup,
F: FnOnce(&mut PluginGroupBuilder) -> &mut PluginGroupBuilder,
{
let mut plugin_group_builder = PluginGroupBuilder::default();
group.build(&mut plugin_group_builder);
func(&mut plugin_group_builder);
plugin_group_builder.finish(self);
plugin_group_builder.finish(self).await;
self
}

Expand All @@ -863,7 +865,7 @@ impl App {
&mut self,
label: impl AppLabel,
app: App,
sub_app_runner: impl Fn(&mut World, &mut App) + 'static,
sub_app_runner: impl Fn(&mut World, &mut App) + Send + 'static,
) -> &mut Self {
self.sub_apps.insert(
Box::new(label),
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_app/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use crate::App;
use async_trait::async_trait;
use std::any::Any;

/// A collection of Bevy app logic and configuration.
///
/// Plugins configure an [`App`]. When an [`App`] registers a plugin,
/// the plugin's [`Plugin::build`] function is run.
#[async_trait]
pub trait Plugin: Any + Send + Sync {
/// Configures the [`App`] to which this plugin is added.
fn build(&self, app: &mut App);
async fn build(&self, app: &mut App);
/// Configures a name for the [`Plugin`] which is primarily used for debugging.
fn name(&self) -> &str {
std::any::type_name::<Self>()
Expand Down
15 changes: 10 additions & 5 deletions crates/bevy_app/src/plugin_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ impl PluginGroupBuilder {

/// Consumes the [`PluginGroupBuilder`] and [builds](Plugin::build) the contained [`Plugin`]s
/// in the order specified.
pub fn finish(self, app: &mut App) {
pub async fn finish(self, app: &mut App) {
for ty in &self.order {
if let Some(entry) = self.plugins.get(ty) {
if entry.enabled {
debug!("added plugin: {}", entry.plugin.name());
entry.plugin.build(app);
entry.plugin.build(app).await;
}
}
}
Expand All @@ -141,22 +141,27 @@ impl PluginGroupBuilder {

#[cfg(test)]
mod tests {
use async_trait::async_trait;

use super::PluginGroupBuilder;
use crate::{App, Plugin};

struct PluginA;
#[async_trait]
impl Plugin for PluginA {
fn build(&self, _: &mut App) {}
async fn build(&self, _: &mut App) {}
}

struct PluginB;
#[async_trait]
impl Plugin for PluginB {
fn build(&self, _: &mut App) {}
async fn build(&self, _: &mut App) {}
}

struct PluginC;
#[async_trait]
impl Plugin for PluginC {
fn build(&self, _: &mut App) {}
async fn build(&self, _: &mut App) {}
}

#[test]
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_app/src/schedule_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
use bevy_ecs::event::{Events, ManualEventReader};
use bevy_utils::{Duration, Instant};

use async_trait::async_trait;
#[cfg(target_arch = "wasm32")]
use std::{cell::RefCell, rc::Rc};
#[cfg(target_arch = "wasm32")]
Expand Down Expand Up @@ -63,8 +64,9 @@ impl ScheduleRunnerSettings {
#[derive(Default)]
pub struct ScheduleRunnerPlugin;

#[async_trait]
impl Plugin for ScheduleRunnerPlugin {
fn build(&self, app: &mut App) {
async fn build(&self, app: &mut App) {
let settings = app
.world
.get_resource_or_insert_with(ScheduleRunnerSettings::default)
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_asset/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ downcast-rs = "1.2.0"
notify = { version = "=5.0.0-pre.11", optional = true }
parking_lot = "0.11.0"
rand = "0.8.0"
async-trait = "0.1"

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { version = "0.2" }
Expand Down
8 changes: 6 additions & 2 deletions crates/bevy_asset/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,12 @@ mod tests {
#[uuid = "44115972-f31b-46e5-be5c-2b9aece6a52f"]
struct MyAsset;
let mut app = App::new();
app.add_plugin(bevy_core::CorePlugin)
.add_plugin(crate::AssetPlugin);
futures_lite::future::block_on(async {
app.add_plugin(bevy_core::CorePlugin)
.await
.add_plugin(crate::AssetPlugin)
.await
});
app.add_asset::<MyAsset>();
let mut assets_before = app.world.resource_mut::<Assets<MyAsset>>();
let handle = assets_before.add(MyAsset);
Expand Down
7 changes: 5 additions & 2 deletions crates/bevy_asset/src/debug_asset_server.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use async_trait::async_trait;
use bevy_app::{App, Plugin};
use bevy_ecs::{
event::Events,
Expand Down Expand Up @@ -56,8 +57,9 @@ impl<T: Asset> Default for HandleMap<T> {
}
}

#[async_trait]
impl Plugin for DebugAssetServerPlugin {
fn build(&self, app: &mut bevy_app::App) {
async fn build(&self, app: &mut bevy_app::App) {
IoTaskPool::init(|| {
TaskPoolBuilder::default()
.num_threads(2)
Expand All @@ -70,7 +72,8 @@ impl Plugin for DebugAssetServerPlugin {
asset_folder: "crates".to_string(),
watch_for_changes: true,
})
.add_plugin(AssetPlugin);
.add_plugin(AssetPlugin)
.await;
app.insert_non_send_resource(DebugAssetApp(debug_asset_app));
app.add_system(run_debug_asset_app);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{Asset, Assets};
use async_trait::async_trait;
use bevy_app::prelude::*;
use bevy_diagnostic::{Diagnostic, DiagnosticId, Diagnostics, MAX_DIAGNOSTIC_NAME_WIDTH};
use bevy_ecs::system::{Res, ResMut};
Expand All @@ -16,8 +17,9 @@ impl<T: Asset> Default for AssetCountDiagnosticsPlugin<T> {
}
}

#[async_trait]
impl<T: Asset> Plugin for AssetCountDiagnosticsPlugin<T> {
fn build(&self, app: &mut App) {
async fn build(&self, app: &mut App) {
app.add_startup_system(Self::setup_system)
.add_system(Self::diagnostic_system);
}
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub mod prelude {

pub use asset_server::*;
pub use assets::*;
use async_trait::async_trait;
pub use bevy_utils::BoxedFuture;
pub use handle::*;
pub use info::*;
Expand Down Expand Up @@ -78,8 +79,9 @@ pub fn create_platform_default_asset_io(app: &mut App) -> Box<dyn AssetIo> {
Box::new(source)
}

#[async_trait]
impl Plugin for AssetPlugin {
fn build(&self, app: &mut App) {
async fn build(&self, app: &mut App) {
if !app.world.contains_resource::<AssetServer>() {
let source = create_platform_default_asset_io(app);
let asset_server = AssetServer::with_boxed_io(source);
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_audio/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }
anyhow = "1.0.4"
rodio = { version = "0.15", default-features = false }
parking_lot = "0.11.0"
async-trait = "0.1"

[target.'cfg(target_arch = "wasm32")'.dependencies]
rodio = { version = "0.15", default-features = false, features = ["wasm-bindgen"] }
Expand Down
12 changes: 8 additions & 4 deletions crates/bevy_audio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
//! # use bevy_app::{App, AppExit};
//! # use bevy_internal::MinimalPlugins;
//! fn main() {
//! # async {
//! App::new()
//! .add_plugins(MinimalPlugins)
//! .add_plugin(AssetPlugin)
//! .add_plugin(AudioPlugin)
//! .add_plugins(MinimalPlugins).await
//! .add_plugin(AssetPlugin).await
//! .add_plugin(AudioPlugin).await
//! # .add_system(stop)
//! .add_startup_system(play_background_audio)
//! .run();
//! # };
//! }
//!
//! fn play_background_audio(asset_server: Res<AssetServer>, audio: Res<Audio>) {
Expand All @@ -38,6 +40,7 @@ pub mod prelude {
pub use crate::{Audio, AudioOutput, AudioSource, Decodable, PlaybackSettings};
}

use async_trait::async_trait;
pub use audio::*;
pub use audio_output::*;
pub use audio_source::*;
Expand All @@ -51,8 +54,9 @@ use bevy_asset::AddAsset;
#[derive(Default)]
pub struct AudioPlugin;

#[async_trait]
impl Plugin for AudioPlugin {
fn build(&self, app: &mut App) {
async fn build(&self, app: &mut App) {
app.init_non_send_resource::<AudioOutput<AudioSource>>()
.add_asset::<AudioSource>()
.add_asset::<AudioSink>()
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }

# other
bytemuck = "1.5"
async-trait = "0.1"
4 changes: 3 additions & 1 deletion crates/bevy_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
mod name;
mod task_pool_options;

use async_trait::async_trait;
pub use bytemuck::{bytes_of, cast_slice, Pod, Zeroable};
pub use name::*;
pub use task_pool_options::*;
Expand All @@ -23,8 +24,9 @@ use std::ops::Range;
#[derive(Default)]
pub struct CorePlugin;

#[async_trait]
impl Plugin for CorePlugin {
fn build(&self, app: &mut App) {
async fn build(&self, app: &mut App) {
// Setup the default bevy task pools
app.world
.get_resource::<DefaultTaskPoolOptions>()
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_core_pipeline/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ bevy_render = { path = "../bevy_render", version = "0.8.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.8.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }

# other
serde = { version = "1", features = ["derive"] }

async-trait = "0.1"
Loading