Add sleep
based on spin
to bevy_platform_support
(#18633)
# Objective - Fixes #18617 ## Solution - Added `thread::sleep` to `bevy_platform_support` using a spin-based fallback. - Fixed bug in `bevy_platform_support::time::Instant::elapsed` (comparison was backwards) - Switched `ScheduleRunnerPlugin` to use `bevy_platform_support:🧵:sleep` on `std` and `no_std` platforms (WASM + Browser excluded) ## Testing - Ran reproduction code from @mockersf in linked issue and confirmed a consistent 60 counts per `println!`. --- ## Notes - I chose to add `bevy_platform_support:🧵:sleep` instead of putting the fix in-line within `ScheduleRunnerPlugin` to keep the separation of concerns clean. `sleep` is only used in one other location in Bevy, `bevy_asset`, but I have decided to leave that as-is since `bevy_asset` isn't `no_std` compatible anyway. - The bug in `bevy_platform_support::time::Instant::elapsed` wasn't the cause of this issue, but it did prevent this fix from working so I have included the it in this PR.
This commit is contained in:
parent
bdfd7a3443
commit
7925e03f7f
@ -159,9 +159,8 @@ impl Plugin for ScheduleRunnerPlugin {
|
|||||||
} else {
|
} else {
|
||||||
loop {
|
loop {
|
||||||
match tick(&mut app, wait) {
|
match tick(&mut app, wait) {
|
||||||
Ok(Some(_delay)) => {
|
Ok(Some(delay)) => {
|
||||||
#[cfg(feature = "std")]
|
bevy_platform_support::thread::sleep(delay);
|
||||||
std::thread::sleep(_delay);
|
|
||||||
}
|
}
|
||||||
Ok(None) => continue,
|
Ok(None) => continue,
|
||||||
Err(exit) => return exit,
|
Err(exit) => return exit,
|
||||||
|
@ -17,6 +17,7 @@ extern crate alloc;
|
|||||||
|
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
|
pub mod thread;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
29
crates/bevy_platform_support/src/thread.rs
Normal file
29
crates/bevy_platform_support/src/thread.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//! Provides `sleep` for all platforms.
|
||||||
|
|
||||||
|
pub use thread::sleep;
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
// TODO: use browser timeouts based on ScheduleRunnerPlugin::build
|
||||||
|
if #[cfg(feature = "std")] {
|
||||||
|
use std::thread;
|
||||||
|
} else {
|
||||||
|
mod fallback {
|
||||||
|
use core::{hint::spin_loop, time::Duration};
|
||||||
|
|
||||||
|
use crate::time::Instant;
|
||||||
|
|
||||||
|
/// Puts the current thread to sleep for at least the specified amount of time.
|
||||||
|
///
|
||||||
|
/// As this is a `no_std` fallback implementation, this will spin the current thread.
|
||||||
|
pub fn sleep(dur: Duration) {
|
||||||
|
let start = Instant::now();
|
||||||
|
|
||||||
|
while start.elapsed() < dur {
|
||||||
|
spin_loop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use fallback as thread;
|
||||||
|
}
|
||||||
|
}
|
@ -80,7 +80,7 @@ impl Instant {
|
|||||||
/// Returns the amount of time elapsed since this instant.
|
/// Returns the amount of time elapsed since this instant.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn elapsed(&self) -> Duration {
|
pub fn elapsed(&self) -> Duration {
|
||||||
self.saturating_duration_since(Instant::now())
|
Instant::now().saturating_duration_since(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
|
/// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
|
||||||
|
Loading…
Reference in New Issue
Block a user