Skip to content

Commit

Permalink
Create bevy_platform_support Crate (#17250)
Browse files Browse the repository at this point in the history
# Objective

- Contributes to #16877

## Solution

- Initial creation of `bevy_platform_support` crate.
- Moved `bevy_utils::Instant` into new `bevy_platform_support` crate.
- Moved `portable-atomic`, `portable-atomic-util`, and
`critical-section` into new `bevy_platform_support` crate.

## Testing

- CI

---

## Showcase

Instead of needing code like this to import an `Arc`:

```rust
#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;

#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;
```

We can now use:

```rust
use bevy_platform_support::sync::Arc;
```

This applies to many other types, but the goal is overall the same:
allowing crates to use `std`-like types without the boilerplate of
conditional compilation and platform-dependencies.

## Migration Guide

- Replace imports of `bevy_utils::Instant` with
`bevy_platform_support::time::Instant`
- Replace imports of `bevy::utils::Instant` with
`bevy::platform_support::time::Instant`

## Notes

- `bevy_platform_support` hasn't been reserved on `crates.io`
- ~~`bevy_platform_support` is not re-exported from `bevy` at this time.
It may be worthwhile exporting this crate, but I am unsure of a
reasonable name to export it under (`platform_support` may be a bit
wordy for user-facing).~~
- I've included an implementation of `Instant` which is suitable for
`no_std` platforms that are not Wasm for the sake of eliminating feature
gates around its use. It may be a controversial inclusion, so I'm happy
to remove it if required.
- There are many other items (`spin`, `bevy_utils::Sync(Unsafe)Cell`,
etc.) which should be added to this crate. I have kept the initial scope
small to demonstrate utility without making this too unwieldy.

---------

Co-authored-by: TimJentzsch <[email protected]>
Co-authored-by: Chris Russell <[email protected]>
Co-authored-by: François Mockers <[email protected]>
  • Loading branch information
4 people authored Jan 20, 2025
1 parent edb34cd commit a64446b
Show file tree
Hide file tree
Showing 57 changed files with 586 additions and 197 deletions.
15 changes: 6 additions & 9 deletions crates/bevy_app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,25 @@ std = [
"downcast-rs/std",
"bevy_utils/std",
"bevy_tasks?/std",
"bevy_platform_support/std",
]

## `critical-section` provides the building blocks for synchronization primitives
## on all platforms, including `no_std`.
critical-section = [
"portable-atomic?/critical-section",
"bevy_tasks?/critical-section",
"bevy_ecs/critical-section",
"bevy_platform_support/critical-section",
"bevy_reflect?/critical-section",
]

## `portable-atomic` provides additional platform support for atomic types and
## operations, even on targets without native support.
portable-atomic = [
"dep:portable-atomic",
"dep:portable-atomic-util",
"bevy_tasks?/portable-atomic",
"bevy_ecs/portable-atomic",
"bevy_platform_support/portable-atomic",
"bevy_reflect?/portable-atomic",
]

[dependencies]
Expand All @@ -76,19 +78,14 @@ bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features
"alloc",
] }
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, optional = true }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false }

# other
downcast-rs = { version = "2", default-features = false }
thiserror = { version = "2", default-features = false }
variadics_please = "1.1"
tracing = { version = "0.1", default-features = false, optional = true }
log = { version = "0.4", default-features = false }
portable-atomic = { version = "1", default-features = false, features = [
"fallback",
], optional = true }
portable-atomic-util = { version = "0.2.4", features = [
"alloc",
], optional = true }

[target.'cfg(any(unix, windows))'.dependencies]
ctrlc = { version = "3.4.4", optional = true }
Expand Down
7 changes: 1 addition & 6 deletions crates/bevy_app/src/schedule_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ use crate::{
plugin::Plugin,
PluginsState,
};
use bevy_platform_support::time::Instant;
use core::time::Duration;

#[cfg(any(target_arch = "wasm32", feature = "std"))]
use bevy_utils::Instant;

#[cfg(target_arch = "wasm32")]
use {
alloc::{boxed::Box, rc::Rc},
Expand Down Expand Up @@ -100,7 +98,6 @@ impl Plugin for ScheduleRunnerPlugin {
let tick = move |app: &mut App,
_wait: Option<Duration>|
-> Result<Option<Duration>, AppExit> {
#[cfg(any(target_arch = "wasm32", feature = "std"))]
let start_time = Instant::now();

app.update();
Expand All @@ -109,10 +106,8 @@ impl Plugin for ScheduleRunnerPlugin {
return Err(exit);
};

#[cfg(any(target_arch = "wasm32", feature = "std"))]
let end_time = Instant::now();

#[cfg(any(target_arch = "wasm32", feature = "std"))]
if let Some(wait) = _wait {
let exe_time = end_time - start_time;
if exe_time < wait {
Expand Down
9 changes: 2 additions & 7 deletions crates/bevy_app/src/task_pool_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,21 @@
feature = "portable-atomic",
expect(
clippy::redundant_closure,
reason = "portable_atomic_util::Arc has subtly different implicit behavior"
reason = "bevy_platform_support::sync::Arc has subtly different implicit behavior"
)
)]

use crate::{App, Plugin};

use alloc::string::ToString;
use bevy_platform_support::sync::Arc;
use bevy_tasks::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, TaskPoolBuilder};
use core::{fmt::Debug, marker::PhantomData};
use log::trace;

#[cfg(not(target_arch = "wasm32"))]
use {crate::Last, bevy_ecs::prelude::NonSend};

#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;

#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;

#[cfg(not(target_arch = "wasm32"))]
use bevy_tasks::tick_global_task_pools_on_main_thread;

Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_core_pipeline/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" }
bevy_window = { path = "../bevy_window", version = "0.16.0-dev" }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [
"std",
] }

serde = { version = "1", features = ["derive"] }
bitflags = "2.3"
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_core_pipeline/src/oit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, Handle};
use bevy_ecs::{component::*, prelude::*};
use bevy_math::UVec2;
use bevy_platform_support::time::Instant;
use bevy_reflect::Reflect;
use bevy_render::{
camera::{Camera, ExtractedCamera},
Expand All @@ -16,7 +17,7 @@ use bevy_render::{
view::Msaa,
Render, RenderApp, RenderSet,
};
use bevy_utils::{HashSet, Instant};
use bevy_utils::HashSet;
use bevy_window::PrimaryWindow;
use resolve::{
node::{OitResolveNode, OitResolvePass},
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_diagnostic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_time = { path = "../bevy_time", version = "0.16.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev" }
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev" }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [
"std",
] }

# other
const-fnv1a-hash = "1.1.0"
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_diagnostic/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use core::{

use bevy_app::{App, SubApp};
use bevy_ecs::system::{Deferred, Res, Resource, SystemBuffer, SystemParam};
use bevy_utils::{HashMap, Instant, PassHash};
use bevy_platform_support::time::Instant;
use bevy_utils::{HashMap, PassHash};
use const_fnv1a_hash::fnv1a_hash_str_64;

use crate::DEFAULT_MAX_HISTORY_LENGTH;
Expand Down
19 changes: 8 additions & 11 deletions crates/bevy_ecs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,24 +76,25 @@ std = [
"nonmax/std",
"arrayvec?/std",
"log/std",
"bevy_platform_support/std",
]

## `critical-section` provides the building blocks for synchronization primitives
## on all platforms, including `no_std`.
critical-section = [
"dep:critical-section",
"bevy_tasks?/critical-section",
"portable-atomic?/critical-section",
"bevy_platform_support/critical-section",
"bevy_reflect?/critical-section",
]

## `portable-atomic` provides additional platform support for atomic types and
## operations, even on targets without native support.
portable-atomic = [
"dep:portable-atomic",
"dep:portable-atomic-util",
"bevy_tasks?/portable-atomic",
"bevy_platform_support/portable-atomic",
"concurrent-queue/portable-atomic",
"spin/portable_atomic",
"bevy_reflect?/portable-atomic",
]

[dependencies]
Expand All @@ -104,6 +105,9 @@ bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features
"alloc",
] }
bevy_ecs_macros = { path = "macros", version = "0.16.0-dev" }
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [
"alloc",
] }

bitflags = { version = "2.3", default-features = false }
concurrent-queue = { version = "2.5.0", default-features = false }
Expand All @@ -124,13 +128,6 @@ arrayvec = { version = "0.7.4", default-features = false, optional = true }
smallvec = { version = "1", features = ["union"] }
indexmap = { version = "2.5.0", default-features = false }
variadics_please = { version = "1.1", default-features = false }
critical-section = { version = "1.2.0", optional = true }
portable-atomic = { version = "1", default-features = false, features = [
"fallback",
], optional = true }
portable-atomic-util = { version = "0.2.4", features = [
"alloc",
], optional = true }
spin = { version = "0.9.8", default-features = false, features = [
"spin_mutex",
"rwlock",
Expand Down
7 changes: 1 addition & 6 deletions crates/bevy_ecs/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{
use alloc::boxed::Box;
use alloc::{borrow::Cow, format, vec::Vec};
pub use bevy_ecs_macros::Component;
use bevy_platform_support::sync::Arc;
use bevy_ptr::{OwningPtr, UnsafeCellDeref};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect;
Expand All @@ -32,12 +33,6 @@ use core::{
use disqualified::ShortName;
use thiserror::Error;

#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;

#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;

pub use bevy_ecs_macros::require;

/// A data type that can be used to store data for an [entity].
Expand Down
10 changes: 2 additions & 8 deletions crates/bevy_ecs/src/entity/clone_entities.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
use alloc::{borrow::ToOwned, vec::Vec};
use bevy_platform_support::sync::Arc;
use bevy_ptr::{Ptr, PtrMut};
use bevy_utils::{HashMap, HashSet};
use bumpalo::Bump;
use core::{any::TypeId, ptr::NonNull};

use bevy_utils::{HashMap, HashSet};

#[cfg(feature = "bevy_reflect")]
use alloc::boxed::Box;

#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;

#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;

use crate::{
bundle::Bundle,
component::{Component, ComponentCloneHandler, ComponentId, ComponentInfo, Components},
Expand Down
6 changes: 1 addition & 5 deletions crates/bevy_ecs/src/entity/entity_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ use core::{

use super::Entity;

#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;

#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;
use bevy_platform_support::sync::Arc;

/// A trait for entity borrows.
///
Expand Down
19 changes: 5 additions & 14 deletions crates/bevy_ecs/src/entity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use crate::{
storage::{SparseSetIndex, TableId, TableRow},
};
use alloc::vec::Vec;
use bevy_platform_support::sync::atomic::Ordering;
use core::{fmt, hash::Hash, mem, num::NonZero};
use log::warn;

Expand All @@ -79,26 +80,16 @@ use core::panic::Location;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};

#[cfg(not(feature = "portable-atomic"))]
use core::sync::atomic::Ordering;

#[cfg(feature = "portable-atomic")]
use portable_atomic::Ordering;

#[cfg(all(target_has_atomic = "64", not(feature = "portable-atomic")))]
use core::sync::atomic::AtomicI64 as AtomicIdCursor;
#[cfg(all(target_has_atomic = "64", feature = "portable-atomic"))]
use portable_atomic::AtomicI64 as AtomicIdCursor;
#[cfg(target_has_atomic = "64")]
use bevy_platform_support::sync::atomic::AtomicI64 as AtomicIdCursor;
#[cfg(target_has_atomic = "64")]
type IdCursor = i64;

/// Most modern platforms support 64-bit atomics, but some less-common platforms
/// do not. This fallback allows compilation using a 32-bit cursor instead, with
/// the caveat that some conversions may fail (and panic) at runtime.
#[cfg(all(not(target_has_atomic = "64"), not(feature = "portable-atomic")))]
use core::sync::atomic::AtomicIsize as AtomicIdCursor;
#[cfg(all(not(target_has_atomic = "64"), feature = "portable-atomic"))]
use portable_atomic::AtomicIsize as AtomicIdCursor;
#[cfg(not(target_has_atomic = "64"))]
use bevy_platform_support::sync::atomic::AtomicIsize as AtomicIdCursor;
#[cfg(not(target_has_atomic = "64"))]
type IdCursor = isize;

Expand Down
7 changes: 1 addition & 6 deletions crates/bevy_ecs/src/schedule/executor/multi_threaded.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloc::{boxed::Box, vec::Vec};
use bevy_platform_support::sync::Arc;
use bevy_tasks::{ComputeTaskPool, Scope, TaskPool, ThreadExecutor};
use bevy_utils::{default, syncunsafecell::SyncUnsafeCell};
use concurrent_queue::ConcurrentQueue;
Expand All @@ -12,12 +13,6 @@ use std::{
#[cfg(feature = "trace")]
use tracing::{info_span, Span};

#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;

#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;

use crate::{
archetype::ArchetypeComponentId,
prelude::Resource,
Expand Down
7 changes: 1 addition & 6 deletions crates/bevy_ecs/src/world/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ use crate::{
system::{ExclusiveSystemParam, ReadOnlySystemParam, SystemMeta, SystemParam},
world::{FromWorld, World},
};

#[cfg(not(feature = "portable-atomic"))]
use core::sync::atomic::{AtomicUsize, Ordering};

#[cfg(feature = "portable-atomic")]
use portable_atomic::{AtomicUsize, Ordering};
use bevy_platform_support::sync::atomic::{AtomicUsize, Ordering};

use super::unsafe_world_cell::UnsafeWorldCell;

Expand Down
14 changes: 3 additions & 11 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,15 @@ use crate::{
},
};
use alloc::{boxed::Box, vec::Vec};
use bevy_platform_support::sync::atomic::{AtomicU32, Ordering};
use bevy_ptr::{OwningPtr, Ptr};
use core::{any::TypeId, fmt};
use core::{any::TypeId, fmt, panic::Location};
use log::warn;

#[cfg(not(feature = "portable-atomic"))]
use core::sync::atomic::{AtomicU32, Ordering};

#[cfg(feature = "portable-atomic")]
use portable_atomic::{AtomicU32, Ordering};
use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell};

#[cfg(feature = "track_location")]
use bevy_ptr::UnsafeCellDeref;

use core::panic::Location;

use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell};

/// Stores and exposes operations on [entities](Entity), [components](Component), resources,
/// and their associated metadata.
///
Expand Down
12 changes: 3 additions & 9 deletions crates/bevy_ecs/src/world/unsafe_world_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,13 @@ use crate::{
system::Resource,
world::RawCommandQueue,
};
use bevy_platform_support::sync::atomic::Ordering;
use bevy_ptr::Ptr;
#[cfg(feature = "track_location")]
use bevy_ptr::UnsafeCellDeref;
#[cfg(feature = "track_location")]
use core::panic::Location;
use core::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData, ptr};
use thiserror::Error;

#[cfg(not(feature = "portable-atomic"))]
use core::sync::atomic::Ordering;

#[cfg(feature = "portable-atomic")]
use portable_atomic::Ordering;
#[cfg(feature = "track_location")]
use {bevy_ptr::UnsafeCellDeref, core::panic::Location};

/// Variant of the [`World`] where resource and component accesses take `&self`, and the responsibility to avoid
/// aliasing violations are given to the caller instead of being checked at compile-time by rust's unique XOR shared rule.
Expand Down
Loading

0 comments on commit a64446b

Please sign in to comment.