Add TimeUpdateStrategy resource for manual Time updating (#6159)
# Objective - Addresses #6146 by allowing manual `Time` updating ## Solution - Create `TimeUpdateStrategy` config resource - Allow users to specify a manual `Instant/Duration` or leave as default (automatic) - Get resource in `bevy_time::time_system`and update time with desired value --- ## Changelog - Add `TimeUpdateStrategy` resource - Update `bevy_time::time_system` to use optional manual values Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Lucidus115 <92978847+Lucidus115@users.noreply.github.com>
This commit is contained in:
parent
9066d51420
commit
f7d3fbc7d5
@ -9,8 +9,8 @@ pub use stopwatch::*;
|
||||
pub use time::*;
|
||||
pub use timer::*;
|
||||
|
||||
use bevy_ecs::system::{Local, Res, ResMut};
|
||||
use bevy_utils::{tracing::warn, Instant};
|
||||
use bevy_ecs::system::{Res, ResMut};
|
||||
use bevy_utils::{tracing::warn, Duration, Instant};
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
|
||||
pub mod prelude {
|
||||
@ -34,6 +34,7 @@ pub struct TimeSystem;
|
||||
impl Plugin for TimePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<Time>()
|
||||
.init_resource::<TimeUpdateStrategy>()
|
||||
.init_resource::<FixedTimesteps>()
|
||||
.register_type::<Timer>()
|
||||
.register_type::<Time>()
|
||||
@ -44,6 +45,20 @@ impl Plugin for TimePlugin {
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration resource used to determine how the time system should run.
|
||||
///
|
||||
/// For most cases, [`TimeUpdateStrategy::Automatic`] is fine. When writing tests, dealing with networking, or similar
|
||||
/// you may prefer to set the next [`Time`] value manually.
|
||||
#[derive(Resource, Default)]
|
||||
pub enum TimeUpdateStrategy {
|
||||
#[default]
|
||||
Automatic,
|
||||
// Update [`Time`] with an exact `Instant` value
|
||||
ManualInstant(Instant),
|
||||
// Update [`Time`] with the current time + a specified `Duration`
|
||||
ManualDuration(Duration),
|
||||
}
|
||||
|
||||
/// Channel resource used to receive time from render world
|
||||
#[derive(Resource)]
|
||||
pub struct TimeReceiver(pub Receiver<Instant>);
|
||||
@ -64,18 +79,26 @@ pub fn create_time_channels() -> (TimeSender, TimeReceiver) {
|
||||
/// there to this system through channels. Otherwise the time is updated in this system.
|
||||
fn time_system(
|
||||
mut time: ResMut<Time>,
|
||||
update_strategy: Res<TimeUpdateStrategy>,
|
||||
time_recv: Option<Res<TimeReceiver>>,
|
||||
mut has_received_time: Local<bool>,
|
||||
) {
|
||||
if let Some(time_recv) = time_recv {
|
||||
let new_time = if let Some(time_recv) = time_recv {
|
||||
// TODO: Figure out how to handle this when using pipelined rendering.
|
||||
if let Ok(new_time) = time_recv.0.try_recv() {
|
||||
time.update_with_instant(new_time);
|
||||
*has_received_time = true;
|
||||
} else if *has_received_time {
|
||||
new_time
|
||||
} else {
|
||||
warn!("time_system did not receive the time from the render world! Calculations depending on the time may be incorrect.");
|
||||
Instant::now()
|
||||
}
|
||||
} else {
|
||||
time.update();
|
||||
Instant::now()
|
||||
};
|
||||
|
||||
match update_strategy.as_ref() {
|
||||
TimeUpdateStrategy::Automatic => time.update_with_instant(new_time),
|
||||
TimeUpdateStrategy::ManualInstant(instant) => time.update_with_instant(*instant),
|
||||
TimeUpdateStrategy::ManualDuration(duration) => {
|
||||
time.update_with_instant(Instant::now() + *duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user