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
951c4dac7e
commit
99289ad988
@ -159,9 +159,8 @@ impl Plugin for ScheduleRunnerPlugin {
|
||||
} else {
|
||||
loop {
|
||||
match tick(&mut app, wait) {
|
||||
Ok(Some(_delay)) => {
|
||||
#[cfg(feature = "std")]
|
||||
std::thread::sleep(_delay);
|
||||
Ok(Some(delay)) => {
|
||||
bevy_platform_support::thread::sleep(delay);
|
||||
}
|
||||
Ok(None) => continue,
|
||||
Err(exit) => return exit,
|
||||
|
@ -17,6 +17,7 @@ extern crate alloc;
|
||||
|
||||
pub mod hash;
|
||||
pub mod sync;
|
||||
pub mod thread;
|
||||
pub mod time;
|
||||
|
||||
#[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.
|
||||
#[must_use]
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user