|
|
@@ -6,27 +6,27 @@ using System.Collections.Generic;
|
|
|
using System.Globalization;
|
|
|
using System.Linq;
|
|
|
|
|
|
-namespace Ryujinx.Ava.Utilities
|
|
|
+namespace Ryujinx.Ava.Utilities.PlayReport
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// The entrypoint for the Play Report analysis system.
|
|
|
/// </summary>
|
|
|
- public class PlayReportAnalyzer
|
|
|
+ public class Analyzer
|
|
|
{
|
|
|
- private readonly List<PlayReportGameSpec> _specs = [];
|
|
|
+ private readonly List<GameSpec> _specs = [];
|
|
|
|
|
|
/// <summary>
|
|
|
/// Add an analysis spec matching a specific game by title ID, with the provided spec configuration.
|
|
|
/// </summary>
|
|
|
/// <param name="titleId">The ID of the game to listen to Play Reports in.</param>
|
|
|
/// <param name="transform">The configuration function for the analysis spec.</param>
|
|
|
- /// <returns>The current <see cref="PlayReportAnalyzer"/>, for chaining convenience.</returns>
|
|
|
- public PlayReportAnalyzer AddSpec(string titleId, Func<PlayReportGameSpec, PlayReportGameSpec> transform)
|
|
|
+ /// <returns>The current <see cref="Analyzer"/>, for chaining convenience.</returns>
|
|
|
+ public Analyzer AddSpec(string titleId, Func<GameSpec, GameSpec> transform)
|
|
|
{
|
|
|
Guard.Ensure(ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _),
|
|
|
- $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(PlayReportGameSpec)}.");
|
|
|
+ $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}.");
|
|
|
|
|
|
- _specs.Add(transform(new PlayReportGameSpec { TitleIds = [titleId] }));
|
|
|
+ _specs.Add(transform(new GameSpec { TitleIds = [titleId] }));
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
@@ -35,13 +35,13 @@ namespace Ryujinx.Ava.Utilities
|
|
|
/// </summary>
|
|
|
/// <param name="titleId">The ID of the game to listen to Play Reports in.</param>
|
|
|
/// <param name="transform">The configuration function for the analysis spec.</param>
|
|
|
- /// <returns>The current <see cref="PlayReportAnalyzer"/>, for chaining convenience.</returns>
|
|
|
- public PlayReportAnalyzer AddSpec(string titleId, Action<PlayReportGameSpec> transform)
|
|
|
+ /// <returns>The current <see cref="Analyzer"/>, for chaining convenience.</returns>
|
|
|
+ public Analyzer AddSpec(string titleId, Action<GameSpec> transform)
|
|
|
{
|
|
|
Guard.Ensure(ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _),
|
|
|
- $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(PlayReportGameSpec)}.");
|
|
|
+ $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}.");
|
|
|
|
|
|
- _specs.Add(new PlayReportGameSpec { TitleIds = [titleId] }.Apply(transform));
|
|
|
+ _specs.Add(new GameSpec { TitleIds = [titleId] }.Apply(transform));
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
@@ -50,15 +50,15 @@ namespace Ryujinx.Ava.Utilities
|
|
|
/// </summary>
|
|
|
/// <param name="titleIds">The IDs of the games to listen to Play Reports in.</param>
|
|
|
/// <param name="transform">The configuration function for the analysis spec.</param>
|
|
|
- /// <returns>The current <see cref="PlayReportAnalyzer"/>, for chaining convenience.</returns>
|
|
|
- public PlayReportAnalyzer AddSpec(IEnumerable<string> titleIds,
|
|
|
- Func<PlayReportGameSpec, PlayReportGameSpec> transform)
|
|
|
+ /// <returns>The current <see cref="Analyzer"/>, for chaining convenience.</returns>
|
|
|
+ public Analyzer AddSpec(IEnumerable<string> titleIds,
|
|
|
+ Func<GameSpec, GameSpec> transform)
|
|
|
{
|
|
|
string[] tids = titleIds.ToArray();
|
|
|
Guard.Ensure(tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _)),
|
|
|
- $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(PlayReportGameSpec)}.");
|
|
|
+ $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}.");
|
|
|
|
|
|
- _specs.Add(transform(new PlayReportGameSpec { TitleIds = [..tids] }));
|
|
|
+ _specs.Add(transform(new GameSpec { TitleIds = [..tids] }));
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
@@ -67,20 +67,20 @@ namespace Ryujinx.Ava.Utilities
|
|
|
/// </summary>
|
|
|
/// <param name="titleIds">The IDs of the games to listen to Play Reports in.</param>
|
|
|
/// <param name="transform">The configuration function for the analysis spec.</param>
|
|
|
- /// <returns>The current <see cref="PlayReportAnalyzer"/>, for chaining convenience.</returns>
|
|
|
- public PlayReportAnalyzer AddSpec(IEnumerable<string> titleIds, Action<PlayReportGameSpec> transform)
|
|
|
+ /// <returns>The current <see cref="Analyzer"/>, for chaining convenience.</returns>
|
|
|
+ public Analyzer AddSpec(IEnumerable<string> titleIds, Action<GameSpec> transform)
|
|
|
{
|
|
|
string[] tids = titleIds.ToArray();
|
|
|
Guard.Ensure(tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _)),
|
|
|
- $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(PlayReportGameSpec)}.");
|
|
|
+ $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}.");
|
|
|
|
|
|
- _specs.Add(new PlayReportGameSpec { TitleIds = [..tids] }.Apply(transform));
|
|
|
+ _specs.Add(new GameSpec { TitleIds = [..tids] }.Apply(transform));
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Runs the configured <see cref="PlayReportGameSpec.FormatterSpec"/> for the specified game title ID.
|
|
|
+ /// Runs the configured <see cref="GameSpec.FormatterSpec"/> for the specified game title ID.
|
|
|
/// </summary>
|
|
|
/// <param name="runningGameId">The game currently running.</param>
|
|
|
/// <param name="appMeta">The Application metadata information, including localized game name and play time information.</param>
|
|
|
@@ -95,15 +95,15 @@ namespace Ryujinx.Ava.Utilities
|
|
|
if (!playReport.IsDictionary)
|
|
|
return FormattedValue.Unhandled;
|
|
|
|
|
|
- if (!_specs.TryGetFirst(s => runningGameId.EqualsAnyIgnoreCase(s.TitleIds), out PlayReportGameSpec spec))
|
|
|
+ if (!_specs.TryGetFirst(s => runningGameId.EqualsAnyIgnoreCase(s.TitleIds), out GameSpec spec))
|
|
|
return FormattedValue.Unhandled;
|
|
|
|
|
|
- foreach (PlayReportGameSpec.FormatterSpec formatSpec in spec.SimpleValueFormatters.OrderBy(x => x.Priority))
|
|
|
+ foreach (GameSpec.FormatterSpec formatSpec in spec.SimpleValueFormatters.OrderBy(x => x.Priority))
|
|
|
{
|
|
|
if (!playReport.AsDictionary().TryGetValue(formatSpec.ReportKey, out MessagePackObject valuePackObject))
|
|
|
continue;
|
|
|
|
|
|
- return formatSpec.ValueFormatter(new PlayReportValue
|
|
|
+ return formatSpec.ValueFormatter(new Value
|
|
|
{
|
|
|
Application = appMeta, PackedValue = valuePackObject
|
|
|
});
|
|
|
@@ -123,7 +123,7 @@ namespace Ryujinx.Ava.Utilities
|
|
|
public bool Handled { get; private init; }
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Did the handler request the caller of the <see cref="PlayReportAnalyzer"/> to reset the existing value?
|
|
|
+ /// Did the handler request the caller of the <see cref="Analyzer"/> to reset the existing value?
|
|
|
/// </summary>
|
|
|
public bool Reset { get; private init; }
|
|
|
|
|
|
@@ -151,7 +151,7 @@ namespace Ryujinx.Ava.Utilities
|
|
|
public static FormattedValue Unhandled => default;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Return this to suggest the caller reset the value it's using the <see cref="PlayReportAnalyzer"/> for.
|
|
|
+ /// Return this to suggest the caller reset the value it's using the <see cref="Analyzer"/> for.
|
|
|
/// </summary>
|
|
|
public static FormattedValue ForceReset => new() { Handled = true, Reset = true };
|
|
|
|
|
|
@@ -172,21 +172,21 @@ namespace Ryujinx.Ava.Utilities
|
|
|
/// <summary>
|
|
|
/// A mapping of title IDs to value formatter specs.
|
|
|
///
|
|
|
- /// <remarks>Generally speaking, use the <see cref="PlayReportAnalyzer"/>.AddSpec(...) methods instead of creating this class yourself.</remarks>
|
|
|
+ /// <remarks>Generally speaking, use the <see cref="Analyzer"/>.AddSpec(...) methods instead of creating this class yourself.</remarks>
|
|
|
/// </summary>
|
|
|
- public class PlayReportGameSpec
|
|
|
+ public class GameSpec
|
|
|
{
|
|
|
public required string[] TitleIds { get; init; }
|
|
|
public List<FormatterSpec> SimpleValueFormatters { get; } = [];
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Add a value formatter to the current <see cref="PlayReportGameSpec"/>
|
|
|
+ /// Add a value formatter to the current <see cref="GameSpec"/>
|
|
|
/// matching a specific key that could exist in a Play Report for the previously specified title IDs.
|
|
|
/// </summary>
|
|
|
/// <param name="reportKey">The key name to match.</param>
|
|
|
/// <param name="valueFormatter">The function which can return a potential formatted value.</param>
|
|
|
- /// <returns>The current <see cref="PlayReportGameSpec"/>, for chaining convenience.</returns>
|
|
|
- public PlayReportGameSpec AddValueFormatter(string reportKey, PlayReportValueFormatter valueFormatter)
|
|
|
+ /// <returns>The current <see cref="GameSpec"/>, for chaining convenience.</returns>
|
|
|
+ public GameSpec AddValueFormatter(string reportKey, PlayReportValueFormatter valueFormatter)
|
|
|
{
|
|
|
SimpleValueFormatters.Add(new FormatterSpec
|
|
|
{
|
|
|
@@ -196,14 +196,14 @@ namespace Ryujinx.Ava.Utilities
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Add a value formatter at a specific priority to the current <see cref="PlayReportGameSpec"/>
|
|
|
+ /// Add a value formatter at a specific priority to the current <see cref="GameSpec"/>
|
|
|
/// matching a specific key that could exist in a Play Report for the previously specified title IDs.
|
|
|
/// </summary>
|
|
|
/// <param name="priority">The resolution priority of this value formatter. Higher resolves sooner.</param>
|
|
|
/// <param name="reportKey">The key name to match.</param>
|
|
|
/// <param name="valueFormatter">The function which can return a potential formatted value.</param>
|
|
|
- /// <returns>The current <see cref="PlayReportGameSpec"/>, for chaining convenience.</returns>
|
|
|
- public PlayReportGameSpec AddValueFormatter(int priority, string reportKey,
|
|
|
+ /// <returns>The current <see cref="GameSpec"/>, for chaining convenience.</returns>
|
|
|
+ public GameSpec AddValueFormatter(int priority, string reportKey,
|
|
|
PlayReportValueFormatter valueFormatter)
|
|
|
{
|
|
|
SimpleValueFormatters.Add(new FormatterSpec
|
|
|
@@ -229,7 +229,7 @@ namespace Ryujinx.Ava.Utilities
|
|
|
/// containing the currently running application's <see cref="ApplicationMetadata"/>,
|
|
|
/// and the matched <see cref="MessagePackObject"/> from the Play Report.
|
|
|
/// </summary>
|
|
|
- public class PlayReportValue
|
|
|
+ public class Value
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// The currently running application's <see cref="ApplicationMetadata"/>.
|
|
|
@@ -276,7 +276,7 @@ namespace Ryujinx.Ava.Utilities
|
|
|
/// <br/>
|
|
|
/// a signal that nothing was available to handle it,
|
|
|
/// <br/>
|
|
|
- /// OR a signal to reset the value that the caller is using the <see cref="PlayReportAnalyzer"/> for.
|
|
|
+ /// OR a signal to reset the value that the caller is using the <see cref="Analyzer"/> for.
|
|
|
/// </summary>
|
|
|
- public delegate PlayReportAnalyzer.FormattedValue PlayReportValueFormatter(PlayReportValue value);
|
|
|
+ public delegate Analyzer.FormattedValue PlayReportValueFormatter(Value value);
|
|
|
}
|