From 64b49c92d068bbde8e5a1fadad82a2de98ac1e5e Mon Sep 17 00:00:00 2001 From: Vitaliy Sapronenko Date: Fri, 21 Jun 2024 16:44:55 +0300 Subject: [PATCH] Sysinfo plugin compilation has been fixed for disabled multi_threaded feature --- crates/bevy_diagnostic/Cargo.toml | 1 + .../system_information_diagnostics_plugin.rs | 13 +++- crates/bevy_internal/Cargo.toml | 1 + .../src/single_threaded_task_pool.rs | 61 ++++++++++++++++--- 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/crates/bevy_diagnostic/Cargo.toml b/crates/bevy_diagnostic/Cargo.toml index a9678d0a23ee0..3ba84cd025251 100644 --- a/crates/bevy_diagnostic/Cargo.toml +++ b/crates/bevy_diagnostic/Cargo.toml @@ -12,6 +12,7 @@ keywords = ["bevy"] # Disables diagnostics that are unsupported when Bevy is dynamically linked dynamic_linking = [] sysinfo_plugin = ["sysinfo"] +multi_threaded = [] [dependencies] # bevy diff --git a/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs index 981912ddc511c..148f5890068b3 100644 --- a/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs @@ -67,7 +67,12 @@ pub mod internal { use bevy_app::{App, First, Startup, Update}; use bevy_ecs::system::Resource; - use bevy_tasks::{available_parallelism, block_on, poll_once, AsyncComputeTaskPool, Task}; + #[cfg(not(feature = "multi_threaded"))] + use bevy_tasks::FakeTask; + use bevy_tasks::{available_parallelism, AsyncComputeTaskPool}; + #[cfg(feature = "multi_threaded")] + use bevy_tasks::{block_on, poll_once, Task}; + use bevy_utils::tracing::info; use sysinfo::{CpuRefreshKind, MemoryRefreshKind, RefreshKind, System}; @@ -98,7 +103,10 @@ pub mod internal { #[derive(Resource, Default)] struct SysinfoTasks { + #[cfg(feature = "multi_threaded")] tasks: Vec>, + #[cfg(not(feature = "multi_threaded"))] + tasks: Vec>, } fn launch_diagnostic_tasks( @@ -151,9 +159,12 @@ pub mod internal { fn read_diagnostic_tasks(mut diagnostics: Diagnostics, mut tasks: ResMut) { tasks.tasks.retain_mut(|task| { + #[cfg(feature = "multi_threaded")] let Some(data) = block_on(poll_once(task)) else { return true; }; + #[cfg(not(feature = "multi_threaded"))] + let data = &task.result; diagnostics.add_measurement(&SystemInformationDiagnosticsPlugin::CPU_USAGE, || { data.current_cpu_usage diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 36f3597fbf3c1..f2b330b0e3a99 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -86,6 +86,7 @@ multi_threaded = [ "bevy_ecs/multi_threaded", "bevy_render?/multi_threaded", "bevy_tasks/multi_threaded", + "bevy_diagnostic/multi_threaded", ] async-io = ["bevy_tasks/async-io"] diff --git a/crates/bevy_tasks/src/single_threaded_task_pool.rs b/crates/bevy_tasks/src/single_threaded_task_pool.rs index de7a13891593d..b2edcc74a9c8c 100644 --- a/crates/bevy_tasks/src/single_threaded_task_pool.rs +++ b/crates/bevy_tasks/src/single_threaded_task_pool.rs @@ -150,28 +150,51 @@ impl TaskPool { /// end-user. /// /// If the provided future is non-`Send`, [`TaskPool::spawn_local`] should be used instead. + #[cfg(not(target_arch = "wasm32"))] + pub fn spawn(&self, future: impl Future + 'static) -> FakeTask + where + T: 'static, + { + LOCAL_EXECUTOR.with(|executor| { + let task = executor.spawn(future); + // Loop until all tasks are done + while executor.try_tick() {} + + FakeTask { + // task should be ready + result: crate::block_on(task), + } + }) + } + + /// Spawns a static future onto the thread pool. The returned Task is a future. It can also be + /// cancelled and "detached" allowing it to continue running without having to be polled by the + /// end-user. + /// + /// If the provided future is non-`Send`, [`TaskPool::spawn_local`] should be used instead. + #[cfg(target_arch = "wasm32")] pub fn spawn(&self, future: impl Future + 'static) -> FakeTask where T: 'static, { - #[cfg(target_arch = "wasm32")] wasm_bindgen_futures::spawn_local(async move { future.await; }); - #[cfg(not(target_arch = "wasm32"))] - { - LOCAL_EXECUTOR.with(|executor| { - let _task = executor.spawn(future); - // Loop until all tasks are done - while executor.try_tick() {} - }); - } - FakeTask } /// Spawns a static future on the JS event loop. This is exactly the same as [`TaskPool::spawn`]. + #[cfg(not(target_arch = "wasm32"))] + pub fn spawn_local(&self, future: impl Future + 'static) -> FakeTask + where + T: 'static, + { + self.spawn(future) + } + + /// Spawns a static future on the JS event loop. This is exactly the same as [`TaskPool::spawn`]. + #[cfg(target_arch = "wasm32")] pub fn spawn_local(&self, future: impl Future + 'static) -> FakeTask where T: 'static, @@ -202,8 +225,26 @@ impl TaskPool { /// /// This does nothing and is therefore safe, and recommended, to ignore. #[derive(Debug)] +#[cfg(not(target_arch = "wasm32"))] +pub struct FakeTask { + /// In case of not wasm arch contains result of future execution + pub result: T, +} + +#[cfg(not(target_arch = "wasm32"))] +impl FakeTask { + /// No op on the single threaded task pool + pub fn detach(self) {} +} + +/// An empty task used in single-threaded contexts. +/// +/// This does nothing and is therefore safe, and recommended, to ignore. +#[derive(Debug)] +#[cfg(target_arch = "wasm32")] pub struct FakeTask; +#[cfg(target_arch = "wasm32")] impl FakeTask { /// No op on the single threaded task pool pub fn detach(self) {}