Skip to content

Commit

Permalink
UI: Create a ColumnIndices struct and pass it by reference to the row…
Browse files Browse the repository at this point in the history
… ctor instead of recomputing the column index for every column on every row
  • Loading branch information
GreemDev committed Jan 10, 2025
1 parent a8c3407 commit 606e149
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 40 deletions.
73 changes: 47 additions & 26 deletions src/Ryujinx/Utilities/Compat/CompatibilityCsv.cs
Original file line number Diff line number Diff line change
@@ -1,50 +1,71 @@
using Gommon;
using nietras.SeparatedValues;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Ryujinx.Ava.Utilities.Compat
{
public class CompatibilityCsv
public struct ColumnIndices(SepReaderHeader header)
{
public static CompatibilityCsv Shared { get; set; }
public const string TitleIdCol = "\"title_id\"";
public const string GameNameCol = "\"game_name\"";
public const string LabelsCol = "\"labels\"";
public const string StatusCol = "\"status\"";
public const string LastUpdatedCol = "\"last_updated\"";

public CompatibilityCsv(SepReader reader)
public readonly int TitleId = header.IndexOf(TitleIdCol);
public readonly int GameName = header.IndexOf(GameNameCol);
public readonly int Labels = header.IndexOf(LabelsCol);
public readonly int Status = header.IndexOf(StatusCol);
public readonly int LastUpdated = header.IndexOf(LastUpdatedCol);
}

public class CompatibilityCsv
{
static CompatibilityCsv()
{
var entries = new List<CompatibilityEntry>();
using Stream csvStream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("RyujinxGameCompatibilityList")!;
csvStream.Position = 0;

foreach (var row in reader)
{
entries.Add(new CompatibilityEntry(reader.Header, row));
}
LoadFromStream(csvStream);
}

public static void LoadFromStream(Stream stream)
{
var reader = Sep.Reader().From(stream);
var columnIndices = new ColumnIndices(reader.Header);

Entries = entries.Where(x => x.Status != null)
.OrderBy(it => it.GameName).ToArray();
Entries = reader
.Enumerate(row => new CompatibilityEntry(ref columnIndices, row))
.OrderBy(it => it.GameName)
.ToArray();

Logger.Debug?.Print(LogClass.UI, "Compatibility CSV loaded.");
}

public CompatibilityEntry[] Entries { get; }
public static CompatibilityEntry[] Entries { get; private set; }
}

public class CompatibilityEntry
{
public CompatibilityEntry(SepReaderHeader header, SepReader.Row row)
public CompatibilityEntry(ref ColumnIndices indices, SepReader.Row row)
{
if (row.ColCount != header.ColNames.Count)
throw new InvalidDataException($"CSV row {row.RowIndex} ({row.ToString()}) has mismatched column count");

var titleIdRow = ColStr(row[header.IndexOf("\"title_id\"")]);
var titleIdRow = ColStr(row[indices.TitleId]);
TitleId = !string.IsNullOrEmpty(titleIdRow)
? titleIdRow
: default(Optional<string>);

GameName = ColStr(row[header.IndexOf("\"game_name\"")]).Trim().Trim('"');
GameName = ColStr(row[indices.GameName]).Trim().Trim('"');

IssueLabels = ColStr(row[header.IndexOf("\"labels\"")]).Split(';');
Status = ColStr(row[header.IndexOf("\"status\"")]).ToLower() switch
Labels = ColStr(row[indices.Labels]).Split(';');
Status = ColStr(row[indices.Status]).ToLower() switch
{
"playable" => LocaleKeys.CompatibilityListPlayable,
"ingame" => LocaleKeys.CompatibilityListIngame,
Expand All @@ -54,8 +75,8 @@ public CompatibilityEntry(SepReaderHeader header, SepReader.Row row)
_ => null
};

if (DateTime.TryParse(ColStr(row[header.IndexOf("\"last_updated\"")]), out var dt))
LastEvent = dt;
if (DateTime.TryParse(ColStr(row[indices.LastUpdated]), out var dt))
LastUpdated = dt;

return;

Expand All @@ -64,15 +85,15 @@ public CompatibilityEntry(SepReaderHeader header, SepReader.Row row)

public string GameName { get; }
public Optional<string> TitleId { get; }
public string[] IssueLabels { get; }
public string[] Labels { get; }
public LocaleKeys? Status { get; }
public DateTime LastEvent { get; }
public DateTime LastUpdated { get; }

public string LocalizedStatus => LocaleManager.Instance[Status!.Value];
public string FormattedTitleId => TitleId
.OrElse(new string(' ', 16));

public string FormattedIssueLabels => IssueLabels
public string FormattedIssueLabels => Labels
.Where(it => !it.StartsWithIgnoreCase("status"))
.Select(FormatLabelName)
.JoinToString(", ");
Expand All @@ -82,9 +103,9 @@ public override string ToString()
var sb = new StringBuilder("CompatibilityEntry: {");
sb.Append($"{nameof(GameName)}=\"{GameName}\", ");
sb.Append($"{nameof(TitleId)}={TitleId}, ");
sb.Append($"{nameof(IssueLabels)}=\"{IssueLabels}\", ");
sb.Append($"{nameof(Labels)}=\"{Labels}\", ");
sb.Append($"{nameof(Status)}=\"{Status}\", ");
sb.Append($"{nameof(LastEvent)}=\"{LastEvent}\"");
sb.Append($"{nameof(LastUpdated)}=\"{LastUpdated}\"");
sb.Append('}');

return sb.ToString();
Expand Down
9 changes: 0 additions & 9 deletions src/Ryujinx/Utilities/Compat/CompatibilityList.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@ public partial class CompatibilityList : UserControl
{
public static async Task Show()
{
if (CompatibilityCsv.Shared is null)
{
await using Stream csvStream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("RyujinxGameCompatibilityList")!;
csvStream.Position = 0;

CompatibilityCsv.Shared = new CompatibilityCsv(Sep.Reader().From(csvStream));
}

ContentDialog contentDialog = new()
{
PrimaryButtonText = string.Empty,
Expand Down
9 changes: 4 additions & 5 deletions src/Ryujinx/Utilities/Compat/CompatibilityViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ public partial class CompatibilityViewModel : ObservableObject
{
[ObservableProperty] private bool _onlyShowOwnedGames = true;

private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityCsv.Shared.Entries;
private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityCsv.Entries;
private readonly string[] _ownedGameTitleIds = [];
private readonly ApplicationLibrary _appLibrary;

public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames
? _currentEntries.Where(x =>
x.TitleId.Check(tid => _ownedGameTitleIds.ContainsIgnoreCase(tid))
|| _appLibrary.Applications.Items.Any(a => a.Name.EqualsIgnoreCase(x.GameName)))
x.TitleId.Check(tid => _ownedGameTitleIds.ContainsIgnoreCase(tid)))
: _currentEntries;

public CompatibilityViewModel() {}
Expand All @@ -39,11 +38,11 @@ public void Search(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm))
{
SetEntries(CompatibilityCsv.Shared.Entries);
SetEntries(CompatibilityCsv.Entries);
return;
}

SetEntries(CompatibilityCsv.Shared.Entries.Where(x =>
SetEntries(CompatibilityCsv.Entries.Where(x =>
x.GameName.ContainsIgnoreCase(searchTerm)
|| x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm))));
}
Expand Down

0 comments on commit 606e149

Please sign in to comment.