mirror of
https://github.com/bevyengine/bevy
synced 2024-11-27 23:20:20 +00:00
Allow bevy_utils
in no_std
Contexts (#15279)
# Objective - Adjust `bevy_utils` to make it `no_std` compatible - Partially replaces #6581 - Contributes to #8161 - Contributes to #6370 ## Solution Added `alloc` and `std` features to `bevy_utils` (`std` is enabled by default), allowing the crate's use in `no_std` contexts. ## Testing - CI passed locally. - Used `bevy_utils` in a `no_std` crate as an experiment and compiled successfully. ## Migration Guide If you were importing `bevy_utils` and setting `default_features` to `false`, but relying on elements which are now gated behind the `std` or `alloc` features, include the relevant feature in your `Cargo.toml`. ## Notes - Bevy already includes a single `no_std` crate, `bevy_ptr`, so there is precedent for this change. - As `bevy_utils` is widely used across the rest of Bevy, further work to make Bevy `no_std` compatible would be blocked on this crate, if such work was to be undertaken. - Most of the changes in this PR are just the removal of an unnecessary call to `to_string()` within unit tests.
This commit is contained in:
parent
b1273d48cb
commit
bd489068c6
6 changed files with 50 additions and 35 deletions
|
@ -9,11 +9,16 @@ license = "MIT OR Apache-2.0"
|
|||
keywords = ["bevy"]
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = ["alloc", "tracing/std", "ahash/std"]
|
||||
alloc = []
|
||||
detailed_trace = []
|
||||
|
||||
[dependencies]
|
||||
ahash = "0.8.7"
|
||||
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
||||
ahash = { version = "0.8.7", default-features = false, features = [
|
||||
"runtime-rng",
|
||||
] }
|
||||
tracing = { version = "0.1", default-features = false }
|
||||
web-time = { version = "1.1" }
|
||||
hashbrown = { version = "0.14.2", features = ["serde"] }
|
||||
bevy_utils_proc_macros = { version = "0.15.0-dev", path = "macros" }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//! Utilities for working with [`Future`]s.
|
||||
use std::{
|
||||
use core::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||
|
@ -44,7 +44,7 @@ fn noop(_data: *const ()) {}
|
|||
const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
|
||||
|
||||
fn noop_raw_waker() -> RawWaker {
|
||||
RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE)
|
||||
RawWaker::new(core::ptr::null(), &NOOP_WAKER_VTABLE)
|
||||
}
|
||||
|
||||
fn noop_waker() -> Waker {
|
||||
|
|
|
@ -4,12 +4,16 @@
|
|||
html_logo_url = "https://bevyengine.org/assets/icon.png",
|
||||
html_favicon_url = "https://bevyengine.org/assets/icon.png"
|
||||
)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
//! General utilities for first-party [Bevy] engine crates.
|
||||
//!
|
||||
//! [Bevy]: https://bevyengine.org/
|
||||
//!
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
|
||||
/// The utilities prelude.
|
||||
///
|
||||
/// This includes the most common types in this crate, re-exported for your convenience.
|
||||
|
@ -18,7 +22,9 @@ pub mod prelude {
|
|||
}
|
||||
|
||||
pub mod futures;
|
||||
#[cfg(feature = "alloc")]
|
||||
mod short_names;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub use short_names::get_short_name;
|
||||
pub mod synccell;
|
||||
pub mod syncunsafecell;
|
||||
|
@ -37,8 +43,10 @@ pub use parallel_queue::*;
|
|||
pub use tracing;
|
||||
pub use web_time::{Duration, Instant, SystemTime, SystemTimeError, TryFromFloatSecsError};
|
||||
|
||||
use hashbrown::hash_map::RawEntryMut;
|
||||
use std::{
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use core::{
|
||||
any::TypeId,
|
||||
fmt::Debug,
|
||||
hash::{BuildHasher, BuildHasherDefault, Hash, Hasher},
|
||||
|
@ -46,6 +54,7 @@ use std::{
|
|||
mem::ManuallyDrop,
|
||||
ops::Deref,
|
||||
};
|
||||
use hashbrown::hash_map::RawEntryMut;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod conditional_send {
|
||||
|
@ -66,11 +75,12 @@ 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: std::future::Future + ConditionalSend {}
|
||||
impl<T: std::future::Future + ConditionalSend> ConditionalSendFuture for T {}
|
||||
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.
|
||||
pub type BoxedFuture<'a, T> = std::pin::Pin<Box<dyn ConditionalSendFuture<Output = T> + 'a>>;
|
||||
#[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`].
|
||||
pub type Entry<'a, K, V, S = BuildHasherDefault<AHasher>> = hashbrown::hash_map::Entry<'a, K, V, S>;
|
||||
|
@ -192,7 +202,7 @@ impl<V: PartialEq, H> PartialEq for Hashed<V, H> {
|
|||
}
|
||||
|
||||
impl<V: Debug, H> Debug for Hashed<V, H> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("Hashed")
|
||||
.field("hash", &self.hash)
|
||||
.field("value", &self.value)
|
||||
|
@ -417,7 +427,7 @@ mod tests {
|
|||
fn fast_typeid_hash() {
|
||||
struct Hasher;
|
||||
|
||||
impl std::hash::Hasher for Hasher {
|
||||
impl core::hash::Hasher for Hasher {
|
||||
fn finish(&self) -> u64 {
|
||||
0
|
||||
}
|
||||
|
@ -430,8 +440,11 @@ mod tests {
|
|||
Hash::hash(&TypeId::of::<()>(), &mut Hasher);
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn stable_hash_within_same_program_execution() {
|
||||
use alloc::vec::Vec;
|
||||
|
||||
let mut map_1 = HashMap::new();
|
||||
let mut map_2 = HashMap::new();
|
||||
for i in 1..10 {
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use std::{cell::RefCell, ops::DerefMut};
|
||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use core::{cell::RefCell, ops::DerefMut};
|
||||
use thread_local::ThreadLocal;
|
||||
|
||||
/// A cohesive set of thread-local values of a given type.
|
||||
|
@ -56,6 +59,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl<T: Send> Parallel<Vec<T>> {
|
||||
/// Collect all enqueued items from all threads and appends them to the end of a
|
||||
/// single Vec.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use alloc::string::String;
|
||||
|
||||
/// Shortens a type name to remove all module paths.
|
||||
///
|
||||
/// The short name of a type is its full name as returned by
|
||||
|
@ -88,43 +90,37 @@ mod name_formatting_tests {
|
|||
fn path_separated() {
|
||||
assert_eq!(
|
||||
get_short_name("bevy_prelude::make_fun_game"),
|
||||
"make_fun_game".to_string()
|
||||
"make_fun_game"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_type() {
|
||||
assert_eq!(
|
||||
get_short_name("(String, String)"),
|
||||
"(String, String)".to_string()
|
||||
);
|
||||
assert_eq!(get_short_name("(String, String)"), "(String, String)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_type() {
|
||||
assert_eq!(get_short_name("[i32; 3]"), "[i32; 3]".to_string());
|
||||
assert_eq!(get_short_name("[i32; 3]"), "[i32; 3]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trivial_generics() {
|
||||
assert_eq!(get_short_name("a<B>"), "a<B>".to_string());
|
||||
assert_eq!(get_short_name("a<B>"), "a<B>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_type_parameters() {
|
||||
assert_eq!(get_short_name("a<B, C>"), "a<B, C>".to_string());
|
||||
assert_eq!(get_short_name("a<B, C>"), "a<B, C>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enums() {
|
||||
assert_eq!(get_short_name("Option::None"), "Option::None".to_string());
|
||||
assert_eq!(
|
||||
get_short_name("Option::Some(2)"),
|
||||
"Option::Some(2)".to_string()
|
||||
);
|
||||
assert_eq!(get_short_name("Option::None"), "Option::None");
|
||||
assert_eq!(get_short_name("Option::Some(2)"), "Option::Some(2)");
|
||||
assert_eq!(
|
||||
get_short_name("bevy_render::RenderSet::Prepare"),
|
||||
"RenderSet::Prepare".to_string()
|
||||
"RenderSet::Prepare"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -132,7 +128,7 @@ mod name_formatting_tests {
|
|||
fn generics() {
|
||||
assert_eq!(
|
||||
get_short_name("bevy_render::camera::camera::extract_cameras<bevy_render::camera::bundle::Camera3d>"),
|
||||
"extract_cameras<Camera3d>".to_string()
|
||||
"extract_cameras<Camera3d>"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -140,7 +136,7 @@ mod name_formatting_tests {
|
|||
fn nested_generics() {
|
||||
assert_eq!(
|
||||
get_short_name("bevy::mad_science::do_mad_science<mad_science::Test<mad_science::Tube>, bavy::TypeSystemAbuse>"),
|
||||
"do_mad_science<Test<Tube>, TypeSystemAbuse>".to_string()
|
||||
"do_mad_science<Test<Tube>, TypeSystemAbuse>"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -148,15 +144,12 @@ mod name_formatting_tests {
|
|||
fn sub_path_after_closing_bracket() {
|
||||
assert_eq!(
|
||||
get_short_name("bevy_asset::assets::Assets<bevy_scene::dynamic_scene::DynamicScene>::asset_event_system"),
|
||||
"Assets<DynamicScene>::asset_event_system".to_string()
|
||||
"Assets<DynamicScene>::asset_event_system"
|
||||
);
|
||||
assert_eq!(
|
||||
get_short_name("(String, String)::default"),
|
||||
"(String, String)::default".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
get_short_name("[i32; 16]::default"),
|
||||
"[i32; 16]::default".to_string()
|
||||
"(String, String)::default"
|
||||
);
|
||||
assert_eq!(get_short_name("[i32; 16]::default"), "[i32; 16]::default");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//!
|
||||
//! [`std::sync::Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
|
||||
|
||||
use std::ptr;
|
||||
use core::ptr;
|
||||
|
||||
/// See [`Exclusive`](https://github.com/rust-lang/rust/issues/98407) for stdlib's upcoming implementation,
|
||||
/// which should replace this one entirely.
|
||||
|
|
Loading…
Reference in a new issue