diff --git a/crates/bevy_app/Cargo.toml b/crates/bevy_app/Cargo.toml index f46db94db36bc..0abe05e6a7d43 100644 --- a/crates/bevy_app/Cargo.toml +++ b/crates/bevy_app/Cargo.toml @@ -48,14 +48,12 @@ std = [ "dep:ctrlc", "downcast-rs/std", "bevy_utils/std", - "bevy_tasks/std", "bevy_platform/std", ] ## `critical-section` provides the building blocks for synchronization primitives ## on all platforms, including `no_std`. critical-section = [ - "bevy_tasks/critical-section", "bevy_ecs/critical-section", "bevy_platform/critical-section", "bevy_reflect?/critical-section", @@ -65,7 +63,6 @@ critical-section = [ ## Note this is currently only applicable on `wasm32` architectures. web = [ "bevy_platform/web", - "bevy_tasks/web", "bevy_reflect?/web", "dep:wasm-bindgen", "dep:web-sys", diff --git a/crates/bevy_asset/Cargo.toml b/crates/bevy_asset/Cargo.toml index 07a45a3f6d210..5ec919804d12e 100644 --- a/crates/bevy_asset/Cargo.toml +++ b/crates/bevy_asset/Cargo.toml @@ -81,9 +81,6 @@ uuid = { version = "1.13.1", default-features = false, features = ["js"] } bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = false, features = [ "web", ] } -bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, features = [ - "web", -] } bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, features = [ "web", ] } diff --git a/crates/bevy_diagnostic/Cargo.toml b/crates/bevy_diagnostic/Cargo.toml index eff17104387df..17ad6df5c97d9 100644 --- a/crates/bevy_diagnostic/Cargo.toml +++ b/crates/bevy_diagnostic/Cargo.toml @@ -40,7 +40,6 @@ std = [ "bevy_platform/std", "bevy_time/std", "bevy_utils/std", - "bevy_tasks/std", ] ## `critical-section` provides the building blocks for synchronization primitives @@ -51,7 +50,6 @@ critical-section = [ "bevy_platform/critical-section", "bevy_time/critical-section", "bevy_utils/critical-section", - "bevy_tasks/critical-section", ] [dependencies] diff --git a/crates/bevy_ecs/Cargo.toml b/crates/bevy_ecs/Cargo.toml index 97cdcee0824b7..91f5a6998113d 100644 --- a/crates/bevy_ecs/Cargo.toml +++ b/crates/bevy_ecs/Cargo.toml @@ -73,7 +73,6 @@ async_executor = ["std", "bevy_tasks/async_executor"] ## supported platforms. std = [ "bevy_reflect?/std", - "bevy_tasks/std", "bevy_utils/std", "bitflags/std", "concurrent-queue/std", @@ -90,7 +89,6 @@ std = [ ## `critical-section` provides the building blocks for synchronization primitives ## on all platforms, including `no_std`. critical-section = [ - "bevy_tasks/critical-section", "bevy_platform/critical-section", "bevy_reflect?/critical-section", ] diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 28d234f2b4e3e..24364fb9089f0 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -300,7 +300,6 @@ std = [ "bevy_time/std", "bevy_transform/std", "bevy_utils/std", - "bevy_tasks/std", "bevy_window?/std", ] @@ -318,7 +317,6 @@ critical-section = [ "bevy_state?/critical-section", "bevy_time/critical-section", "bevy_utils/critical-section", - "bevy_tasks/critical-section", ] # Uses the `libm` maths library instead of the one provided in `std` and `core`. @@ -342,12 +340,7 @@ async_executor = [ # Enables use of browser APIs. # Note this is currently only applicable on `wasm32` architectures. -web = [ - "bevy_app/web", - "bevy_platform/web", - "bevy_reflect/web", - "bevy_tasks/web", -] +web = ["bevy_app/web", "bevy_platform/web", "bevy_reflect/web"] [dependencies] # bevy (no_std) diff --git a/crates/bevy_platform/Cargo.toml b/crates/bevy_platform/Cargo.toml index 44c680394d5a3..bc2fc3dfc2645 100644 --- a/crates/bevy_platform/Cargo.toml +++ b/crates/bevy_platform/Cargo.toml @@ -32,6 +32,10 @@ std = [ "spin/std", "foldhash/std", "serde?/std", + "wasm-bindgen-futures?/std", + "futures-channel/std", + "wasm-bindgen?/std", + "js-sys?/std", ] ## Allows access to the `alloc` crate. @@ -43,7 +47,14 @@ critical-section = ["dep:critical-section", "portable-atomic/critical-section"] ## Enables use of browser APIs. ## Note this is currently only applicable on `wasm32` architectures. -web = ["dep:web-time", "dep:getrandom"] +web = [ + "std", + "dep:web-time", + "dep:getrandom", + "dep:wasm-bindgen-futures", + "dep:wasm-bindgen", + "dep:js-sys", +] [dependencies] critical-section = { version = "1.2.0", default-features = false, optional = true } @@ -68,6 +79,10 @@ web-time = { version = "1.1", default-features = false, optional = true } getrandom = { version = "0.2.0", default-features = false, optional = true, features = [ "js", ] } +wasm-bindgen-futures = { version = "0.4", default-features = false, optional = true } +futures-channel = { version = "0.3", default-features = false } +js-sys = { version = "0.3", default-features = false, optional = true } +wasm-bindgen = { version = "0.2", default-features = false, optional = true } [target.'cfg(not(all(target_has_atomic = "8", target_has_atomic = "16", target_has_atomic = "32", target_has_atomic = "64", target_has_atomic = "ptr")))'.dependencies] portable-atomic = { version = "1", default-features = false, features = [ diff --git a/crates/bevy_platform/src/lib.rs b/crates/bevy_platform/src/lib.rs index 668442f29929f..6603521d28e1b 100644 --- a/crates/bevy_platform/src/lib.rs +++ b/crates/bevy_platform/src/lib.rs @@ -50,3 +50,14 @@ pub mod prelude { // * println // * thread_local } + +/// Re-exports of crates that are useful across Bevy. +/// Not intended for external crates to use. +#[doc(hidden)] +pub mod exports { + crate::cfg::web! { + pub use js_sys; + pub use wasm_bindgen; + pub use wasm_bindgen_futures; + } +} diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index aa6b6e239cbfd..f59207b0ae98e 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -141,9 +141,6 @@ wasm-bindgen = "0.2" bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = false, features = [ "web", ] } -bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, features = [ - "web", -] } bevy_platform = { path = "../bevy_platform", version = "0.16.0-dev", default-features = false, features = [ "web", ] } diff --git a/crates/bevy_tasks/Cargo.toml b/crates/bevy_tasks/Cargo.toml index 07c20b9750f5b..58c59ff5aaf72 100644 --- a/crates/bevy_tasks/Cargo.toml +++ b/crates/bevy_tasks/Cargo.toml @@ -9,37 +9,27 @@ license = "MIT OR Apache-2.0" keywords = ["bevy"] [features] -default = ["std", "async_executor"] +default = ["async_executor", "futures-lite"] -# Functionality - -## Enables multi-threading support. -## Without this feature, all tasks will be run on a single thread. -multi_threaded = ["std", "dep:async-channel", "dep:concurrent-queue"] - -## Uses `async-executor` as a task execution backend. -## This backend is incompatible with `no_std` targets. -async_executor = ["std", "dep:async-executor"] - -# Platform Compatibility +# Enables multi-threading support. +# Without this feature, all tasks will be run on a single thread. +multi_threaded = [ + "bevy_platform/std", + "dep:async-channel", + "dep:concurrent-queue", + "async_executor", +] -## Allows access to the `std` crate. Enabling this feature will prevent compilation -## on `no_std` targets, but provides access to certain additional features on -## supported platforms. -std = ["futures-lite/std", "async-task/std", "bevy_platform/std"] +# Uses `async-executor` as a task execution backend. +# This backend is incompatible with `no_std` targets. +async_executor = ["bevy_platform/std", "dep:async-executor"] -## `critical-section` provides the building blocks for synchronization primitives -## on all platforms, including `no_std`. -critical-section = ["bevy_platform/critical-section"] +# Provide an implementation of `block_on` from `futures-lite`. +futures-lite = ["bevy_platform/std", "futures-lite/std"] -## Enables use of browser APIs. -## Note this is currently only applicable on `wasm32` architectures. -web = [ - "bevy_platform/web", - "dep:wasm-bindgen-futures", - "dep:pin-project", - "dep:futures-channel", -] +# Use async-io's implementation of block_on instead of futures-lite's implementation. +# This is preferred if your application uses async-io. +async-io = ["bevy_platform/std", "dep:async-io"] [dependencies] bevy_platform = { path = "../bevy_platform", version = "0.16.0-dev", default-features = false, features = [ @@ -54,7 +44,6 @@ derive_more = { version = "1", default-features = false, features = [ "deref", "deref_mut", ] } -cfg-if = "1.0.0" async-executor = { version = "1.11", optional = true } async-channel = { version = "2.3.0", optional = true } async-io = { version = "2.0.0", optional = true } @@ -65,9 +54,8 @@ crossbeam-queue = { version = "0.3", default-features = false, features = [ ] } [target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen-futures = { version = "0.4", optional = true } -pin-project = { version = "1", optional = true } -futures-channel = { version = "0.3", optional = true } +pin-project = { version = "1" } +futures-channel = { version = "0.3", default-features = false } [target.'cfg(not(all(target_has_atomic = "8", target_has_atomic = "16", target_has_atomic = "32", target_has_atomic = "64", target_has_atomic = "ptr")))'.dependencies] async-task = { version = "4.4.0", default-features = false, features = [ @@ -80,6 +68,11 @@ atomic-waker = { version = "1", default-features = false, features = [ "portable-atomic", ] } +[dev-dependencies] +futures-lite = { version = "2.0.1", default-features = false, features = [ + "std", +] } + [lints] workspace = true diff --git a/crates/bevy_tasks/src/executor.rs b/crates/bevy_tasks/src/executor.rs index 9a9f4f9dfa8b2..129bc2ed894dc 100644 --- a/crates/bevy_tasks/src/executor.rs +++ b/crates/bevy_tasks/src/executor.rs @@ -14,8 +14,8 @@ use core::{ }; use derive_more::{Deref, DerefMut}; -cfg_if::cfg_if! { - if #[cfg(feature = "async_executor")] { +crate::cfg::async_executor! { + if { type ExecutorInner<'a> = async_executor::Executor<'a>; type LocalExecutorInner<'a> = async_executor::LocalExecutor<'a>; } else { @@ -24,8 +24,9 @@ cfg_if::cfg_if! { } } -#[cfg(all(feature = "multi_threaded", not(target_arch = "wasm32")))] -pub use async_task::FallibleTask; +crate::cfg::multi_threaded! { + pub use async_task::FallibleTask; +} /// Wrapper around a multi-threading-aware async executor. /// Spawning will generally require tasks to be `Send` and `Sync` to allow multiple diff --git a/crates/bevy_tasks/src/futures.rs b/crates/bevy_tasks/src/futures.rs index a28138e0ecaa2..7bc6c59c00f5c 100644 --- a/crates/bevy_tasks/src/futures.rs +++ b/crates/bevy_tasks/src/futures.rs @@ -49,7 +49,7 @@ fn noop_raw_waker() -> RawWaker { RawWaker::new(core::ptr::null(), &NOOP_WAKER_VTABLE) } -fn noop_waker() -> Waker { +pub(crate) fn noop_waker() -> Waker { // SAFETY: the `RawWakerVTable` is just a big noop and doesn't violate any of the rules in `RawWakerVTable`s documentation // (which talks about retaining and releasing any "resources", of which there are none in this case) unsafe { Waker::from_raw(noop_raw_waker()) } diff --git a/crates/bevy_tasks/src/lib.rs b/crates/bevy_tasks/src/lib.rs index ae684a4eb5124..ec18a20b3f6ca 100644 --- a/crates/bevy_tasks/src/lib.rs +++ b/crates/bevy_tasks/src/lib.rs @@ -6,28 +6,59 @@ )] #![no_std] -#[cfg(feature = "std")] -extern crate std; +/// Configuration information for this crate. +pub mod cfg { + pub(crate) use bevy_platform::cfg::*; -extern crate alloc; + pub use bevy_platform::cfg::{alloc, std, web}; + + define_alias! { + #[cfg(feature = "async_executor")] => { + /// Indicates `async_executor` is used as the future execution backend. + async_executor + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))] => { + /// Indicates multithreading support. + multi_threaded + } + + #[cfg(target_arch = "wasm32")] => { + /// Indicates the current target requires additional `Send` bounds. + conditional_send + } + + #[cfg(feature = "async-io")] => { + /// Indicates `async-io` will be used for the implementation of `block_on`. + async_io + } -mod conditional_send { - cfg_if::cfg_if! { - if #[cfg(target_arch = "wasm32")] { - /// Use [`ConditionalSend`] to mark an optional Send trait bound. Useful as on certain platforms (eg. Wasm), - /// futures aren't Send. - pub trait ConditionalSend {} - impl ConditionalSend for T {} - } else { - /// Use [`ConditionalSend`] to mark an optional Send trait bound. Useful as on certain platforms (eg. Wasm), - /// futures aren't Send. - pub trait ConditionalSend: Send {} - impl ConditionalSend for T {} + #[cfg(feature = "futures-lite")] => { + /// Indicates `futures-lite` will be used for the implementation of `block_on`. + futures_lite } } } -pub use conditional_send::*; +cfg::std! { + extern crate std; +} + +extern crate alloc; + +cfg::conditional_send! { + if { + /// Use [`ConditionalSend`] to mark an optional Send trait bound. Useful as on certain platforms (eg. Wasm), + /// futures aren't Send. + pub trait ConditionalSend {} + impl ConditionalSend for T {} + } else { + /// Use [`ConditionalSend`] to mark an optional Send trait bound. Useful as on certain platforms (eg. Wasm), + /// futures aren't Send. + pub trait ConditionalSend: Send {} + impl ConditionalSend for T {} + } +} /// Use [`ConditionalSendFuture`] for a future with an optional Send trait bound, as on certain platforms (eg. Wasm), /// futures aren't Send. @@ -41,27 +72,38 @@ pub type BoxedFuture<'a, T> = core::pin::Pin { pub use async_io::block_on; - } else { + } + cfg::futures_lite => { pub use futures_lite::future::block_on; } + _ => { + /// Blocks on the supplied `future`. + /// This implementation will busy-wait until it is completed. + /// Consider enabling the `async-io` or `futures-lite` features. + pub fn block_on(future: impl Future) -> T { + use core::task::{Poll, Context}; + + // Pin the future on the stack. + let mut future = core::pin::pin!(future); + + // We don't care about the waker as we're just going to poll as fast as possible. + let waker = futures::noop_waker(); + let cx = &mut Context::from_waker(&waker); + + // Keep polling until the future is ready. + loop { + match future.as_mut().poll(cx) { + Poll::Ready(output) => return output, + Poll::Pending => core::hint::spin_loop(), + } + } + } + } } mod iter; @@ -95,38 +157,28 @@ pub use futures_lite; pub mod prelude { #[doc(hidden)] pub use crate::{ + block_on, iter::ParallelIterator, slice::{ParallelSlice, ParallelSliceMut}, usages::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool}, }; - - #[cfg(feature = "std")] - #[doc(hidden)] - pub use crate::block_on; } -cfg_if::cfg_if! { - if #[cfg(feature = "std")] { - use core::num::NonZero; - - /// Gets the logical CPU core count available to the current process. - /// - /// This is identical to [`std::thread::available_parallelism`], except - /// it will return a default value of 1 if it internally errors out. - /// - /// This will always return at least 1. - pub fn available_parallelism() -> usize { +/// Gets the logical CPU core count available to the current process. +/// +/// This is identical to `std::thread::available_parallelism`, except +/// it will return a default value of 1 if it internally errors out. +/// +/// This will always return at least 1. +pub fn available_parallelism() -> usize { + cfg::switch! {{ + cfg::std => { std::thread::available_parallelism() - .map(NonZero::::get) + .map(core::num::NonZero::::get) .unwrap_or(1) } - } else { - /// Gets the logical CPU core count available to the current process. - /// - /// This will always return at least 1. - pub fn available_parallelism() -> usize { - // Without access to std, assume a single thread is available + _ => { 1 } - } + }} } diff --git a/crates/bevy_tasks/src/single_threaded_task_pool.rs b/crates/bevy_tasks/src/single_threaded_task_pool.rs index 0f9488bcd0f33..d7f74c2d66c86 100644 --- a/crates/bevy_tasks/src/single_threaded_task_pool.rs +++ b/crates/bevy_tasks/src/single_threaded_task_pool.rs @@ -4,32 +4,26 @@ use core::{cell::RefCell, future::Future, marker::PhantomData, mem}; use crate::Task; -#[cfg(feature = "std")] -use std::thread_local; +crate::cfg::std! { + if { + use std::thread_local; + use crate::executor::LocalExecutor; -#[cfg(not(feature = "std"))] -use bevy_platform::sync::{Mutex, PoisonError}; + thread_local! { + static LOCAL_EXECUTOR: LocalExecutor<'static> = const { LocalExecutor::new() }; + } -#[cfg(feature = "std")] -use crate::executor::LocalExecutor; + type ScopeResult = alloc::rc::Rc>>; + } else { + use bevy_platform::sync::{Mutex, PoisonError}; + use crate::executor::Executor as LocalExecutor; -#[cfg(not(feature = "std"))] -use crate::executor::Executor as LocalExecutor; + static LOCAL_EXECUTOR: LocalExecutor<'static> = const { LocalExecutor::new() }; -#[cfg(feature = "std")] -thread_local! { - static LOCAL_EXECUTOR: LocalExecutor<'static> = const { LocalExecutor::new() }; + type ScopeResult = Arc>>; + } } -#[cfg(not(feature = "std"))] -static LOCAL_EXECUTOR: LocalExecutor<'static> = const { LocalExecutor::new() }; - -#[cfg(feature = "std")] -type ScopeResult = alloc::rc::Rc>>; - -#[cfg(not(feature = "std"))] -type ScopeResult = Arc>>; - /// Used to create a [`TaskPool`]. #[derive(Debug, Default, Clone)] pub struct TaskPoolBuilder {} @@ -173,16 +167,15 @@ impl TaskPool { let results = scope.results.borrow(); results .iter() - .map(|result| { - #[cfg(feature = "std")] - return result.borrow_mut().take().unwrap(); - - #[cfg(not(feature = "std"))] - { + .map(|result| crate::cfg::switch! {{ + crate::cfg::std => { + result.borrow_mut().take().unwrap() + } + _ => { let mut lock = result.lock().unwrap_or_else(PoisonError::into_inner); lock.take().unwrap() } - }) + }}) .collect() } @@ -199,10 +192,11 @@ impl TaskPool { where T: 'static + MaybeSend + MaybeSync, { - cfg_if::cfg_if! { - if #[cfg(all(target_arch = "wasm32", feature = "web"))] { + crate::cfg::switch! {{ + crate::cfg::web => { Task::wrap_future(future) - } else if #[cfg(feature = "std")] { + } + crate::cfg::std => { LOCAL_EXECUTOR.with(|executor| { let task = executor.spawn(future); // Loop until all tasks are done @@ -210,16 +204,15 @@ impl TaskPool { Task::new(task) }) - } else { - { - let task = LOCAL_EXECUTOR.spawn(future); - // Loop until all tasks are done - while LOCAL_EXECUTOR.try_tick() {} + } + _ => { + let task = LOCAL_EXECUTOR.spawn(future); + // Loop until all tasks are done + while LOCAL_EXECUTOR.try_tick() {} - Task::new(task) - } + Task::new(task) } - } + }} } /// Spawns a static future on the JS event loop. This is exactly the same as [`TaskPool::spawn`]. @@ -248,11 +241,14 @@ impl TaskPool { where F: FnOnce(&LocalExecutor) -> R, { - #[cfg(feature = "std")] - return LOCAL_EXECUTOR.with(f); - - #[cfg(not(feature = "std"))] - return f(&LOCAL_EXECUTOR); + crate::cfg::switch! {{ + crate::cfg::std => { + LOCAL_EXECUTOR.with(f) + } + _ => { + f(&LOCAL_EXECUTOR) + } + }} } } @@ -304,35 +300,31 @@ impl<'scope, 'env, T: Send + 'env> Scope<'scope, 'env, T> { let f = async move { let temp_result = f.await; - #[cfg(feature = "std")] - result.borrow_mut().replace(temp_result); - - #[cfg(not(feature = "std"))] - { - let mut lock = result.lock().unwrap_or_else(PoisonError::into_inner); - *lock = Some(temp_result); + crate::cfg::std! { + if { + result.borrow_mut().replace(temp_result); + } else { + let mut lock = result.lock().unwrap_or_else(PoisonError::into_inner); + *lock = Some(temp_result); + } } }; self.executor.spawn(f).detach(); } } -#[cfg(feature = "std")] -mod send_sync_bounds { - pub trait MaybeSend {} - impl MaybeSend for T {} - - pub trait MaybeSync {} - impl MaybeSync for T {} -} - -#[cfg(not(feature = "std"))] -mod send_sync_bounds { - pub trait MaybeSend: Send {} - impl MaybeSend for T {} - - pub trait MaybeSync: Sync {} - impl MaybeSync for T {} +crate::cfg::std! { + if { + pub trait MaybeSend {} + impl MaybeSend for T {} + + pub trait MaybeSync {} + impl MaybeSync for T {} + } else { + pub trait MaybeSend: Send {} + impl MaybeSend for T {} + + pub trait MaybeSync: Sync {} + impl MaybeSync for T {} + } } - -use send_sync_bounds::{MaybeSend, MaybeSync}; diff --git a/crates/bevy_tasks/src/usages.rs b/crates/bevy_tasks/src/usages.rs index 8b08d5941c6bd..40cabd76ac5e6 100644 --- a/crates/bevy_tasks/src/usages.rs +++ b/crates/bevy_tasks/src/usages.rs @@ -75,32 +75,35 @@ taskpool! { (IO_TASK_POOL, IoTaskPool) } -/// A function used by `bevy_app` to tick the global tasks pools on the main thread. -/// This will run a maximum of 100 local tasks per executor per call to this function. -/// -/// # Warning -/// -/// This function *must* be called on the main thread, or the task pools will not be updated appropriately. -#[cfg(not(all(target_arch = "wasm32", feature = "web")))] -pub fn tick_global_task_pools_on_main_thread() { - COMPUTE_TASK_POOL - .get() - .unwrap() - .with_local_executor(|compute_local_executor| { - ASYNC_COMPUTE_TASK_POOL +crate::cfg::web! { + if {} else { + /// A function used by `bevy_app` to tick the global tasks pools on the main thread. + /// This will run a maximum of 100 local tasks per executor per call to this function. + /// + /// # Warning + /// + /// This function *must* be called on the main thread, or the task pools will not be updated appropriately. + pub fn tick_global_task_pools_on_main_thread() { + COMPUTE_TASK_POOL .get() .unwrap() - .with_local_executor(|async_local_executor| { - IO_TASK_POOL + .with_local_executor(|compute_local_executor| { + ASYNC_COMPUTE_TASK_POOL .get() .unwrap() - .with_local_executor(|io_local_executor| { - for _ in 0..100 { - compute_local_executor.try_tick(); - async_local_executor.try_tick(); - io_local_executor.try_tick(); - } + .with_local_executor(|async_local_executor| { + IO_TASK_POOL + .get() + .unwrap() + .with_local_executor(|io_local_executor| { + for _ in 0..100 { + compute_local_executor.try_tick(); + async_local_executor.try_tick(); + io_local_executor.try_tick(); + } + }); }); }); - }); + } + } } diff --git a/crates/bevy_tasks/src/wasm_task.rs b/crates/bevy_tasks/src/wasm_task.rs index 0cc569c47913d..91eac7304ddec 100644 --- a/crates/bevy_tasks/src/wasm_task.rs +++ b/crates/bevy_tasks/src/wasm_task.rs @@ -1,13 +1,14 @@ use alloc::boxed::Box; use core::{ any::Any, - future::{Future, IntoFuture}, + future::Future, panic::{AssertUnwindSafe, UnwindSafe}, pin::Pin, task::{Context, Poll}, }; use futures_channel::oneshot; +use bevy_platform::exports::wasm_bindgen_futures; /// Wraps an asynchronous task, a spawned future. /// @@ -24,7 +25,7 @@ impl Task { let value = CatchUnwind(AssertUnwindSafe(future)).await; let _ = sender.send(value); }); - Self(receiver.into_future()) + Self(receiver) } /// When building for Wasm, this method has no effect. @@ -60,12 +61,14 @@ impl Future for Task { // NOTE: Propagating the panic here sorta has parity with the async_executor behavior. // For those tasks, polling them after a panic returns a `None` which gets `unwrap`ed, so // using `resume_unwind` here is essentially keeping the same behavior while adding more information. - #[cfg(feature = "std")] - Poll::Ready(Ok(Err(panic))) => std::panic::resume_unwind(panic), - #[cfg(not(feature = "std"))] - Poll::Ready(Ok(Err(_panic))) => { - unreachable!("catching a panic is only possible with std") - } + Poll::Ready(Ok(Err(_panic))) => crate::cfg::switch! {{ + crate::cfg::std => { + std::panic::resume_unwind(_panic) + } + _ => { + unreachable!("catching a panic is only possible with std") + } + }}, Poll::Ready(Err(_)) => panic!("Polled a task after it was cancelled"), Poll::Pending => Poll::Pending, } @@ -82,11 +85,14 @@ impl Future for CatchUnwind { fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { let f = AssertUnwindSafe(|| self.project().0.poll(cx)); - #[cfg(feature = "std")] - let result = std::panic::catch_unwind(f)?; - - #[cfg(not(feature = "std"))] - let result = f(); + let result = crate::cfg::switch! {{ + crate::cfg::std => { + std::panic::catch_unwind(f)? + } + _ => { + f() + } + }}; result.map(Ok) } diff --git a/crates/bevy_transform/Cargo.toml b/crates/bevy_transform/Cargo.toml index 348db148ce66a..74736a32b29c6 100644 --- a/crates/bevy_transform/Cargo.toml +++ b/crates/bevy_transform/Cargo.toml @@ -73,7 +73,6 @@ std = [ "bevy_ecs?/std", "bevy_math/std", "bevy_reflect?/std", - "bevy_tasks/std", "bevy_utils/std", "serde?/std", ] @@ -83,7 +82,6 @@ std = [ critical-section = [ "bevy_app?/critical-section", "bevy_ecs?/critical-section", - "bevy_tasks/critical-section", "bevy_reflect?/critical-section", ] diff --git a/crates/bevy_winit/Cargo.toml b/crates/bevy_winit/Cargo.toml index 5665a96029551..cafcda77d4cc9 100644 --- a/crates/bevy_winit/Cargo.toml +++ b/crates/bevy_winit/Cargo.toml @@ -71,9 +71,6 @@ crossbeam-channel = "0.5" bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = false, features = [ "web", ] } -bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, features = [ - "web", -] } bevy_platform = { path = "../bevy_platform", version = "0.16.0-dev", default-features = false, features = [ "web", ] }