Skip to content

Bare Minimum no_std support for bevy_asset #19070

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

bushrat011899
Copy link
Contributor

@bushrat011899 bushrat011899 commented May 5, 2025

Objective

Solution

  • Added std and web features to bevy_asset
  • Gated all non-no_std dependencies behind std feature
  • Gated substantial functionality behind std primarily at the lib.rs level
  • Ensured all crates depending on bevy_asset enable std and/or web where required
  • Added simple documentation to bevy_asset features
  • Switched from crossbeam_channel to concurrent_queue where required for no_std support
  • Switched from tracing to log where required for no_atomic support
  • Moved AssetSourceId to bevy_asset::path, leaving a re-export so there's no breaking change
  • Refactored AssetPath to use str instead of Path when std is disabled
  • Added bevy_asset feature to no_std_library example to ensure it's tested in CI

Testing

  • CI

Notes

  • View the release notes here
  • This PR is overly restrictive in what requires std, opting to start with some low-hanging-fruit such as the Asset trait and AssetPath. Since the Assets, Handle<T>, Asset, and AssetPath items are all available, a bare-minimum workflow where assets are added individually without the AssetServer is possible. It is my intention to chip away at these std feature gates to bring greater parity.
  • Notable missing items:
    • AssetLoader
    • AssetReader
    • AssetServer
    • AssetSaver

"Most" functionality excluding:
- processor
- io
- saver
- transformer
- loader / loader_builders
- server
@bushrat011899 bushrat011899 added C-Feature A new feature, making something new possible A-Assets Load files from disk to use for things like images, models, and sounds X-Contentious There are nontrivial implications that should be thought through D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward O-Embedded Weird hardware and no_std platforms labels May 5, 2025
Need to configure a custom backend for `no_std` in CI
run: cd examples/no_std/library && cargo check --no-default-features --features libm,critical-section --target x86_64-unknown-none
run: cd examples/no_std/library && RUSTFLAGS='--cfg getrandom_backend="rdrand"' cargo check --no-default-features --features libm,critical-section --target x86_64-unknown-none
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getrandom is a bit frustrating from a library perspective. For no_std support, we need to enable backend via RUSTFLAGS. This is only needed for users on esoteric platforms, but that does make CI a little uglier.

features = [
# "bevy_color",
# "bevy_state",
]
features = ["bevy_color", "bevy_state", "bevy_asset"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enabling these features to ensure they're tested for no_std compatibility in CI.

Comment on lines 55 to 61
pub(crate) struct AssetIndexAllocator {
/// A monotonically increasing index.
next_index: AtomicU32,
recycled_queue_sender: Sender<AssetIndex>,
/// This receives every recycled [`AssetIndex`]. It serves as a buffer/queue to store indices ready for reuse.
recycled_queue_receiver: Receiver<AssetIndex>,
recycled_sender: Sender<AssetIndex>,
recycled_receiver: Receiver<AssetIndex>,
recycled_queue: ConcurrentQueue<AssetIndex>,
recycled: ConcurrentQueue<AssetIndex>,
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since crossbeam_channel isn't no_std compatible, I switched to concurrent_queue for tracking recycled asset indexes. Since the sender and receiver were colocated and never shared outside the type, I actually think concurrent_queue better matches the intended semantics anyway. This does increase the stack size of AssetIndexAllocator though (~1024 bytes instead of ~64). Moving the queues into an Arc<...> would solve that issue if it's contentious.

Comment on lines +18 to +19
#[deprecated(since = "0.17.0", note = "use `bevy_asset::AssetSourceId` instead")]
pub use crate::AssetSourceId;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved AssetSourceId to path.rs to make the feature gating less ugly. I also think it makes more sense to live there anyway, since it's a fundamental component of what we define as an AssetPath.

Comment on lines 157 to 165
#[cfg(feature = "std")]
pub mod io;
pub mod meta;
#[cfg(feature = "std")]
pub mod processor;
#[cfg(feature = "std")]
pub mod saver;
#[cfg(feature = "std")]
pub mod transformer;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These modules, along with loader, loader_builders, and server will require substantial changes to attain no_std compatibility. To make those efforts easier to chip at, I'm just gating them entirely right now and getting the surrounding items compatible first. This will allow more targeted PRs in the future to (hopefully) bring us closer to feature parity.

Comment on lines +177 to +179
#[cfg(feature = "std")]
#[doc(hidden)]
pub use crate::AssetServer;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AssetServer really requires everything else to be no_std compatible first before it can be.

Comment on lines 189 to 192
#[cfg(feature = "std")]
mod loader;
#[cfg(feature = "std")]
mod loader_builders;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future PR: I feel like these modules should be combined into a bevy_asset::loader and bevy_asset::loader::builders (or further split).

Comment on lines +446 to +447
#[cfg(feature = "std")]
self.build_asset_plugin_std(app);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the std-requiring parts of the plugin build function into its own method just to make the feature gating cleaner.

}
}

impl Plugin for AssetPlugin {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's important that AssetPlugin implement Plugin for no_std, as the DefaultPlugins will include AssetPlugin if bevy_asset is enabled on bevy.

Comment on lines +19 to +23
#[cfg(feature = "std")]
type PathInner = Path;

#[cfg(not(feature = "std"))]
type PathInner = str;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future PR: Cart has previously expressed a desire to move away from std::path::Path, as AssetPath shouldn't support platform-specific functionality like Windows prefixes or different path separators. AssetPath should always use str instead of Path, but that will requiring providing our own implementations for common Path operations (components, file_name, etc.).

@alice-i-cecile alice-i-cecile added the M-Needs-Release-Note Work that should be called out in the blog due to impact label May 5, 2025
Copy link
Contributor

github-actions bot commented May 5, 2025

It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note.

Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Assets Load files from disk to use for things like images, models, and sounds C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes M-Needs-Release-Note Work that should be called out in the blog due to impact O-Embedded Weird hardware and no_std platforms S-Needs-Review Needs reviewer attention (from anyone!) to move forward X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants