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::*;
 | 
			
		||||
 | 
			
		||||
use alloc::sync::Arc;
 | 
			
		||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture};
 | 
			
		||||
use bevy_tasks::{BoxedFuture, ConditionalSendFuture};
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
use core::{
 | 
			
		||||
    mem::size_of,
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,8 @@ use crate::{
 | 
			
		||||
};
 | 
			
		||||
use atomicow::CowArc;
 | 
			
		||||
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 downcast_rs::{impl_downcast, Downcast};
 | 
			
		||||
use ron::error::SpannedError;
 | 
			
		||||
 | 
			
		||||
@ -58,16 +58,15 @@ use crate::{
 | 
			
		||||
};
 | 
			
		||||
use alloc::{collections::VecDeque, sync::Arc};
 | 
			
		||||
use bevy_ecs::prelude::*;
 | 
			
		||||
#[cfg(feature = "trace")]
 | 
			
		||||
use bevy_tasks::ConditionalSendFuture;
 | 
			
		||||
use bevy_tasks::IoTaskPool;
 | 
			
		||||
#[cfg(feature = "trace")]
 | 
			
		||||
use bevy_utils::tracing::{info_span, instrument::Instrument};
 | 
			
		||||
use bevy_utils::{
 | 
			
		||||
    tracing::{debug, error, trace, warn},
 | 
			
		||||
    HashMap, HashSet,
 | 
			
		||||
};
 | 
			
		||||
#[cfg(feature = "trace")]
 | 
			
		||||
use bevy_utils::{
 | 
			
		||||
    tracing::{info_span, instrument::Instrument},
 | 
			
		||||
    ConditionalSendFuture,
 | 
			
		||||
};
 | 
			
		||||
use futures_io::ErrorKind;
 | 
			
		||||
use futures_lite::{AsyncReadExt, AsyncWriteExt, StreamExt};
 | 
			
		||||
use parking_lot::RwLock;
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ use crate::{
 | 
			
		||||
    AssetLoadError, AssetLoader, AssetPath, DeserializeMetaError, ErasedLoadedAsset,
 | 
			
		||||
    MissingAssetLoaderForExtensionError, MissingAssetLoaderForTypeNameError,
 | 
			
		||||
};
 | 
			
		||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture};
 | 
			
		||||
use bevy_tasks::{BoxedFuture, ConditionalSendFuture};
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
use thiserror::Error;
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,8 @@ use crate::{
 | 
			
		||||
    ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle,
 | 
			
		||||
};
 | 
			
		||||
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 serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,13 +4,12 @@ use crate::{
 | 
			
		||||
};
 | 
			
		||||
use alloc::sync::Arc;
 | 
			
		||||
use async_broadcast::RecvError;
 | 
			
		||||
use bevy_tasks::IoTaskPool;
 | 
			
		||||
use bevy_utils::{tracing::warn, HashMap, TypeIdMap};
 | 
			
		||||
#[cfg(feature = "trace")]
 | 
			
		||||
use bevy_utils::{
 | 
			
		||||
    tracing::{info_span, instrument::Instrument},
 | 
			
		||||
    ConditionalSendFuture,
 | 
			
		||||
};
 | 
			
		||||
use bevy_tasks::ConditionalSendFuture;
 | 
			
		||||
use bevy_tasks::IoTaskPool;
 | 
			
		||||
#[cfg(feature = "trace")]
 | 
			
		||||
use bevy_utils::tracing::{info_span, instrument::Instrument};
 | 
			
		||||
use bevy_utils::{tracing::warn, HashMap, TypeIdMap};
 | 
			
		||||
use core::any::TypeId;
 | 
			
		||||
use thiserror::Error;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
use crate::{meta::Settings, Asset, ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle};
 | 
			
		||||
use atomicow::CowArc;
 | 
			
		||||
use bevy_utils::{ConditionalSendFuture, HashMap};
 | 
			
		||||
use bevy_tasks::ConditionalSendFuture;
 | 
			
		||||
use bevy_utils::HashMap;
 | 
			
		||||
use core::{
 | 
			
		||||
    borrow::Borrow,
 | 
			
		||||
    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,
 | 
			
		||||
                // and on wasm the error will be handled by wgpu and crash the application.
 | 
			
		||||
                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));
 | 
			
		||||
                }
 | 
			
		||||
@ -874,7 +874,7 @@ impl PipelineCache {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            CachedPipelineState::Creating(ref mut task) => {
 | 
			
		||||
                match bevy_utils::futures::check_ready(task) {
 | 
			
		||||
                match bevy_tasks::futures::check_ready(task) {
 | 
			
		||||
                    Some(Ok(pipeline)) => {
 | 
			
		||||
                        cached_pipeline.state = CachedPipelineState::Ok(pipeline);
 | 
			
		||||
                        return;
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
#![expect(unsafe_code, reason = "Futures require unsafe code.")]
 | 
			
		||||
 | 
			
		||||
//! Utilities for working with [`Future`]s.
 | 
			
		||||
use core::{
 | 
			
		||||
    future::Future,
 | 
			
		||||
@ -8,6 +8,35 @@
 | 
			
		||||
 | 
			
		||||
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 slice;
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
 | 
			
		||||
#![expect(
 | 
			
		||||
    unsafe_code,
 | 
			
		||||
    reason = "Some utilities, such as futures and cells, require unsafe code."
 | 
			
		||||
    reason = "Some utilities, such as cells, require unsafe code."
 | 
			
		||||
)]
 | 
			
		||||
#![doc(
 | 
			
		||||
    html_logo_url = "https://bevyengine.org/assets/icon.png",
 | 
			
		||||
@ -23,7 +23,6 @@ pub mod prelude {
 | 
			
		||||
    pub use crate::default;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub mod futures;
 | 
			
		||||
pub mod synccell;
 | 
			
		||||
pub mod syncunsafecell;
 | 
			
		||||
 | 
			
		||||
@ -64,9 +63,6 @@ pub use time::*;
 | 
			
		||||
#[cfg(feature = "tracing")]
 | 
			
		||||
pub use tracing;
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "alloc")]
 | 
			
		||||
use alloc::boxed::Box;
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "alloc")]
 | 
			
		||||
use core::any::TypeId;
 | 
			
		||||
use core::{
 | 
			
		||||
@ -77,32 +73,6 @@ use core::{
 | 
			
		||||
    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`].
 | 
			
		||||
#[cfg(feature = "alloc")]
 | 
			
		||||
pub type Entry<'a, K, V, S = FixedHasher> = hashbrown::hash_map::Entry<'a, K, V, S>;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user