Add no_std support to bevy (#17955)

# Objective

- Fixes #15460 (will open new issues for further `no_std` efforts)
- Supersedes #17715

## Solution

- Threaded in new features as required
- Made certain crates optional but default enabled
- Removed `compile-check-no-std` from internal `ci` tool since GitHub CI
can now simply check `bevy` itself now
- Added CI task to check `bevy` on `thumbv6m-none-eabi` to ensure
`portable-atomic` support is still valid [^1]

[^1]: This may be controversial, since it could be interpreted as
implying Bevy will maintain support for `thumbv6m-none-eabi` going
forward. In reality, just like `x86_64-unknown-none`, this is a
[canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine) target to
make it clear when `portable-atomic` no longer works as intended (fixing
atomic support on atomically challenged platforms). If a PR comes
through and makes supporting this class of platforms impossible, then
this CI task can be removed. I however wager this won't be a problem.

## Testing

- CI

---

## Release Notes

Bevy now has support for `no_std` directly from the `bevy` crate.

Users can disable default features and enable a new `default_no_std`
feature instead, allowing `bevy` to be used in `no_std` applications and
libraries.

```toml
# Bevy for `no_std` platforms
bevy = { version = "0.16", default-features = false, features = ["default_no_std"] }
```

`default_no_std` enables certain required features, such as `libm` and
`critical-section`, and as many optional crates as possible (currently
just `bevy_state`). For atomically-challenged platforms such as the
Raspberry Pi Pico, `portable-atomic` will be used automatically.

For library authors, we recommend depending on `bevy` with
`default-features = false` to allow `std` and `no_std` users to both
depend on your crate. Here are some recommended features a library crate
may want to expose:

```toml
[features]
# Most users will be on a platform which has `std` and can use the more-powerful `async_executor`.
default = ["std", "async_executor"]

# Features for typical platforms.
std = ["bevy/std"]
async_executor = ["bevy/async_executor"]

# Features for `no_std` platforms.
libm = ["bevy/libm"]
critical-section = ["bevy/critical-section"]

[dependencies]
# We disable default features to ensure we don't accidentally enable `std` on `no_std` targets, for example. 
bevy = { version = "0.16", default-features = false }
```

While this is verbose, it gives the maximum control to end-users to
decide how they wish to use Bevy on their platform.

We encourage library authors to experiment with `no_std` support. For
libraries relying exclusively on `bevy` and no other dependencies, it
may be as simple as adding `#![no_std]` to your `lib.rs` and exposing
features as above! Bevy can also provide many `std` types, such as
`HashMap`, `Mutex`, and `Instant` on all platforms. See
`bevy::platform_support` for details on what's available out of the box!

## Migration Guide

- If you were previously relying on `bevy` with default features
disabled, you may need to enable the `std` and `async_executor`
features.
- `bevy_reflect` has had its `bevy` feature removed. If you were relying
on this feature, simply enable `smallvec` and `smol_str` instead.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
Zachary Harrold 2025-03-07 14:39:46 +11:00 committed by GitHub
parent 5bc1d68a65
commit cc69fdd0c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 903 additions and 363 deletions

View File

@ -151,7 +151,31 @@ jobs:
- name: Install Linux dependencies - name: Install Linux dependencies
uses: ./.github/actions/install-linux-deps uses: ./.github/actions/install-linux-deps
- name: Check Compile - name: Check Compile
run: cargo run -p ci -- compile-check-no-std run: cargo check -p bevy --no-default-features --features default_no_std --target x86_64-unknown-none
check-compiles-no-std-portable-atomic:
runs-on: ubuntu-latest
timeout-minutes: 30
needs: ci
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
crates/bevy_ecs_compile_fail_tests/target/
crates/bevy_reflect_compile_fail_tests/target/
key: ${{ runner.os }}-cargo-check-compiles-no-std-portable-atomic-${{ hashFiles('**/Cargo.toml') }}
- uses: dtolnay/rust-toolchain@stable
with:
targets: thumbv6m-none-eabi
- name: Install Linux dependencies
uses: ./.github/actions/install-linux-deps
- name: Check Compile
run: cargo check -p bevy --no-default-features --features default_no_std --target thumbv6m-none-eabi
build-wasm: build-wasm:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -120,6 +120,8 @@ unused_qualifications = "warn"
[features] [features]
default = [ default = [
"std",
"async_executor",
"android-game-activity", "android-game-activity",
"android_shared_stdcxx", "android_shared_stdcxx",
"animation", "animation",
@ -130,6 +132,8 @@ default = [
"bevy_gilrs", "bevy_gilrs",
"bevy_gizmos", "bevy_gizmos",
"bevy_gltf", "bevy_gltf",
"bevy_input_focus",
"bevy_log",
"bevy_mesh_picking_backend", "bevy_mesh_picking_backend",
"bevy_pbr", "bevy_pbr",
"bevy_picking", "bevy_picking",
@ -156,6 +160,9 @@ default = [
"x11", "x11",
] ]
# Recommended defaults for no_std applications
default_no_std = ["libm", "critical-section", "bevy_color", "bevy_state"]
# Provides an implementation for picking meshes # Provides an implementation for picking meshes
bevy_mesh_picking_backend = [ bevy_mesh_picking_backend = [
"bevy_picking", "bevy_picking",
@ -263,6 +270,12 @@ bevy_dev_tools = ["bevy_internal/bevy_dev_tools"]
# Enable the Bevy Remote Protocol # Enable the Bevy Remote Protocol
bevy_remote = ["bevy_internal/bevy_remote"] bevy_remote = ["bevy_internal/bevy_remote"]
# Enable integration with `tracing` and `log`
bevy_log = ["bevy_internal/bevy_log"]
# Enable input focus subsystem
bevy_input_focus = ["bevy_internal/bevy_input_focus"]
# Enable passthrough loading for SPIR-V shaders (Only supported on Vulkan, shader capabilities and extensions must agree with the platform implementation) # Enable passthrough loading for SPIR-V shaders (Only supported on Vulkan, shader capabilities and extensions must agree with the platform implementation)
spirv_shader_passthrough = ["bevy_internal/spirv_shader_passthrough"] spirv_shader_passthrough = ["bevy_internal/spirv_shader_passthrough"]
@ -488,6 +501,18 @@ custom_cursor = ["bevy_internal/custom_cursor"]
# Experimental support for nodes that are ignored for UI layouting # Experimental support for nodes that are ignored for UI layouting
ghost_nodes = ["bevy_internal/ghost_nodes"] ghost_nodes = ["bevy_internal/ghost_nodes"]
# Uses `async-executor` as a task execution backend.
async_executor = ["std", "bevy_internal/async_executor"]
# Allows access to the `std` crate.
std = ["bevy_internal/std"]
# `critical-section` provides the building blocks for synchronization primitives on all platforms, including `no_std`.
critical-section = ["bevy_internal/critical-section"]
# Uses the `libm` maths library instead of the one provided in `std` and `core`.
libm = ["bevy_internal/libm"]
[dependencies] [dependencies]
bevy_internal = { path = "crates/bevy_internal", version = "0.16.0-dev", default-features = false } bevy_internal = { path = "crates/bevy_internal", version = "0.16.0-dev", default-features = false }
tracing = { version = "0.1", default-features = false, optional = true } tracing = { version = "0.1", default-features = false, optional = true }

View File

@ -17,7 +17,6 @@ bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" }
bevy_log = { path = "../bevy_log", version = "0.16.0-dev" } bevy_log = { path = "../bevy_log", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [
"bevy",
"petgraph", "petgraph",
] } ] }
bevy_render = { path = "../bevy_render", version = "0.16.0-dev" } bevy_render = { path = "../bevy_render", version = "0.16.0-dev" }

View File

@ -9,13 +9,7 @@ license = "MIT OR Apache-2.0"
keywords = ["bevy"] keywords = ["bevy"]
[features] [features]
default = [ default = ["std", "bevy_reflect", "bevy_ecs/default", "error_panic_hook"]
"std",
"bevy_reflect",
"bevy_tasks",
"bevy_ecs/default",
"error_panic_hook",
]
# Functionality # Functionality
@ -29,9 +23,6 @@ reflect_functions = [
"bevy_ecs/reflect_functions", "bevy_ecs/reflect_functions",
] ]
## Adds support for running async background tasks
bevy_tasks = ["dep:bevy_tasks"]
# Debugging Features # Debugging Features
## Enables `tracing` integration, allowing spans and other metrics to be reported ## Enables `tracing` integration, allowing spans and other metrics to be reported
@ -57,14 +48,14 @@ std = [
"dep:ctrlc", "dep:ctrlc",
"downcast-rs/std", "downcast-rs/std",
"bevy_utils/std", "bevy_utils/std",
"bevy_tasks?/std", "bevy_tasks/std",
"bevy_platform_support/std", "bevy_platform_support/std",
] ]
## `critical-section` provides the building blocks for synchronization primitives ## `critical-section` provides the building blocks for synchronization primitives
## on all platforms, including `no_std`. ## on all platforms, including `no_std`.
critical-section = [ critical-section = [
"bevy_tasks?/critical-section", "bevy_tasks/critical-section",
"bevy_ecs/critical-section", "bevy_ecs/critical-section",
"bevy_platform_support/critical-section", "bevy_platform_support/critical-section",
"bevy_reflect?/critical-section", "bevy_reflect?/critical-section",
@ -78,7 +69,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-featu
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [ bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [
"alloc", "alloc",
] } ] }
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, optional = true } bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false } bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false }
# other # other

View File

@ -1353,7 +1353,7 @@ type RunnerFn = Box<dyn FnOnce(App) -> AppExit>;
fn run_once(mut app: App) -> AppExit { fn run_once(mut app: App) -> AppExit {
while app.plugins_state() == PluginsState::Adding { while app.plugins_state() == PluginsState::Adding {
#[cfg(all(not(target_arch = "wasm32"), feature = "bevy_tasks"))] #[cfg(not(target_arch = "wasm32"))]
bevy_tasks::tick_global_task_pools_on_main_thread(); bevy_tasks::tick_global_task_pools_on_main_thread();
} }
app.finish(); app.finish();

View File

@ -30,7 +30,6 @@ mod plugin;
mod plugin_group; mod plugin_group;
mod schedule_runner; mod schedule_runner;
mod sub_app; mod sub_app;
#[cfg(feature = "bevy_tasks")]
mod task_pool_plugin; mod task_pool_plugin;
#[cfg(all(any(unix, windows), feature = "std"))] #[cfg(all(any(unix, windows), feature = "std"))]
mod terminal_ctrl_c_handler; mod terminal_ctrl_c_handler;
@ -42,7 +41,6 @@ pub use plugin::*;
pub use plugin_group::*; pub use plugin_group::*;
pub use schedule_runner::*; pub use schedule_runner::*;
pub use sub_app::*; pub use sub_app::*;
#[cfg(feature = "bevy_tasks")]
pub use task_pool_plugin::*; pub use task_pool_plugin::*;
#[cfg(all(any(unix, windows), feature = "std"))] #[cfg(all(any(unix, windows), feature = "std"))]
pub use terminal_ctrl_c_handler::*; pub use terminal_ctrl_c_handler::*;
@ -60,10 +58,6 @@ pub mod prelude {
RunFixedMainLoopSystem, SpawnScene, Startup, Update, RunFixedMainLoopSystem, SpawnScene, Startup, Update,
}, },
sub_app::SubApp, sub_app::SubApp,
Plugin, PluginGroup, NonSendMarker, Plugin, PluginGroup, TaskPoolOptions, TaskPoolPlugin,
}; };
#[cfg(feature = "bevy_tasks")]
#[doc(hidden)]
pub use crate::{NonSendMarker, TaskPoolOptions, TaskPoolPlugin};
} }

View File

@ -77,7 +77,7 @@ impl Plugin for ScheduleRunnerPlugin {
let plugins_state = app.plugins_state(); let plugins_state = app.plugins_state();
if plugins_state != PluginsState::Cleaned { if plugins_state != PluginsState::Cleaned {
while app.plugins_state() == PluginsState::Adding { while app.plugins_state() == PluginsState::Adding {
#[cfg(all(not(target_arch = "wasm32"), feature = "bevy_tasks"))] #[cfg(not(target_arch = "wasm32"))]
bevy_tasks::tick_global_task_pools_on_main_thread(); bevy_tasks::tick_global_task_pools_on_main_thread();
} }
app.finish(); app.finish();

View File

@ -14,9 +14,7 @@ bevy_app = { path = "../bevy_app", version = "0.16.0-dev" }
bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" } bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" }

View File

@ -26,7 +26,7 @@ serialize = [
dynamic_linking = [] dynamic_linking = []
## Adds integration with `sysinfo`. ## Adds integration with `sysinfo`.
sysinfo_plugin = ["sysinfo", "dep:bevy_tasks"] sysinfo_plugin = ["sysinfo"]
# Platform Compatibility # Platform Compatibility
@ -40,7 +40,7 @@ std = [
"bevy_platform_support/std", "bevy_platform_support/std",
"bevy_time/std", "bevy_time/std",
"bevy_utils/std", "bevy_utils/std",
"bevy_tasks?/std", "bevy_tasks/std",
] ]
## `critical-section` provides the building blocks for synchronization primitives ## `critical-section` provides the building blocks for synchronization primitives
@ -51,7 +51,7 @@ critical-section = [
"bevy_platform_support/critical-section", "bevy_platform_support/critical-section",
"bevy_time/critical-section", "bevy_time/critical-section",
"bevy_utils/critical-section", "bevy_utils/critical-section",
"bevy_tasks?/critical-section", "bevy_tasks/critical-section",
] ]
[dependencies] [dependencies]
@ -62,7 +62,7 @@ bevy_time = { path = "../bevy_time", version = "0.16.0-dev", default-features =
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [ bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [
"alloc", "alloc",
] } ] }
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, optional = true } bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [ bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [
"alloc", "alloc",
] } ] }

View File

@ -60,11 +60,7 @@ track_location = []
## Uses `async-executor` as a task execution backend. ## Uses `async-executor` as a task execution backend.
## This backend is incompatible with `no_std` targets. ## This backend is incompatible with `no_std` targets.
async_executor = ["dep:bevy_tasks", "std", "bevy_tasks/async_executor"] async_executor = ["std", "bevy_tasks/async_executor"]
## Uses `edge-executor` as a task execution backend.
## Use this instead of `async-executor` if working on a `no_std` target.
edge_executor = ["dep:bevy_tasks", "bevy_tasks/edge_executor"]
# Platform Compatibility # Platform Compatibility
@ -90,7 +86,7 @@ std = [
## `critical-section` provides the building blocks for synchronization primitives ## `critical-section` provides the building blocks for synchronization primitives
## on all platforms, including `no_std`. ## on all platforms, including `no_std`.
critical-section = [ critical-section = [
"bevy_tasks?/critical-section", "bevy_tasks/critical-section",
"bevy_platform_support/critical-section", "bevy_platform_support/critical-section",
"bevy_reflect?/critical-section", "bevy_reflect?/critical-section",
] ]
@ -100,7 +96,7 @@ bevy_ptr = { path = "../bevy_ptr", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [
"smallvec", "smallvec",
], default-features = false, optional = true } ], default-features = false, optional = true }
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, optional = true } bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false }
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [ bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [
"alloc", "alloc",
] } ] }

View File

@ -13,10 +13,11 @@ use alloc::{
boxed::Box, boxed::Box,
collections::{BTreeSet, BinaryHeap, LinkedList, VecDeque}, collections::{BTreeSet, BinaryHeap, LinkedList, VecDeque},
rc::Rc, rc::Rc,
sync::Arc,
vec::Vec, vec::Vec,
}; };
use bevy_platform_support::sync::Arc;
use super::{unique_slice, TrustedEntityBorrow, UniqueEntityIter, UniqueEntitySlice}; use super::{unique_slice, TrustedEntityBorrow, UniqueEntityIter, UniqueEntitySlice};
/// An array that contains only unique entities. /// An array that contains only unique entities.
@ -73,9 +74,9 @@ impl<T: TrustedEntityBorrow, const N: usize> UniqueEntityArray<T, N> {
} }
/// Casts `self` to the inner array. /// Casts `self` to the inner array.
pub fn into_arc_inner(self: Arc<Self>) -> Arc<[T; N]> { pub fn into_arc_inner(this: Arc<Self>) -> Arc<[T; N]> {
// SAFETY: UniqueEntityArray is a transparent wrapper around [T; N]. // SAFETY: UniqueEntityArray is a transparent wrapper around [T; N].
unsafe { Arc::from_raw(Arc::into_raw(self).cast()) } unsafe { Arc::from_raw(Arc::into_raw(this).cast()) }
} }
// Constructs a `Rc<UniqueEntityArray>` from a [`Rc<[T; N]>`] unsafely. // Constructs a `Rc<UniqueEntityArray>` from a [`Rc<[T; N]>`] unsafely.

View File

@ -17,10 +17,11 @@ use alloc::{
boxed::Box, boxed::Box,
collections::VecDeque, collections::VecDeque,
rc::Rc, rc::Rc,
sync::Arc,
vec::Vec, vec::Vec,
}; };
use bevy_platform_support::sync::Arc;
use super::{ use super::{
unique_vec, EntitySet, EntitySetIterator, FromEntitySetIterator, TrustedEntityBorrow, unique_vec, EntitySet, EntitySetIterator, FromEntitySetIterator, TrustedEntityBorrow,
UniqueEntityArray, UniqueEntityIter, UniqueEntityVec, UniqueEntityArray, UniqueEntityIter, UniqueEntityVec,
@ -86,9 +87,9 @@ impl<T: TrustedEntityBorrow> UniqueEntitySlice<T> {
} }
/// Casts `self` to the inner slice. /// Casts `self` to the inner slice.
pub fn into_arc_inner(self: Arc<Self>) -> Arc<[T]> { pub fn into_arc_inner(this: Arc<Self>) -> Arc<[T]> {
// SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. // SAFETY: UniqueEntitySlice is a transparent wrapper around [T].
unsafe { Arc::from_raw(Arc::into_raw(self) as *mut [T]) } unsafe { Arc::from_raw(Arc::into_raw(this) as *mut [T]) }
} }
// Constructs a `UniqueEntitySlice` from a [`Rc<[T]>`] unsafely. // Constructs a `UniqueEntitySlice` from a [`Rc<[T]>`] unsafely.

View File

@ -12,10 +12,11 @@ use alloc::{
boxed::Box, boxed::Box,
collections::{BTreeSet, BinaryHeap, TryReserveError, VecDeque}, collections::{BTreeSet, BinaryHeap, TryReserveError, VecDeque},
rc::Rc, rc::Rc,
sync::Arc,
vec::{self, Vec}, vec::{self, Vec},
}; };
use bevy_platform_support::sync::Arc;
use super::{ use super::{
unique_slice, EntitySet, FromEntitySetIterator, TrustedEntityBorrow, UniqueEntityArray, unique_slice, EntitySet, FromEntitySetIterator, TrustedEntityBorrow, UniqueEntityArray,
UniqueEntityIter, UniqueEntitySlice, UniqueEntityIter, UniqueEntitySlice,

View File

@ -28,9 +28,7 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.16.0-dev" } bevy_image = { path = "../bevy_image", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_pbr = { path = "../bevy_pbr", version = "0.16.0-dev" } bevy_pbr = { path = "../bevy_pbr", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_render = { path = "../bevy_render", version = "0.16.0-dev" } bevy_render = { path = "../bevy_render", version = "0.16.0-dev" }
bevy_scene = { path = "../bevy_scene", version = "0.16.0-dev", features = [ bevy_scene = { path = "../bevy_scene", version = "0.16.0-dev", features = [
"bevy_render", "bevy_render",

View File

@ -49,9 +49,7 @@ bevy_color = { path = "../bevy_color", version = "0.16.0-dev", features = [
"wgpu-types", "wgpu-types",
] } ] }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", optional = true }
"bevy",
], optional = true }
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [ bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [
"std", "std",

View File

@ -90,6 +90,7 @@ shader_format_glsl = [
shader_format_spirv = ["bevy_render/shader_format_spirv"] shader_format_spirv = ["bevy_render/shader_format_spirv"]
serialize = [ serialize = [
"bevy_a11y?/serialize",
"bevy_color?/serialize", "bevy_color?/serialize",
"bevy_ecs/serialize", "bevy_ecs/serialize",
"bevy_image?/serialize", "bevy_image?/serialize",
@ -104,12 +105,13 @@ serialize = [
"bevy_platform_support/serialize", "bevy_platform_support/serialize",
] ]
multi_threaded = [ multi_threaded = [
"std",
"bevy_asset?/multi_threaded", "bevy_asset?/multi_threaded",
"bevy_ecs/multi_threaded", "bevy_ecs/multi_threaded",
"bevy_render?/multi_threaded", "bevy_render?/multi_threaded",
"bevy_tasks/multi_threaded", "bevy_tasks/multi_threaded",
] ]
async-io = ["bevy_tasks/async-io"] async-io = ["std", "bevy_tasks/async-io"]
# Display server protocol support (X11 is enabled by default) # Display server protocol support (X11 is enabled by default)
wayland = ["bevy_winit/wayland"] wayland = ["bevy_winit/wayland"]
@ -195,6 +197,8 @@ bevy_render = [
"bevy_scene?/bevy_render", "bevy_scene?/bevy_render",
"bevy_gizmos?/bevy_render", "bevy_gizmos?/bevy_render",
"bevy_image", "bevy_image",
"bevy_color/wgpu-types",
"bevy_color/encase",
] ]
# Enable assertions to check the validity of parameters passed to glam # Enable assertions to check the validity of parameters passed to glam
@ -275,49 +279,133 @@ custom_cursor = ["bevy_winit/custom_cursor"]
# Experimental support for nodes that are ignored for UI layouting # Experimental support for nodes that are ignored for UI layouting
ghost_nodes = ["bevy_ui/ghost_nodes"] ghost_nodes = ["bevy_ui/ghost_nodes"]
# Allows access to the `std` crate. Enabling this feature will prevent compilation
# on `no_std` targets, but provides access to certain additional features on
# supported platforms.
std = [
"bevy_a11y?/std",
"bevy_app/std",
"bevy_color?/std",
"bevy_diagnostic/std",
"bevy_ecs/std",
"bevy_input/std",
"bevy_input_focus?/std",
"bevy_math/std",
"bevy_platform_support/std",
"bevy_reflect/std",
"bevy_state?/std",
"bevy_time/std",
"bevy_transform/std",
"bevy_utils/std",
"bevy_tasks/std",
"bevy_window?/std",
]
# `critical-section` provides the building blocks for synchronization primitives
# on all platforms, including `no_std`.
critical-section = [
"bevy_a11y?/critical-section",
"bevy_app/critical-section",
"bevy_diagnostic/critical-section",
"bevy_ecs/critical-section",
"bevy_input/critical-section",
"bevy_input_focus?/critical-section",
"bevy_platform_support/critical-section",
"bevy_reflect/critical-section",
"bevy_state?/critical-section",
"bevy_time/critical-section",
"bevy_utils/critical-section",
"bevy_tasks/critical-section",
]
# Uses the `libm` maths library instead of the one provided in `std` and `core`.
libm = [
"bevy_a11y?/libm",
"bevy_color?/libm",
"bevy_input/libm",
"bevy_input_focus?/libm",
"bevy_math/libm",
"bevy_transform/libm",
"bevy_window?/libm",
]
# Uses `async-executor` as a task execution backend.
# This backend is incompatible with `no_std` targets.
async_executor = ["std", "bevy_tasks/async_executor", "bevy_ecs/async_executor"]
[dependencies] [dependencies]
# bevy # bevy (no_std)
bevy_a11y = { path = "../bevy_a11y", version = "0.16.0-dev", optional = true } bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = false, features = [
bevy_app = { path = "../bevy_app", version = "0.16.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" }
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.16.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_state = { path = "../bevy_state", optional = true, version = "0.16.0-dev" }
bevy_input = { path = "../bevy_input", version = "0.16.0-dev" }
bevy_input_focus = { path = "../bevy_input_focus", version = "0.16.0-dev" }
bevy_log = { path = "../bevy_log", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev", features = [
"bevy_reflect", "bevy_reflect",
] } ] }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev" } bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev", default-features = false }
bevy_ptr = { path = "../bevy_ptr", version = "0.16.0-dev" } bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.16.0-dev", default-features = false }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev", default-features = false, features = [
"bevy", "bevy_reflect",
] } ] }
bevy_time = { path = "../bevy_time", version = "0.16.0-dev" } bevy_input = { path = "../bevy_input", version = "0.16.0-dev", default-features = false, features = [
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" } "bevy_reflect",
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" } ], optional = true }
bevy_window = { path = "../bevy_window", version = "0.16.0-dev", optional = true } bevy_math = { path = "../bevy_math", version = "0.16.0-dev", default-features = false, features = [
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev" } "bevy_reflect",
], optional = true }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [
"alloc",
] }
bevy_ptr = { path = "../bevy_ptr", version = "0.16.0-dev", default-features = false }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, features = [
"smallvec",
] }
bevy_time = { path = "../bevy_time", version = "0.16.0-dev", default-features = false, features = [
"bevy_reflect",
] }
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev", default-features = false, features = [
"bevy-support",
"bevy_reflect",
], optional = true }
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [
"alloc",
] }
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false }
# bevy (std required)
bevy_log = { path = "../bevy_log", version = "0.16.0-dev", optional = true }
# bevy (optional) # bevy (optional)
bevy_a11y = { path = "../bevy_a11y", optional = true, version = "0.16.0-dev", features = [
"bevy_reflect",
] }
bevy_animation = { path = "../bevy_animation", optional = true, version = "0.16.0-dev" } bevy_animation = { path = "../bevy_animation", optional = true, version = "0.16.0-dev" }
bevy_asset = { path = "../bevy_asset", optional = true, version = "0.16.0-dev" } bevy_asset = { path = "../bevy_asset", optional = true, version = "0.16.0-dev" }
bevy_audio = { path = "../bevy_audio", optional = true, version = "0.16.0-dev" } bevy_audio = { path = "../bevy_audio", optional = true, version = "0.16.0-dev" }
bevy_color = { path = "../bevy_color", optional = true, version = "0.16.0-dev" } bevy_color = { path = "../bevy_color", optional = true, version = "0.16.0-dev", default-features = false, features = [
"alloc",
"bevy_reflect",
] }
bevy_core_pipeline = { path = "../bevy_core_pipeline", optional = true, version = "0.16.0-dev" } bevy_core_pipeline = { path = "../bevy_core_pipeline", optional = true, version = "0.16.0-dev" }
bevy_dev_tools = { path = "../bevy_dev_tools", optional = true, version = "0.16.0-dev" } bevy_dev_tools = { path = "../bevy_dev_tools", optional = true, version = "0.16.0-dev" }
bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.16.0-dev" } bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.16.0-dev" }
bevy_gizmos = { path = "../bevy_gizmos", optional = true, version = "0.16.0-dev", default-features = false } bevy_gizmos = { path = "../bevy_gizmos", optional = true, version = "0.16.0-dev", default-features = false }
bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.16.0-dev" } bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.16.0-dev" }
bevy_image = { path = "../bevy_image", optional = true, version = "0.16.0-dev" } bevy_image = { path = "../bevy_image", optional = true, version = "0.16.0-dev" }
bevy_input_focus = { path = "../bevy_input_focus", optional = true, version = "0.16.0-dev", default-features = false, features = [
"bevy_reflect",
] }
bevy_pbr = { path = "../bevy_pbr", optional = true, version = "0.16.0-dev" } bevy_pbr = { path = "../bevy_pbr", optional = true, version = "0.16.0-dev" }
bevy_picking = { path = "../bevy_picking", optional = true, version = "0.16.0-dev" } bevy_picking = { path = "../bevy_picking", optional = true, version = "0.16.0-dev" }
bevy_remote = { path = "../bevy_remote", optional = true, version = "0.16.0-dev" } bevy_remote = { path = "../bevy_remote", optional = true, version = "0.16.0-dev" }
bevy_render = { path = "../bevy_render", optional = true, version = "0.16.0-dev" } bevy_render = { path = "../bevy_render", optional = true, version = "0.16.0-dev" }
bevy_scene = { path = "../bevy_scene", optional = true, version = "0.16.0-dev" } bevy_scene = { path = "../bevy_scene", optional = true, version = "0.16.0-dev" }
bevy_sprite = { path = "../bevy_sprite", optional = true, version = "0.16.0-dev" } bevy_sprite = { path = "../bevy_sprite", optional = true, version = "0.16.0-dev" }
bevy_state = { path = "../bevy_state", optional = true, version = "0.16.0-dev", default-features = false, features = [
"bevy_app",
"bevy_reflect",
] }
bevy_text = { path = "../bevy_text", optional = true, version = "0.16.0-dev" } bevy_text = { path = "../bevy_text", optional = true, version = "0.16.0-dev" }
bevy_ui = { path = "../bevy_ui", optional = true, version = "0.16.0-dev" } bevy_ui = { path = "../bevy_ui", optional = true, version = "0.16.0-dev" }
bevy_window = { path = "../bevy_window", optional = true, version = "0.16.0-dev", default-features = false, features = [
"bevy_reflect",
] }
bevy_winit = { path = "../bevy_winit", optional = true, version = "0.16.0-dev" } bevy_winit = { path = "../bevy_winit", optional = true, version = "0.16.0-dev" }
[lints] [lints]

View File

@ -4,12 +4,15 @@ plugin_group! {
/// This plugin group will add all the default plugins for a *Bevy* application: /// This plugin group will add all the default plugins for a *Bevy* application:
pub struct DefaultPlugins { pub struct DefaultPlugins {
bevy_app:::PanicHandlerPlugin, bevy_app:::PanicHandlerPlugin,
#[cfg(feature = "bevy_log")]
bevy_log:::LogPlugin, bevy_log:::LogPlugin,
bevy_app:::TaskPoolPlugin, bevy_app:::TaskPoolPlugin,
bevy_diagnostic:::FrameCountPlugin, bevy_diagnostic:::FrameCountPlugin,
bevy_time:::TimePlugin, bevy_time:::TimePlugin,
#[custom(cfg(any(feature = "libm", feature = "std")))]
bevy_transform:::TransformPlugin, bevy_transform:::TransformPlugin,
bevy_diagnostic:::DiagnosticsPlugin, bevy_diagnostic:::DiagnosticsPlugin,
#[custom(cfg(any(feature = "libm", feature = "std")))]
bevy_input:::InputPlugin, bevy_input:::InputPlugin,
#[custom(cfg(not(feature = "bevy_window")))] #[custom(cfg(not(feature = "bevy_window")))]
bevy_app:::ScheduleRunnerPlugin, bevy_app:::ScheduleRunnerPlugin,
@ -17,6 +20,7 @@ plugin_group! {
bevy_window:::WindowPlugin, bevy_window:::WindowPlugin,
#[cfg(feature = "bevy_window")] #[cfg(feature = "bevy_window")]
bevy_a11y:::AccessibilityPlugin, bevy_a11y:::AccessibilityPlugin,
#[cfg(feature = "std")]
#[custom(cfg(any(unix, windows)))] #[custom(cfg(any(unix, windows)))]
bevy_app:::TerminalCtrlCHandlerPlugin, bevy_app:::TerminalCtrlCHandlerPlugin,
#[cfg(feature = "bevy_asset")] #[cfg(feature = "bevy_asset")]

View File

@ -4,6 +4,7 @@
html_logo_url = "https://bevyengine.org/assets/icon.png", html_logo_url = "https://bevyengine.org/assets/icon.png",
html_favicon_url = "https://bevyengine.org/assets/icon.png" html_favicon_url = "https://bevyengine.org/assets/icon.png"
)] )]
#![no_std]
//! This module is separated into its own crate to enable simple dynamic linking for Bevy, and should not be used directly //! This module is separated into its own crate to enable simple dynamic linking for Bevy, and should not be used directly
@ -38,9 +39,13 @@ pub use bevy_gizmos as gizmos;
pub use bevy_gltf as gltf; pub use bevy_gltf as gltf;
#[cfg(feature = "bevy_image")] #[cfg(feature = "bevy_image")]
pub use bevy_image as image; pub use bevy_image as image;
#[cfg(any(feature = "libm", feature = "std"))]
pub use bevy_input as input; pub use bevy_input as input;
#[cfg(feature = "bevy_input_focus")]
pub use bevy_input_focus as input_focus; pub use bevy_input_focus as input_focus;
#[cfg(feature = "bevy_log")]
pub use bevy_log as log; pub use bevy_log as log;
#[cfg(any(feature = "libm", feature = "std"))]
pub use bevy_math as math; pub use bevy_math as math;
#[cfg(feature = "bevy_pbr")] #[cfg(feature = "bevy_pbr")]
pub use bevy_pbr as pbr; pub use bevy_pbr as pbr;
@ -63,6 +68,7 @@ pub use bevy_tasks as tasks;
#[cfg(feature = "bevy_text")] #[cfg(feature = "bevy_text")]
pub use bevy_text as text; pub use bevy_text as text;
pub use bevy_time as time; pub use bevy_time as time;
#[cfg(any(feature = "libm", feature = "std"))]
pub use bevy_transform as transform; pub use bevy_transform as transform;
#[cfg(feature = "bevy_ui")] #[cfg(feature = "bevy_ui")]
pub use bevy_ui as ui; pub use bevy_ui as ui;

View File

@ -1,10 +1,17 @@
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{
app::prelude::*, ecs::prelude::*, input::prelude::*, log::prelude::*, math::prelude::*, app::prelude::*, ecs::prelude::*, reflect::prelude::*, time::prelude::*, utils::prelude::*,
reflect::prelude::*, time::prelude::*, transform::prelude::*, utils::prelude::*,
DefaultPlugins, MinimalPlugins, DefaultPlugins, MinimalPlugins,
}; };
#[doc(hidden)]
#[cfg(any(feature = "libm", feature = "std"))]
pub use crate::{input::prelude::*, math::prelude::*, transform::prelude::*};
#[doc(hidden)]
#[cfg(feature = "bevy_log")]
pub use crate::log::prelude::*;
#[doc(hidden)] #[doc(hidden)]
#[cfg(feature = "bevy_window")] #[cfg(feature = "bevy_window")]
pub use crate::window::prelude::*; pub use crate::window::prelude::*;

View File

@ -13,9 +13,7 @@ keywords = ["bevy"]
bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.16.0-dev" } bevy_image = { path = "../bevy_image", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }
bevy_mikktspace = { path = "../bevy_mikktspace", version = "0.16.0-dev" } bevy_mikktspace = { path = "../bevy_mikktspace", version = "0.16.0-dev" }

View File

@ -40,9 +40,7 @@ bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.16.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.16.0-dev" } bevy_image = { path = "../bevy_image", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_render = { path = "../bevy_render", version = "0.16.0-dev" } bevy_render = { path = "../bevy_render", version = "0.16.0-dev" }
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", optional = true } bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", optional = true }
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }

View File

@ -45,12 +45,7 @@ This is explicitly incompatible with `no_std` targets.
Enables usage of the [`alloc`](https://doc.rust-lang.org/stable/alloc/) crate. Note that this feature is automatically enabled when enabling `std`. Enables usage of the [`alloc`](https://doc.rust-lang.org/stable/alloc/) crate. Note that this feature is automatically enabled when enabling `std`.
This is compatible with most `no_std` targets, but not all. This is compatible with most `no_std` targets, but not all.
### `portable-atomic`
Switches to using [`portable-atomic`](https://docs.rs/portable-atomic/latest/portable_atomic/) as a backend for atomic types, such as `Arc`, `AtomicU8`, etc.
You may need to enable this feature on platforms without full support for atomic types or certain operations, such as [atomic CAS](https://en.wikipedia.org/wiki/Compare-and-swap).
### `critical-section` ### `critical-section`
Switches to using [`critical-section`](https://docs.rs/critical-section/latest/critical_section/) as a backend for synchronization. Switches to using [`critical-section`](https://docs.rs/critical-section/latest/critical_section/) as a backend for synchronization.
You may need to enable this feature on platforms with little to no support for atomic operations, and is often paired with the `portable-atomic` feature. You may need to enable this feature on platforms with little to no support for atomic operations.

View File

@ -20,9 +20,6 @@ documentation = ["bevy_reflect_derive/documentation"]
## Enables function reflection ## Enables function reflection
functions = ["bevy_reflect_derive/functions"] functions = ["bevy_reflect_derive/functions"]
# When enabled, provides Bevy-related reflection implementations
bevy = ["smallvec", "smol_str"]
# Debugging Features # Debugging Features
## Enables features useful for debugging reflection ## Enables features useful for debugging reflection

View File

@ -48,9 +48,7 @@ bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.16.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_encase_derive = { path = "../bevy_encase_derive", version = "0.16.0-dev" } bevy_encase_derive = { path = "../bevy_encase_derive", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_render_macros = { path = "macros", version = "0.16.0-dev" } bevy_render_macros = { path = "macros", version = "0.16.0-dev" }
bevy_time = { path = "../bevy_time", version = "0.16.0-dev" } bevy_time = { path = "../bevy_time", version = "0.16.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }

View File

@ -23,9 +23,7 @@ bevy_app = { path = "../bevy_app", version = "0.16.0-dev" }
bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" } bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" }
bevy_render = { path = "../bevy_render", version = "0.16.0-dev", optional = true } bevy_render = { path = "../bevy_render", version = "0.16.0-dev", optional = true }

View File

@ -23,9 +23,7 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.16.0-dev" } bevy_image = { path = "../bevy_image", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_picking = { path = "../bevy_picking", version = "0.16.0-dev", optional = true } bevy_picking = { path = "../bevy_picking", version = "0.16.0-dev", optional = true }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_render = { path = "../bevy_render", version = "0.16.0-dev" } bevy_render = { path = "../bevy_render", version = "0.16.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" }

View File

@ -13,16 +13,12 @@ default = ["std", "async_executor"]
std = [ std = [
"futures-lite/std", "futures-lite/std",
"async-task/std", "async-task/std",
"edge-executor?/std",
"bevy_platform_support/std", "bevy_platform_support/std",
"once_cell/std",
] ]
multi_threaded = ["std", "dep:async-channel", "dep:concurrent-queue"] multi_threaded = ["std", "dep:async-channel", "dep:concurrent-queue"]
async_executor = ["std", "dep:async-executor"] async_executor = ["std", "dep:async-executor"]
edge_executor = ["dep:edge-executor"] critical-section = ["bevy_platform_support/critical-section"]
critical-section = [
"bevy_platform_support/critical-section",
"edge-executor?/critical-section",
]
[dependencies] [dependencies]
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [ bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [
@ -37,12 +33,17 @@ derive_more = { version = "1", default-features = false, features = [
"deref", "deref",
"deref_mut", "deref_mut",
] } ] }
async-executor = { version = "1.11", optional = true } async-executor = { version = "1.11", optional = true }
edge-executor = { version = "0.4.1", default-features = false, optional = true }
async-channel = { version = "2.3.0", optional = true } async-channel = { version = "2.3.0", optional = true }
async-io = { version = "2.0.0", optional = true } async-io = { version = "2.0.0", optional = true }
concurrent-queue = { version = "2.0.0", optional = true } concurrent-queue = { version = "2.0.0", optional = true }
atomic-waker = { version = "1", default-features = false }
once_cell = { version = "1.18", default-features = false, features = [
"critical-section",
] }
crossbeam-queue = { version = "0.3", default-features = false, features = [
"alloc",
] }
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen-futures = "0.4" wasm-bindgen-futures = "0.4"
@ -53,7 +54,10 @@ futures-channel = "0.3"
async-task = { version = "4.4.0", default-features = false, features = [ async-task = { version = "4.4.0", default-features = false, features = [
"portable-atomic", "portable-atomic",
] } ] }
edge-executor = { version = "0.4.1", default-features = false, optional = true, features = [ heapless = { version = "0.8", default-features = false, features = [
"portable-atomic",
] }
atomic-waker = { version = "1", default-features = false, features = [
"portable-atomic", "portable-atomic",
] } ] }

View File

@ -36,7 +36,7 @@ The determining factor for what kind of work should go in each pool is latency r
## `no_std` Support ## `no_std` Support
To enable `no_std` support in this crate, you will need to disable default features, and enable the `edge_executor` and `critical-section` features. For platforms without full support for Rust atomics, you may also need to enable the `portable-atomic` feature. To enable `no_std` support in this crate, you will need to disable default features, and enable the `edge_executor` and `critical-section` features.
[bevy]: https://bevyengine.org [bevy]: https://bevyengine.org
[rayon]: https://github.com/rayon-rs/rayon [rayon]: https://github.com/rayon-rs/rayon

View File

@ -0,0 +1,653 @@
//! Alternative to `async_executor` based on [`edge_executor`] by Ivan Markov.
//!
//! It has been vendored along with its tests to update several outdated dependencies.
//!
//! [`async_executor`]: https://github.com/smol-rs/async-executor
//! [`edge_executor`]: https://github.com/ivmarkov/edge-executor
#![expect(unsafe_code, reason = "original implementation relies on unsafe")]
#![expect(
dead_code,
reason = "keeping methods from original implementation for transparency"
)]
// TODO: Create a more tailored replacement, possibly integrating [Fotre](https://github.com/NthTensor/Forte)
use alloc::rc::Rc;
use core::{
future::{poll_fn, Future},
marker::PhantomData,
task::{Context, Poll},
};
use async_task::{Runnable, Task};
use atomic_waker::AtomicWaker;
use bevy_platform_support::sync::Arc;
use futures_lite::FutureExt;
use once_cell::sync::OnceCell;
/// An async executor.
///
/// # Examples
///
/// A multi-threaded executor:
///
/// ```ignore
/// use async_channel::unbounded;
/// use easy_parallel::Parallel;
///
/// use edge_executor::{Executor, block_on};
///
/// let ex: Executor = Default::default();
/// let (signal, shutdown) = unbounded::<()>();
///
/// Parallel::new()
/// // Run four executor threads.
/// .each(0..4, |_| block_on(ex.run(shutdown.recv())))
/// // Run the main future on the current thread.
/// .finish(|| block_on(async {
/// println!("Hello world!");
/// drop(signal);
/// }));
/// ```
pub struct Executor<'a, const C: usize = 64> {
state: OnceCell<Arc<State<C>>>,
_invariant: PhantomData<core::cell::UnsafeCell<&'a ()>>,
}
impl<'a, const C: usize> Executor<'a, C> {
/// Creates a new executor.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::Executor;
///
/// let ex: Executor = Default::default();
/// ```
pub const fn new() -> Self {
Self {
state: OnceCell::new(),
_invariant: PhantomData,
}
}
/// Spawns a task onto the executor.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::Executor;
///
/// let ex: Executor = Default::default();
///
/// let task = ex.spawn(async {
/// println!("Hello world");
/// });
/// ```
///
/// Note that if the executor's queue size is equal to the number of currently
/// spawned and running tasks, spawning this additional task might cause the executor to panic
/// later, when the task is scheduled for polling.
pub fn spawn<F>(&self, fut: F) -> Task<F::Output>
where
F: Future + Send + 'a,
F::Output: Send + 'a,
{
// SAFETY: Original implementation missing safety documentation
unsafe { self.spawn_unchecked(fut) }
}
/// Attempts to run a task if at least one is scheduled.
///
/// Running a scheduled task means simply polling its future once.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::Executor;
///
/// let ex: Executor = Default::default();
/// assert!(!ex.try_tick()); // no tasks to run
///
/// let task = ex.spawn(async {
/// println!("Hello world");
/// });
/// assert!(ex.try_tick()); // a task was found
/// ```
pub fn try_tick(&self) -> bool {
if let Some(runnable) = self.try_runnable() {
runnable.run();
true
} else {
false
}
}
/// Runs a single task asynchronously.
///
/// Running a task means simply polling its future once.
///
/// If no tasks are scheduled when this method is called, it will wait until one is scheduled.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::{Executor, block_on};
///
/// let ex: Executor = Default::default();
///
/// let task = ex.spawn(async {
/// println!("Hello world");
/// });
/// block_on(ex.tick()); // runs the task
/// ```
pub async fn tick(&self) {
self.runnable().await.run();
}
/// Runs the executor asynchronously until the given future completes.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::{Executor, block_on};
///
/// let ex: Executor = Default::default();
///
/// let task = ex.spawn(async { 1 + 2 });
/// let res = block_on(ex.run(async { task.await * 2 }));
///
/// assert_eq!(res, 6);
/// ```
pub async fn run<F>(&self, fut: F) -> F::Output
where
F: Future + Send + 'a,
{
// SAFETY: Original implementation missing safety documentation
unsafe { self.run_unchecked(fut).await }
}
/// Waits for the next runnable task to run.
async fn runnable(&self) -> Runnable {
poll_fn(|ctx| self.poll_runnable(ctx)).await
}
/// Polls the first task scheduled for execution by the executor.
fn poll_runnable(&self, ctx: &Context<'_>) -> Poll<Runnable> {
self.state().waker.register(ctx.waker());
if let Some(runnable) = self.try_runnable() {
Poll::Ready(runnable)
} else {
Poll::Pending
}
}
/// Pops the first task scheduled for execution by the executor.
///
/// Returns
/// - `None` - if no task was scheduled for execution
/// - `Some(Runnnable)` - the first task scheduled for execution. Calling `Runnable::run` will
/// execute the task. In other words, it will poll its future.
fn try_runnable(&self) -> Option<Runnable> {
let runnable;
#[cfg(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
))]
{
runnable = self.state().queue.pop();
}
#[cfg(not(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
)))]
{
runnable = self.state().queue.dequeue();
}
runnable
}
/// # Safety
///
/// Original implementation missing safety documentation
unsafe fn spawn_unchecked<F>(&self, fut: F) -> Task<F::Output>
where
F: Future,
{
let schedule = {
let state = self.state().clone();
move |runnable| {
#[cfg(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
))]
{
state.queue.push(runnable).unwrap();
}
#[cfg(not(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
)))]
{
state.queue.enqueue(runnable).unwrap();
}
if let Some(waker) = state.waker.take() {
waker.wake();
}
}
};
// SAFETY: Original implementation missing safety documentation
let (runnable, task) = unsafe { async_task::spawn_unchecked(fut, schedule) };
runnable.schedule();
task
}
/// # Safety
///
/// Original implementation missing safety documentation
async unsafe fn run_unchecked<F>(&self, fut: F) -> F::Output
where
F: Future,
{
let run_forever = async {
loop {
self.tick().await;
}
};
run_forever.or(fut).await
}
/// Returns a reference to the inner state.
fn state(&self) -> &Arc<State<C>> {
self.state.get_or_init(|| Arc::new(State::new()))
}
}
impl<'a, const C: usize> Default for Executor<'a, C> {
fn default() -> Self {
Self::new()
}
}
// SAFETY: Original implementation missing safety documentation
unsafe impl<'a, const C: usize> Send for Executor<'a, C> {}
// SAFETY: Original implementation missing safety documentation
unsafe impl<'a, const C: usize> Sync for Executor<'a, C> {}
/// A thread-local executor.
///
/// The executor can only be run on the thread that created it.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::{LocalExecutor, block_on};
///
/// let local_ex: LocalExecutor = Default::default();
///
/// block_on(local_ex.run(async {
/// println!("Hello world!");
/// }));
/// ```
pub struct LocalExecutor<'a, const C: usize = 64> {
executor: Executor<'a, C>,
_not_send: PhantomData<core::cell::UnsafeCell<&'a Rc<()>>>,
}
impl<'a, const C: usize> LocalExecutor<'a, C> {
/// Creates a single-threaded executor.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::LocalExecutor;
///
/// let local_ex: LocalExecutor = Default::default();
/// ```
pub const fn new() -> Self {
Self {
executor: Executor::<C>::new(),
_not_send: PhantomData,
}
}
/// Spawns a task onto the executor.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::LocalExecutor;
///
/// let local_ex: LocalExecutor = Default::default();
///
/// let task = local_ex.spawn(async {
/// println!("Hello world");
/// });
/// ```
///
/// Note that if the executor's queue size is equal to the number of currently
/// spawned and running tasks, spawning this additional task might cause the executor to panic
/// later, when the task is scheduled for polling.
pub fn spawn<F>(&self, fut: F) -> Task<F::Output>
where
F: Future + 'a,
F::Output: 'a,
{
// SAFETY: Original implementation missing safety documentation
unsafe { self.executor.spawn_unchecked(fut) }
}
/// Attempts to run a task if at least one is scheduled.
///
/// Running a scheduled task means simply polling its future once.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::LocalExecutor;
///
/// let local_ex: LocalExecutor = Default::default();
/// assert!(!local_ex.try_tick()); // no tasks to run
///
/// let task = local_ex.spawn(async {
/// println!("Hello world");
/// });
/// assert!(local_ex.try_tick()); // a task was found
/// ```
pub fn try_tick(&self) -> bool {
self.executor.try_tick()
}
/// Runs a single task asynchronously.
///
/// Running a task means simply polling its future once.
///
/// If no tasks are scheduled when this method is called, it will wait until one is scheduled.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::{LocalExecutor, block_on};
///
/// let local_ex: LocalExecutor = Default::default();
///
/// let task = local_ex.spawn(async {
/// println!("Hello world");
/// });
/// block_on(local_ex.tick()); // runs the task
/// ```
pub async fn tick(&self) {
self.executor.tick().await;
}
/// Runs the executor asynchronously until the given future completes.
///
/// # Examples
///
/// ```ignore
/// use edge_executor::{LocalExecutor, block_on};
///
/// let local_ex: LocalExecutor = Default::default();
///
/// let task = local_ex.spawn(async { 1 + 2 });
/// let res = block_on(local_ex.run(async { task.await * 2 }));
///
/// assert_eq!(res, 6);
/// ```
pub async fn run<F>(&self, fut: F) -> F::Output
where
F: Future,
{
// SAFETY: Original implementation missing safety documentation
unsafe { self.executor.run_unchecked(fut) }.await
}
}
impl<'a, const C: usize> Default for LocalExecutor<'a, C> {
fn default() -> Self {
Self::new()
}
}
struct State<const C: usize> {
#[cfg(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
))]
queue: crossbeam_queue::ArrayQueue<Runnable>,
#[cfg(not(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
)))]
queue: heapless::mpmc::MpMcQueue<Runnable, C>,
waker: AtomicWaker,
}
impl<const C: usize> State<C> {
fn new() -> Self {
Self {
#[cfg(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
))]
queue: crossbeam_queue::ArrayQueue::new(C),
#[cfg(not(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
)))]
queue: heapless::mpmc::MpMcQueue::new(),
waker: AtomicWaker::new(),
}
}
}
#[cfg(test)]
mod different_executor_tests {
use core::cell::Cell;
use futures_lite::future::{block_on, pending, poll_once};
use futures_lite::pin;
use super::LocalExecutor;
#[test]
fn shared_queue_slot() {
block_on(async {
let was_polled = Cell::new(false);
let future = async {
was_polled.set(true);
pending::<()>().await;
};
let ex1: LocalExecutor = Default::default();
let ex2: LocalExecutor = Default::default();
// Start the futures for running forever.
let (run1, run2) = (ex1.run(pending::<()>()), ex2.run(pending::<()>()));
pin!(run1);
pin!(run2);
assert!(poll_once(run1.as_mut()).await.is_none());
assert!(poll_once(run2.as_mut()).await.is_none());
// Spawn the future on executor one and then poll executor two.
ex1.spawn(future).detach();
assert!(poll_once(run2).await.is_none());
assert!(!was_polled.get());
// Poll the first one.
assert!(poll_once(run1).await.is_none());
assert!(was_polled.get());
});
}
}
#[cfg(test)]
mod drop_tests {
use alloc::string::String;
use core::mem;
use core::sync::atomic::{AtomicUsize, Ordering};
use core::task::{Poll, Waker};
use std::sync::Mutex;
use futures_lite::future;
use once_cell::sync::Lazy;
use super::{Executor, Task};
#[test]
fn leaked_executor_leaks_everything() {
static DROP: AtomicUsize = AtomicUsize::new(0);
static WAKER: Lazy<Mutex<Option<Waker>>> = Lazy::new(Default::default);
let ex: Executor = Default::default();
let task = ex.spawn(async {
let _guard = CallOnDrop(|| {
DROP.fetch_add(1, Ordering::SeqCst);
});
future::poll_fn(|cx| {
*WAKER.lock().unwrap() = Some(cx.waker().clone());
Poll::Pending::<()>
})
.await;
});
future::block_on(ex.tick());
assert!(WAKER.lock().unwrap().is_some());
assert_eq!(DROP.load(Ordering::SeqCst), 0);
mem::forget(ex);
assert_eq!(DROP.load(Ordering::SeqCst), 0);
assert!(future::block_on(future::poll_once(task)).is_none());
assert_eq!(DROP.load(Ordering::SeqCst), 0);
}
#[test]
fn await_task_after_dropping_executor() {
let s: String = "hello".into();
let ex: Executor = Default::default();
let task: Task<&str> = ex.spawn(async { &*s });
assert!(ex.try_tick());
drop(ex);
assert_eq!(future::block_on(task), "hello");
drop(s);
}
#[test]
fn drop_executor_and_then_drop_finished_task() {
static DROP: AtomicUsize = AtomicUsize::new(0);
let ex: Executor = Default::default();
let task = ex.spawn(async {
CallOnDrop(|| {
DROP.fetch_add(1, Ordering::SeqCst);
})
});
assert!(ex.try_tick());
assert_eq!(DROP.load(Ordering::SeqCst), 0);
drop(ex);
assert_eq!(DROP.load(Ordering::SeqCst), 0);
drop(task);
assert_eq!(DROP.load(Ordering::SeqCst), 1);
}
#[test]
fn drop_finished_task_and_then_drop_executor() {
static DROP: AtomicUsize = AtomicUsize::new(0);
let ex: Executor = Default::default();
let task = ex.spawn(async {
CallOnDrop(|| {
DROP.fetch_add(1, Ordering::SeqCst);
})
});
assert!(ex.try_tick());
assert_eq!(DROP.load(Ordering::SeqCst), 0);
drop(task);
assert_eq!(DROP.load(Ordering::SeqCst), 1);
drop(ex);
assert_eq!(DROP.load(Ordering::SeqCst), 1);
}
struct CallOnDrop<F: Fn()>(F);
impl<F: Fn()> Drop for CallOnDrop<F> {
fn drop(&mut self) {
(self.0)();
}
}
}
#[cfg(test)]
mod local_queue {
use alloc::boxed::Box;
use futures_lite::{future, pin};
use super::Executor;
#[test]
fn two_queues() {
future::block_on(async {
// Create an executor with two runners.
let ex: Executor = Default::default();
let (run1, run2) = (
ex.run(future::pending::<()>()),
ex.run(future::pending::<()>()),
);
let mut run1 = Box::pin(run1);
pin!(run2);
// Poll them both.
assert!(future::poll_once(run1.as_mut()).await.is_none());
assert!(future::poll_once(run2.as_mut()).await.is_none());
// Drop the first one, which should leave the local queue in the `None` state.
drop(run1);
assert!(future::poll_once(run2.as_mut()).await.is_none());
});
}
}

View File

@ -23,11 +23,11 @@ type ExecutorInner<'a> = async_executor::Executor<'a>;
#[cfg(feature = "async_executor")] #[cfg(feature = "async_executor")]
type LocalExecutorInner<'a> = async_executor::LocalExecutor<'a>; type LocalExecutorInner<'a> = async_executor::LocalExecutor<'a>;
#[cfg(all(not(feature = "async_executor"), feature = "edge_executor"))] #[cfg(not(feature = "async_executor"))]
type ExecutorInner<'a> = edge_executor::Executor<'a, 64>; type ExecutorInner<'a> = crate::edge_executor::Executor<'a, 64>;
#[cfg(all(not(feature = "async_executor"), feature = "edge_executor"))] #[cfg(not(feature = "async_executor"))]
type LocalExecutorInner<'a> = edge_executor::LocalExecutor<'a, 64>; type LocalExecutorInner<'a> = crate::edge_executor::LocalExecutor<'a, 64>;
/// Wrapper around a multi-threading-aware async executor. /// Wrapper around a multi-threading-aware async executor.
/// Spawning will generally require tasks to be `Send` and `Sync` to allow multiple /// Spawning will generally require tasks to be `Send` and `Sync` to allow multiple

View File

@ -11,9 +11,6 @@ extern crate std;
extern crate alloc; extern crate alloc;
#[cfg(not(any(feature = "async_executor", feature = "edge_executor")))]
compile_error!("Either of the `async_executor` or the `edge_executor` features must be enabled.");
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
mod conditional_send { mod conditional_send {
/// Use [`ConditionalSend`] to mark an optional Send trait bound. Useful as on certain platforms (eg. Wasm), /// Use [`ConditionalSend`] to mark an optional Send trait bound. Useful as on certain platforms (eg. Wasm),
@ -43,7 +40,9 @@ pub type BoxedFuture<'a, T> = core::pin::Pin<Box<dyn ConditionalSendFuture<Outpu
pub mod futures; pub mod futures;
#[cfg(any(feature = "async_executor", feature = "edge_executor"))] #[cfg(not(feature = "async_executor"))]
mod edge_executor;
mod executor; mod executor;
mod slice; mod slice;

View File

@ -10,50 +10,12 @@ use std::thread_local;
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
use bevy_platform_support::sync::{Mutex, PoisonError}; use bevy_platform_support::sync::{Mutex, PoisonError};
#[cfg(all( #[cfg(feature = "std")]
feature = "std",
any(feature = "async_executor", feature = "edge_executor")
))]
use crate::executor::LocalExecutor; use crate::executor::LocalExecutor;
#[cfg(all( #[cfg(not(feature = "std"))]
not(feature = "std"),
any(feature = "async_executor", feature = "edge_executor")
))]
use crate::executor::Executor as LocalExecutor; use crate::executor::Executor as LocalExecutor;
#[cfg(not(any(feature = "async_executor", feature = "edge_executor")))]
mod dummy_executor {
use async_task::Task;
use core::{future::Future, marker::PhantomData};
/// Dummy implementation of a `LocalExecutor` to allow for a cleaner compiler error
/// due to missing feature flags.
#[doc(hidden)]
#[derive(Debug)]
pub struct LocalExecutor<'a>(PhantomData<fn(&'a ())>);
impl<'a> LocalExecutor<'a> {
/// Dummy implementation
pub const fn new() -> Self {
Self(PhantomData)
}
/// Dummy implementation
pub fn try_tick(&self) -> bool {
unimplemented!()
}
/// Dummy implementation
pub fn spawn<T: 'a>(&self, _: impl Future<Output = T> + 'a) -> Task<T> {
unimplemented!()
}
}
}
#[cfg(not(any(feature = "async_executor", feature = "edge_executor")))]
use dummy_executor::LocalExecutor;
#[cfg(feature = "std")] #[cfg(feature = "std")]
thread_local! { thread_local! {
static LOCAL_EXECUTOR: LocalExecutor<'static> = const { LocalExecutor::new() }; static LOCAL_EXECUTOR: LocalExecutor<'static> = const { LocalExecutor::new() };

View File

@ -21,9 +21,7 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.16.0-dev" } bevy_image = { path = "../bevy_image", version = "0.16.0-dev" }
bevy_log = { path = "../bevy_log", version = "0.16.0-dev" } bevy_log = { path = "../bevy_log", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_render = { path = "../bevy_render", version = "0.16.0-dev" } bevy_render = { path = "../bevy_render", version = "0.16.0-dev" }
bevy_sprite = { path = "../bevy_sprite", version = "0.16.0-dev" } bevy_sprite = { path = "../bevy_sprite", version = "0.16.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }

View File

@ -54,9 +54,7 @@ critical-section = [
# bevy # bevy
bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = false } bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = false }
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev", default-features = false } bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev", default-features = false }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, optional = true }
"bevy",
], optional = true }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false } bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false }
# other # other

View File

@ -15,7 +15,7 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev", default-features = fa
bevy_log = { path = "../bevy_log", version = "0.16.0-dev", default-features = false, optional = true } bevy_log = { path = "../bevy_log", version = "0.16.0-dev", default-features = false, optional = true }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev", default-features = false } bevy_math = { path = "../bevy_math", version = "0.16.0-dev", default-features = false }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, optional = true } bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, optional = true }
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, optional = true } bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false }
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, optional = true } bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, optional = true }
serde = { version = "1", default-features = false, features = [ serde = { version = "1", default-features = false, features = [
"derive", "derive",
@ -59,16 +59,7 @@ bevy_reflect = [
## Uses `async-executor` as a task execution backend. ## Uses `async-executor` as a task execution backend.
## This backend is incompatible with `no_std` targets. ## This backend is incompatible with `no_std` targets.
async_executor = [ async_executor = ["std", "dep:bevy_utils", "bevy_tasks/async_executor"]
"std",
"dep:bevy_tasks",
"dep:bevy_utils",
"bevy_tasks/async_executor",
]
## Uses `edge-executor` as a task execution backend.
## Use this instead of `async-executor` if working on a `no_std` target.
edge_executor = ["dep:bevy_tasks", "bevy_tasks/edge_executor"]
# Platform Compatibility # Platform Compatibility
@ -82,7 +73,7 @@ std = [
"bevy_ecs?/std", "bevy_ecs?/std",
"bevy_math/std", "bevy_math/std",
"bevy_reflect?/std", "bevy_reflect?/std",
"bevy_tasks?/std", "bevy_tasks/std",
"bevy_utils?/std", "bevy_utils?/std",
"serde?/std", "serde?/std",
] ]
@ -92,7 +83,7 @@ std = [
critical-section = [ critical-section = [
"bevy_app?/critical-section", "bevy_app?/critical-section",
"bevy_ecs?/critical-section", "bevy_ecs?/critical-section",
"bevy_tasks?/critical-section", "bevy_tasks/critical-section",
"bevy_reflect?/critical-section", "bevy_reflect?/critical-section",
] ]

View File

@ -20,9 +20,7 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.16.0-dev" } bevy_image = { path = "../bevy_image", version = "0.16.0-dev" }
bevy_input = { path = "../bevy_input", version = "0.16.0-dev" } bevy_input = { path = "../bevy_input", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" } bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
"bevy",
] }
bevy_render = { path = "../bevy_render", version = "0.16.0-dev" } bevy_render = { path = "../bevy_render", version = "0.16.0-dev" }
bevy_sprite = { path = "../bevy_sprite", version = "0.16.0-dev" } bevy_sprite = { path = "../bevy_sprite", version = "0.16.0-dev" }
bevy_text = { path = "../bevy_text", version = "0.16.0-dev" } bevy_text = { path = "../bevy_text", version = "0.16.0-dev" }

View File

@ -14,6 +14,7 @@ The default feature set enables most of the expected features of a game engine,
|android-game-activity|Android GameActivity support. Default, choose between this and `android-native-activity`.| |android-game-activity|Android GameActivity support. Default, choose between this and `android-native-activity`.|
|android_shared_stdcxx|Enable using a shared stdlib for cxx on Android| |android_shared_stdcxx|Enable using a shared stdlib for cxx on Android|
|animation|Enable animation support, and glTF animation loading| |animation|Enable animation support, and glTF animation loading|
|async_executor|Uses `async-executor` as a task execution backend.|
|bevy_animation|Provides animation functionality| |bevy_animation|Provides animation functionality|
|bevy_asset|Provides asset functionality| |bevy_asset|Provides asset functionality|
|bevy_audio|Provides audio functionality| |bevy_audio|Provides audio functionality|
@ -22,6 +23,8 @@ The default feature set enables most of the expected features of a game engine,
|bevy_gilrs|Adds gamepad support| |bevy_gilrs|Adds gamepad support|
|bevy_gizmos|Adds support for rendering gizmos| |bevy_gizmos|Adds support for rendering gizmos|
|bevy_gltf|[glTF](https://www.khronos.org/gltf/) support| |bevy_gltf|[glTF](https://www.khronos.org/gltf/) support|
|bevy_input_focus|Enable input focus subsystem|
|bevy_log|Enable integration with `tracing` and `log`|
|bevy_mesh_picking_backend|Provides an implementation for picking meshes| |bevy_mesh_picking_backend|Provides an implementation for picking meshes|
|bevy_pbr|Adds PBR rendering| |bevy_pbr|Adds PBR rendering|
|bevy_picking|Provides picking functionality| |bevy_picking|Provides picking functionality|
@ -42,6 +45,7 @@ The default feature set enables most of the expected features of a game engine,
|multi_threaded|Enables multithreaded parallelism in the engine. Disabling it forces all engine tasks to run on a single thread.| |multi_threaded|Enables multithreaded parallelism in the engine. Disabling it forces all engine tasks to run on a single thread.|
|png|PNG image format support| |png|PNG image format support|
|smaa_luts|Include SMAA Look Up Tables KTX2 Files| |smaa_luts|Include SMAA Look Up Tables KTX2 Files|
|std|Allows access to the `std` crate.|
|sysinfo_plugin|Enables system information diagnostic plugin| |sysinfo_plugin|Enables system information diagnostic plugin|
|tonemapping_luts|Include tonemapping Look Up Tables KTX2 files. If everything is pink, you need to enable this feature or change the `Tonemapping` method for your `Camera2d` or `Camera3d`.| |tonemapping_luts|Include tonemapping Look Up Tables KTX2 files. If everything is pink, you need to enable this feature or change the `Tonemapping` method for your `Camera2d` or `Camera3d`.|
|vorbis|OGG/VORBIS audio format support| |vorbis|OGG/VORBIS audio format support|
@ -65,8 +69,10 @@ The default feature set enables most of the expected features of a game engine,
|bevy_remote|Enable the Bevy Remote Protocol| |bevy_remote|Enable the Bevy Remote Protocol|
|bevy_ui_debug|Provides a debug overlay for bevy UI| |bevy_ui_debug|Provides a debug overlay for bevy UI|
|bmp|BMP image format support| |bmp|BMP image format support|
|critical-section|`critical-section` provides the building blocks for synchronization primitives on all platforms, including `no_std`.|
|dds|DDS compressed texture support| |dds|DDS compressed texture support|
|debug_glam_assert|Enable assertions in debug builds to check the validity of parameters passed to glam| |debug_glam_assert|Enable assertions in debug builds to check the validity of parameters passed to glam|
|default_no_std|Recommended defaults for no_std applications|
|detailed_trace|Enable detailed trace event logging. These trace events are expensive even when off, thus they require compile time opt-in| |detailed_trace|Enable detailed trace event logging. These trace events are expensive even when off, thus they require compile time opt-in|
|dynamic_linking|Force dynamic linking, which improves iterative compile times| |dynamic_linking|Force dynamic linking, which improves iterative compile times|
|embedded_watcher|Enables watching in memory asset providers for Bevy Asset hot-reloading| |embedded_watcher|Enables watching in memory asset providers for Bevy Asset hot-reloading|
@ -80,6 +86,7 @@ The default feature set enables most of the expected features of a game engine,
|glam_assert|Enable assertions to check the validity of parameters passed to glam| |glam_assert|Enable assertions to check the validity of parameters passed to glam|
|ico|ICO image format support| |ico|ICO image format support|
|jpeg|JPEG image format support| |jpeg|JPEG image format support|
|libm|Uses the `libm` maths library instead of the one provided in `std` and `core`.|
|meshlet|Enables the meshlet renderer for dense high-poly scenes (experimental)| |meshlet|Enables the meshlet renderer for dense high-poly scenes (experimental)|
|meshlet_processor|Enables processing meshes into meshlet meshes for bevy_pbr| |meshlet_processor|Enables processing meshes into meshlet meshes for bevy_pbr|
|minimp3|MP3 audio format support (through minimp3)| |minimp3|MP3 audio format support (through minimp3)|

View File

@ -44,6 +44,7 @@
html_logo_url = "https://bevyengine.org/assets/icon.png", html_logo_url = "https://bevyengine.org/assets/icon.png",
html_favicon_url = "https://bevyengine.org/assets/icon.png" html_favicon_url = "https://bevyengine.org/assets/icon.png"
)] )]
#![no_std]
pub use bevy_internal::*; pub use bevy_internal::*;

View File

@ -84,7 +84,6 @@ impl CI {
cmds.append(&mut commands::DocCheckCommand::default().prepare(sh, flags)); cmds.append(&mut commands::DocCheckCommand::default().prepare(sh, flags));
cmds.append(&mut commands::DocTestCommand::default().prepare(sh, flags)); cmds.append(&mut commands::DocTestCommand::default().prepare(sh, flags));
cmds.append(&mut commands::CompileCheckCommand::default().prepare(sh, flags)); cmds.append(&mut commands::CompileCheckCommand::default().prepare(sh, flags));
cmds.append(&mut commands::CompileCheckNoStdCommand::default().prepare(sh, flags));
cmds.append(&mut commands::CompileFailCommand::default().prepare(sh, flags)); cmds.append(&mut commands::CompileFailCommand::default().prepare(sh, flags));
cmds.append(&mut commands::BenchCheckCommand::default().prepare(sh, flags)); cmds.append(&mut commands::BenchCheckCommand::default().prepare(sh, flags));
cmds.append(&mut commands::ExampleCheckCommand::default().prepare(sh, flags)); cmds.append(&mut commands::ExampleCheckCommand::default().prepare(sh, flags));
@ -113,7 +112,6 @@ enum Commands {
DocCheck(commands::DocCheckCommand), DocCheck(commands::DocCheckCommand),
DocTest(commands::DocTestCommand), DocTest(commands::DocTestCommand),
CompileCheck(commands::CompileCheckCommand), CompileCheck(commands::CompileCheckCommand),
CompileCheckNoStd(commands::CompileCheckNoStdCommand),
CompileFail(commands::CompileFailCommand), CompileFail(commands::CompileFailCommand),
BenchCheck(commands::BenchCheckCommand), BenchCheck(commands::BenchCheckCommand),
ExampleCheck(commands::ExampleCheckCommand), ExampleCheck(commands::ExampleCheckCommand),
@ -136,7 +134,6 @@ impl Prepare for Commands {
Commands::DocCheck(subcommand) => subcommand.prepare(sh, flags), Commands::DocCheck(subcommand) => subcommand.prepare(sh, flags),
Commands::DocTest(subcommand) => subcommand.prepare(sh, flags), Commands::DocTest(subcommand) => subcommand.prepare(sh, flags),
Commands::CompileCheck(subcommand) => subcommand.prepare(sh, flags), Commands::CompileCheck(subcommand) => subcommand.prepare(sh, flags),
Commands::CompileCheckNoStd(subcommand) => subcommand.prepare(sh, flags),
Commands::CompileFail(subcommand) => subcommand.prepare(sh, flags), Commands::CompileFail(subcommand) => subcommand.prepare(sh, flags),
Commands::BenchCheck(subcommand) => subcommand.prepare(sh, flags), Commands::BenchCheck(subcommand) => subcommand.prepare(sh, flags),
Commands::ExampleCheck(subcommand) => subcommand.prepare(sh, flags), Commands::ExampleCheck(subcommand) => subcommand.prepare(sh, flags),

View File

@ -1,179 +0,0 @@
use crate::{Flag, Prepare, PreparedCommand};
use argh::FromArgs;
use xshell::cmd;
/// Checks that the project compiles for a `no_std` target.
/// Note that this tool will attempt to install the target via rustup.
/// This can be skipped by passing the "--skip-install" flag.
#[derive(FromArgs)]
#[argh(subcommand, name = "compile-check-no-std")]
pub struct CompileCheckNoStdCommand {
/// the target to check against.
/// Defaults to "x86_64-unknown-none"
#[argh(option, default = "Self::default().target")]
target: String,
/// skip attempting the installation of the target.
#[argh(switch)]
skip_install: bool,
}
impl Default for CompileCheckNoStdCommand {
fn default() -> Self {
Self {
target: String::from("x86_64-unknown-none"),
skip_install: false,
}
}
}
impl Prepare for CompileCheckNoStdCommand {
fn prepare<'a>(&self, sh: &'a xshell::Shell, _flags: Flag) -> Vec<PreparedCommand<'a>> {
let target = self.target.as_str();
let mut commands = Vec::new();
if !self.skip_install {
commands.push(PreparedCommand::new::<Self>(
cmd!(sh, "rustup target add {target}"),
"Unable to add the required target via rustup, is it spelled correctly?",
));
}
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_ptr --no-default-features --target {target}"
),
"Please fix compiler errors in output above for bevy_ptr no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_utils --no-default-features --target {target}"
),
"Please fix compiler errors in output above for bevy_utils no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_mikktspace --no-default-features --features libm --target {target}"
),
"Please fix compiler errors in output above for bevy_mikktspace no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_reflect --no-default-features --target {target}"
),
"Please fix compiler errors in output above for bevy_reflect no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_math --no-default-features --features libm --target {target}"
),
"Please fix compiler errors in output above for bevy_math no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_color --no-default-features --features libm --target {target}"
),
"Please fix compiler errors in output above for bevy_color no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_tasks --no-default-features --features edge_executor,critical-section --target {target}"
),
"Please fix compiler errors in output above for bevy_tasks no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_ecs --no-default-features --features edge_executor,critical-section,bevy_debug_stepping,bevy_reflect --target {target}"
),
"Please fix compiler errors in output above for bevy_ecs no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_app --no-default-features --features bevy_reflect --target {target}"
),
"Please fix compiler errors in output above for bevy_app no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_input --no-default-features --features libm,serialize,bevy_reflect --target {target}"
),
"Please fix compiler errors in output above for bevy_input no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_state --no-default-features --features bevy_reflect,bevy_app --target {target}"
),
"Please fix compiler errors in output above for bevy_state no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_window --no-default-features --features libm,bevy_reflect,serialize --target {target}"
),
"Please fix compiler errors in output above for bevy_window no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_transform --no-default-features --features bevy-support,edge_executor,critical-section,serialize,libm --target {target}"
),
"Please fix compiler errors in output above for bevy_transform no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_time --no-default-features --features bevy_reflect,serialize --target {target}"
),
"Please fix compiler errors in output above for bevy_time no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_input_focus --no-default-features --features libm,serialize,bevy_reflect --target {target}"
),
"Please fix compiler errors in output above for bevy_input_focus no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_a11y --no-default-features --features libm,serialize,bevy_reflect --target {target}"
),
"Please fix compiler errors in output above for bevy_a11y no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_diagnostic --no-default-features --features serialize --target {target}"
),
"Please fix compiler errors in output above for bevy_diagnostic no_std compatibility.",
));
commands
}
}

View File

@ -2,7 +2,6 @@ pub use bench_check::*;
pub use clippy::*; pub use clippy::*;
pub use compile::*; pub use compile::*;
pub use compile_check::*; pub use compile_check::*;
pub use compile_check_no_std::*;
pub use compile_fail::*; pub use compile_fail::*;
pub use doc::*; pub use doc::*;
pub use doc_check::*; pub use doc_check::*;
@ -20,7 +19,6 @@ mod bench_check;
mod clippy; mod clippy;
mod compile; mod compile;
mod compile_check; mod compile_check;
mod compile_check_no_std;
mod compile_fail; mod compile_fail;
mod doc; mod doc;
mod doc_check; mod doc_check;