#![doc = include_str!("../README.md")]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc(
html_logo_url = "https://bevy.org/assets/icon.png",
html_favicon_url = "https://bevy.org/assets/icon.png"
)]
#![no_std]
pub mod cfg {
pub(crate) use bevy_platform::cfg::*;
pub use bevy_platform::cfg::{alloc, std, web};
define_alias! {
#[cfg(feature = "async_executor")] => {
async_executor
}
#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))] => {
multi_threaded
}
#[cfg(target_arch = "wasm32")] => {
conditional_send
}
#[cfg(feature = "async-io")] => {
async_io
}
#[cfg(feature = "futures-lite")] => {
futures_lite
}
}
}
cfg::std! {
extern crate std;
}
extern crate alloc;
cfg::conditional_send! {
if {
pub trait ConditionalSend {}
impl<T> ConditionalSend for T {}
} else {
pub trait ConditionalSend: Send {}
impl<T: Send> ConditionalSend for T {}
}
}
pub trait ConditionalSendFuture: Future + ConditionalSend {}
impl<T: Future + ConditionalSend> ConditionalSendFuture for T {}
use alloc::boxed::Box;
pub type BoxedFuture<'a, T> = core::pin::Pin<Box<dyn ConditionalSendFuture<Output = T> + 'a>>;
mod executor;
pub mod futures;
mod iter;
mod slice;
mod task;
mod usages;
cfg::async_executor! {
if {} else {
mod edge_executor;
}
}
pub use iter::ParallelIterator;
pub use slice::{ParallelSlice, ParallelSliceMut};
pub use task::Task;
pub use usages::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool};
pub use futures_lite;
pub use futures_lite::future::poll_once;
cfg::web! {
if {} else {
pub use usages::tick_global_task_pools_on_main_thread;
}
}
cfg::multi_threaded! {
if {
mod task_pool;
mod thread_executor;
pub use task_pool::{Scope, TaskPool, TaskPoolBuilder};
pub use thread_executor::{ThreadExecutor, ThreadExecutorTicker};
} else {
mod single_threaded_task_pool;
pub use single_threaded_task_pool::{Scope, TaskPool, TaskPoolBuilder, ThreadExecutor};
}
}
cfg::switch! {
cfg::async_io => {
pub use async_io::block_on;
}
cfg::futures_lite => {
pub use futures_lite::future::block_on;
}
_ => {
pub fn block_on<T>(future: impl Future<Output = T>) -> T {
use core::task::{Poll, Context};
let mut future = core::pin::pin!(future);
let cx = &mut Context::from_waker(core::task::Waker::noop());
loop {
match future.as_mut().poll(cx) {
Poll::Ready(output) => return output,
Poll::Pending => core::hint::spin_loop(),
}
}
}
}
}
pub mod prelude {
#[doc(hidden)]
pub use crate::{
block_on,
iter::ParallelIterator,
slice::{ParallelSlice, ParallelSliceMut},
usages::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool},
};
}
pub fn available_parallelism() -> usize {
cfg::switch! {{
cfg::std => {
std::thread::available_parallelism()
.map(core::num::NonZero::<usize>::get)
.unwrap_or(1)
}
_ => {
1
}
}}
}