From a151ae5b8aa08f8969d5c40713e15dc79ff7baac Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Wed, 11 Jun 2025 15:37:56 -0500 Subject: [PATCH] Rework updates of application metadata gameplay hours Rely on `AppHost` to more accurately track active gameplay time instead of doing naive DateTime.UtcNow subtraction in UpdatePre/UpdatePostGame() calls. --- src/Ryujinx/Systems/AppHost.cs | 14 ++++++++------ .../Systems/AppLibrary/ApplicationMetadata.cs | 17 +++-------------- .../UI/ViewModels/MainWindowViewModel.cs | 4 ++-- 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/Ryujinx/Systems/AppHost.cs b/src/Ryujinx/Systems/AppHost.cs index 94c2f2900..1c5f64309 100644 --- a/src/Ryujinx/Systems/AppHost.cs +++ b/src/Ryujinx/Systems/AppHost.cs @@ -75,7 +75,7 @@ namespace Ryujinx.Ava.Systems private readonly long _ticksPerFrame; private readonly Stopwatch _chrono; - private readonly Stopwatch _pauseTimer; + private readonly Stopwatch _playTimer; private long _ticks; private readonly AccountManager _accountManager; @@ -176,7 +176,7 @@ namespace Ryujinx.Ava.Systems _chrono = new Stopwatch(); _ticksPerFrame = Stopwatch.Frequency / TargetFps; - _pauseTimer = new Stopwatch(); + _playTimer = new Stopwatch(); if (ApplicationPath.StartsWith("@SystemContent")) { @@ -567,6 +567,7 @@ namespace Ryujinx.Ava.Systems public void Stop() { _isActive = false; + _playTimer.Stop(); } private void Exit() @@ -618,7 +619,7 @@ namespace Ryujinx.Ava.Systems private void Dispose() { if (Device.Processes != null) - MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText, _pauseTimer.Elapsed); + MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText, _playTimer.Elapsed); ConfigurationState.Instance.System.IgnoreMissingServices.Event -= UpdateIgnoreMissingServicesState; ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState; @@ -637,7 +638,7 @@ namespace Ryujinx.Ava.Systems _gpuCancellationTokenSource.Dispose(); _chrono.Stop(); - _pauseTimer.Stop(); + _playTimer.Stop(); } public void DisposeGpu() @@ -871,6 +872,7 @@ namespace Ryujinx.Ava.Systems ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata => appMetadata.UpdatePreGame() ); + _playTimer.Start(); return true; } @@ -880,7 +882,7 @@ namespace Ryujinx.Ava.Systems Device?.System.TogglePauseEmulation(false); _viewModel.IsPaused = false; - _pauseTimer.Stop(); + _playTimer.Start(); _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI); Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed"); } @@ -890,7 +892,7 @@ namespace Ryujinx.Ava.Systems Device?.System.TogglePauseEmulation(true); _viewModel.IsPaused = true; - _pauseTimer.Start(); + _playTimer.Stop(); _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI, LocaleManager.Instance[LocaleKeys.Paused]); Logger.Info?.Print(LogClass.Emulation, "Emulation was paused"); } diff --git a/src/Ryujinx/Systems/AppLibrary/ApplicationMetadata.cs b/src/Ryujinx/Systems/AppLibrary/ApplicationMetadata.cs index e80fae009..8940657b0 100644 --- a/src/Ryujinx/Systems/AppLibrary/ApplicationMetadata.cs +++ b/src/Ryujinx/Systems/AppLibrary/ApplicationMetadata.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Text.Json.Serialization; namespace Ryujinx.Ava.Systems.AppLibrary @@ -34,21 +33,11 @@ namespace Ryujinx.Ava.Systems.AppLibrary /// /// Updates and . Call this after a game ends. /// - /// The amount of time emulation was paused while playing. - public void UpdatePostGame(TimeSpan pauseTime) + /// The active gameplay time this past session. + public void UpdatePostGame(TimeSpan playTime) { - DateTime? prevLastPlayed = LastPlayed; UpdatePreGame(); - - if (!prevLastPlayed.HasValue) - { - return; - } - - TimeSpan diff = DateTime.UtcNow - prevLastPlayed.Value; - Debug.Assert(pauseTime <= diff); - double newTotalSeconds = TimePlayed.Add(diff - pauseTime).TotalSeconds; - TimePlayed = TimeSpan.FromSeconds(Math.Round(newTotalSeconds, MidpointRounding.AwayFromZero)); + TimePlayed += playTime; } } } diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 1ea9d009d..5e7df4d62 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -1688,8 +1688,8 @@ namespace Ryujinx.Ava.UI.ViewModels RendererHostControl.Focus(); }); - public static void UpdateGameMetadata(string titleId, TimeSpan pauseTime) - => ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => appMetadata.UpdatePostGame(pauseTime)); + public static void UpdateGameMetadata(string titleId, TimeSpan playTime) + => ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => appMetadata.UpdatePostGame(playTime)); public void RefreshFirmwareStatus() {