Move futures.rs, ConditionalSend and BoxedFuture types to bevy_tasks (#16951)
# Objective - Related to https://github.com/bevyengine/bevy/issues/11478 ## Solution - Moved `futures.rs`, `ConditionalSend` `ConditionalSendFuture` and `BoxedFuture` from `bevy_utils` to `bevy_tasks`. ## Testing - CI checks ## Migration Guide - Several modules were moved from `bevy_utils` into `bevy_tasks`: - Replace `bevy_utils::futures` imports with `bevy_tasks::futures`. - Replace `bevy_utils::ConditionalSend` with `bevy_tasks::ConditionalSend`. - Replace `bevy_utils::ConditionalSendFuture` with `bevy_tasks::ConditionalSendFuture`. - Replace `bevy_utils::BoxedFuture` with `bevy_tasks::BoxedFuture`.
This commit is contained in:
parent
847c3a1719
commit
5157c78651
@ -22,7 +22,7 @@ pub use futures_lite::AsyncWriteExt;
|
|||||||
pub use source::*;
|
pub use source::*;
|
||||||
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture};
|
use bevy_tasks::{BoxedFuture, ConditionalSendFuture};
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::{
|
use core::{
|
||||||
mem::size_of,
|
mem::size_of,
|
||||||
|
|||||||
@ -8,7 +8,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use atomicow::CowArc;
|
use atomicow::CowArc;
|
||||||
use bevy_ecs::world::World;
|
use bevy_ecs::world::World;
|
||||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture, HashMap, HashSet};
|
use bevy_tasks::{BoxedFuture, ConditionalSendFuture};
|
||||||
|
use bevy_utils::{HashMap, HashSet};
|
||||||
use core::any::{Any, TypeId};
|
use core::any::{Any, TypeId};
|
||||||
use downcast_rs::{impl_downcast, Downcast};
|
use downcast_rs::{impl_downcast, Downcast};
|
||||||
use ron::error::SpannedError;
|
use ron::error::SpannedError;
|
||||||
|
|||||||
@ -58,16 +58,15 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use alloc::{collections::VecDeque, sync::Arc};
|
use alloc::{collections::VecDeque, sync::Arc};
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
use bevy_tasks::ConditionalSendFuture;
|
||||||
use bevy_tasks::IoTaskPool;
|
use bevy_tasks::IoTaskPool;
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
use bevy_utils::tracing::{info_span, instrument::Instrument};
|
||||||
use bevy_utils::{
|
use bevy_utils::{
|
||||||
tracing::{debug, error, trace, warn},
|
tracing::{debug, error, trace, warn},
|
||||||
HashMap, HashSet,
|
HashMap, HashSet,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
use bevy_utils::{
|
|
||||||
tracing::{info_span, instrument::Instrument},
|
|
||||||
ConditionalSendFuture,
|
|
||||||
};
|
|
||||||
use futures_io::ErrorKind;
|
use futures_io::ErrorKind;
|
||||||
use futures_lite::{AsyncReadExt, AsyncWriteExt, StreamExt};
|
use futures_lite::{AsyncReadExt, AsyncWriteExt, StreamExt};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use crate::{
|
|||||||
AssetLoadError, AssetLoader, AssetPath, DeserializeMetaError, ErasedLoadedAsset,
|
AssetLoadError, AssetLoader, AssetPath, DeserializeMetaError, ErasedLoadedAsset,
|
||||||
MissingAssetLoaderForExtensionError, MissingAssetLoaderForTypeNameError,
|
MissingAssetLoaderForExtensionError, MissingAssetLoaderForTypeNameError,
|
||||||
};
|
};
|
||||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture};
|
use bevy_tasks::{BoxedFuture, ConditionalSendFuture};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|||||||
@ -3,7 +3,8 @@ use crate::{
|
|||||||
ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle,
|
ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle,
|
||||||
};
|
};
|
||||||
use atomicow::CowArc;
|
use atomicow::CowArc;
|
||||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture, HashMap};
|
use bevy_tasks::{BoxedFuture, ConditionalSendFuture};
|
||||||
|
use bevy_utils::HashMap;
|
||||||
use core::{borrow::Borrow, hash::Hash, ops::Deref};
|
use core::{borrow::Borrow, hash::Hash, ops::Deref};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|||||||
@ -4,13 +4,12 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use async_broadcast::RecvError;
|
use async_broadcast::RecvError;
|
||||||
use bevy_tasks::IoTaskPool;
|
|
||||||
use bevy_utils::{tracing::warn, HashMap, TypeIdMap};
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
use bevy_utils::{
|
use bevy_tasks::ConditionalSendFuture;
|
||||||
tracing::{info_span, instrument::Instrument},
|
use bevy_tasks::IoTaskPool;
|
||||||
ConditionalSendFuture,
|
#[cfg(feature = "trace")]
|
||||||
};
|
use bevy_utils::tracing::{info_span, instrument::Instrument};
|
||||||
|
use bevy_utils::{tracing::warn, HashMap, TypeIdMap};
|
||||||
use core::any::TypeId;
|
use core::any::TypeId;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::{meta::Settings, Asset, ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle};
|
use crate::{meta::Settings, Asset, ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle};
|
||||||
use atomicow::CowArc;
|
use atomicow::CowArc;
|
||||||
use bevy_utils::{ConditionalSendFuture, HashMap};
|
use bevy_tasks::ConditionalSendFuture;
|
||||||
|
use bevy_utils::HashMap;
|
||||||
use core::{
|
use core::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
convert::Infallible,
|
convert::Infallible,
|
||||||
|
|||||||
@ -329,7 +329,7 @@ impl ShaderCache {
|
|||||||
// So to keep the complexity of the ShaderCache low, we will only catch this error early on native platforms,
|
// So to keep the complexity of the ShaderCache low, we will only catch this error early on native platforms,
|
||||||
// and on wasm the error will be handled by wgpu and crash the application.
|
// and on wasm the error will be handled by wgpu and crash the application.
|
||||||
if let Some(Some(wgpu::Error::Validation { description, .. })) =
|
if let Some(Some(wgpu::Error::Validation { description, .. })) =
|
||||||
bevy_utils::futures::now_or_never(error)
|
bevy_tasks::futures::now_or_never(error)
|
||||||
{
|
{
|
||||||
return Err(PipelineCacheError::CreateShaderModule(description));
|
return Err(PipelineCacheError::CreateShaderModule(description));
|
||||||
}
|
}
|
||||||
@ -874,7 +874,7 @@ impl PipelineCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CachedPipelineState::Creating(ref mut task) => {
|
CachedPipelineState::Creating(ref mut task) => {
|
||||||
match bevy_utils::futures::check_ready(task) {
|
match bevy_tasks::futures::check_ready(task) {
|
||||||
Some(Ok(pipeline)) => {
|
Some(Ok(pipeline)) => {
|
||||||
cached_pipeline.state = CachedPipelineState::Ok(pipeline);
|
cached_pipeline.state = CachedPipelineState::Ok(pipeline);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
#![expect(unsafe_code, reason = "Futures require unsafe code.")]
|
||||||
|
|
||||||
//! Utilities for working with [`Future`]s.
|
//! Utilities for working with [`Future`]s.
|
||||||
use core::{
|
use core::{
|
||||||
future::Future,
|
future::Future,
|
||||||
@ -8,6 +8,35 @@
|
|||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
mod conditional_send {
|
||||||
|
/// 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<T: Send> ConditionalSend for T {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[expect(missing_docs, reason = "Not all docs are written yet (#3492).")]
|
||||||
|
mod conditional_send {
|
||||||
|
pub trait ConditionalSend {}
|
||||||
|
impl<T> ConditionalSend for T {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use conditional_send::*;
|
||||||
|
|
||||||
|
/// Use [`ConditionalSendFuture`] for a future with an optional Send trait bound, as on certain platforms (eg. Wasm),
|
||||||
|
/// futures aren't Send.
|
||||||
|
pub trait ConditionalSendFuture: core::future::Future + ConditionalSend {}
|
||||||
|
impl<T: core::future::Future + ConditionalSend> ConditionalSendFuture for T {}
|
||||||
|
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
|
/// An owned and dynamically typed Future used when you can't statically type your result or need to add some indirection.
|
||||||
|
pub type BoxedFuture<'a, T> = core::pin::Pin<Box<dyn ConditionalSendFuture<Output = T> + 'a>>;
|
||||||
|
|
||||||
|
pub mod futures;
|
||||||
|
|
||||||
mod executor;
|
mod executor;
|
||||||
|
|
||||||
mod slice;
|
mod slice;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||||
#![expect(
|
#![expect(
|
||||||
unsafe_code,
|
unsafe_code,
|
||||||
reason = "Some utilities, such as futures and cells, require unsafe code."
|
reason = "Some utilities, such as cells, require unsafe code."
|
||||||
)]
|
)]
|
||||||
#![doc(
|
#![doc(
|
||||||
html_logo_url = "https://bevyengine.org/assets/icon.png",
|
html_logo_url = "https://bevyengine.org/assets/icon.png",
|
||||||
@ -23,7 +23,6 @@ pub mod prelude {
|
|||||||
pub use crate::default;
|
pub use crate::default;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod futures;
|
|
||||||
pub mod synccell;
|
pub mod synccell;
|
||||||
pub mod syncunsafecell;
|
pub mod syncunsafecell;
|
||||||
|
|
||||||
@ -64,9 +63,6 @@ pub use time::*;
|
|||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
pub use tracing;
|
pub use tracing;
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
use alloc::boxed::Box;
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use core::any::TypeId;
|
use core::any::TypeId;
|
||||||
use core::{
|
use core::{
|
||||||
@ -77,32 +73,6 @@ use core::{
|
|||||||
ops::Deref,
|
ops::Deref,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
mod conditional_send {
|
|
||||||
/// 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<T: Send> ConditionalSend for T {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
#[expect(missing_docs, reason = "Not all docs are written yet (#3492).")]
|
|
||||||
mod conditional_send {
|
|
||||||
pub trait ConditionalSend {}
|
|
||||||
impl<T> ConditionalSend for T {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use conditional_send::*;
|
|
||||||
|
|
||||||
/// Use [`ConditionalSendFuture`] for a future with an optional Send trait bound, as on certain platforms (eg. Wasm),
|
|
||||||
/// futures aren't Send.
|
|
||||||
pub trait ConditionalSendFuture: core::future::Future + ConditionalSend {}
|
|
||||||
impl<T: core::future::Future + ConditionalSend> ConditionalSendFuture for T {}
|
|
||||||
|
|
||||||
/// An owned and dynamically typed Future used when you can't statically type your result or need to add some indirection.
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
pub type BoxedFuture<'a, T> = core::pin::Pin<Box<dyn ConditionalSendFuture<Output = T> + 'a>>;
|
|
||||||
|
|
||||||
/// A shortcut alias for [`hashbrown::hash_map::Entry`].
|
/// A shortcut alias for [`hashbrown::hash_map::Entry`].
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub type Entry<'a, K, V, S = FixedHasher> = hashbrown::hash_map::Entry<'a, K, V, S>;
|
pub type Entry<'a, K, V, S = FixedHasher> = hashbrown::hash_map::Entry<'a, K, V, S>;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user