Skip to content

Commit 79d58be

Browse files
authored
Updated handle_delayed_save to use Res<Time<Real>> instead of Res<Time>. (#25599)
# Objective - Fixes #25571 ## Solution - Made the change as described in the title. - This ensures the delayed save timer ticks using real elapsed time rather than virtual game time, allowing settings to save even when the game is paused. ## Testing - Verified that it works correctly through manual testing using the reproduction code below. ### Reproduction code ```rust //! issue_25571 use std::time::Duration; use bevy::{ prelude::*, settings::{ReflectSettingsGroup, SaveSettingsDeferred, SettingsGroup, SettingsPlugin}, }; fn main() { App::new() .add_plugins((DefaultPlugins, SettingsPlugin::new("issue_25571"))) .add_systems(Startup, setup) .add_systems(Update, trigger_save) .run(); } #[derive(Resource, SettingsGroup, Reflect, Default)] #[reflect(Resource, SettingsGroup, Default)] struct MySettings { volume: f32, } fn setup(mut settings: ResMut<MySettings>, mut time: ResMut<Time<Virtual>>) { settings.volume = 0.5; time.pause(); } fn trigger_save(mut commands: Commands, mut executed: Local<bool>) { if !*executed { commands.queue(SaveSettingsDeferred(Duration::from_secs(1))); *executed = true; } } ``` ### Output ```toml [my_settings] volume = 0.5 ```
1 parent c2b98c8 commit 79d58be

1 file changed

Lines changed: 36 additions & 3 deletions

File tree

  • crates/bevy_settings/src

crates/bevy_settings/src/lib.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ mod store_fs;
3030
#[cfg(target_arch = "wasm32")]
3131
mod store_wasm;
3232

33-
use bevy_time::{Time, Timer, TimerMode};
33+
use bevy_time::{Real, Time, Timer, TimerMode};
3434
use serde::de::DeserializeSeed;
3535
#[cfg(not(target_arch = "wasm32"))]
3636
use store_fs::SettingsStore;
@@ -612,7 +612,7 @@ fn load_properties(value: &toml::Value, resource: &mut dyn PartialReflect, types
612612

613613
fn handle_delayed_save(
614614
mut settings: ResMut<SettingsFileRegistry>,
615-
time: Res<Time>,
615+
time: Res<Time<Real>>,
616616
mut commands: Commands,
617617
) {
618618
settings.save_timer.tick(time.delta());
@@ -624,8 +624,9 @@ fn handle_delayed_save(
624624
#[cfg(test)]
625625
mod tests {
626626
use super::*;
627-
use bevy_ecs::change_detection::Tick;
627+
use bevy_ecs::{change_detection::Tick, schedule::Schedule};
628628
use bevy_reflect::Reflect;
629+
use bevy_time::Virtual;
629630
// Required to make proc macros work in bevy itself.
630631
extern crate self as bevy_settings;
631632

@@ -1078,4 +1079,36 @@ mod tests {
10781079
let refresh_rate = world.get_resource::<CounterRefreshRateSettings>().unwrap();
10791080
assert_eq!(*refresh_rate, CounterRefreshRateSettings::Fast);
10801081
}
1082+
1083+
#[test]
1084+
fn test_handle_delayed_save_ticks_with_real_time_while_paused() {
1085+
let mut world = World::new();
1086+
world.insert_resource(Time::<Real>::default());
1087+
world.insert_resource(Time::<Virtual>::default());
1088+
// Virtual time is paused, so the delayed save timer must use real time.
1089+
world.resource_mut::<Time<Virtual>>().pause();
1090+
1091+
// SettingsFileRegistry with a delayed save timer
1092+
world.insert_resource(SettingsFileRegistry {
1093+
app_name: "test_app".to_string(),
1094+
files: HashMap::new(),
1095+
save_timer: {
1096+
let mut timer = Timer::new(Duration::from_millis(500), TimerMode::Once);
1097+
timer.unpause();
1098+
timer
1099+
},
1100+
});
1101+
1102+
// Simulate real time advancing
1103+
world
1104+
.resource_mut::<Time<Real>>()
1105+
.advance_by(Duration::from_millis(600));
1106+
1107+
let mut schedule = Schedule::default();
1108+
schedule.add_systems(handle_delayed_save);
1109+
schedule.run(&mut world);
1110+
1111+
let registry = world.resource::<SettingsFileRegistry>();
1112+
assert!(registry.save_timer.just_finished());
1113+
}
10811114
}

0 commit comments

Comments
 (0)