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.
This commit is contained in:
Mahmoud Al-Qudsi 2025-06-11 15:37:56 -05:00 committed by GreemDev
parent 84758d0ddc
commit a151ae5b8a
3 changed files with 13 additions and 22 deletions

View file

@ -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");
}

View file

@ -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
/// <summary>
/// Updates <see cref="LastPlayed"/> and <see cref="TimePlayed"/>. Call this after a game ends.
/// </summary>
/// <param name="pauseTime">The amount of time emulation was paused while playing.</param>
public void UpdatePostGame(TimeSpan pauseTime)
/// <param name="playTime">The active gameplay time this past session.</param>
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;
}
}
}

View file

@ -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()
{