Bläddra i källkod

UI: Simplify LDN data logic

Evan Husted 1 år sedan
förälder
incheckning
d3bc3a1081

+ 2 - 0
src/Ryujinx.UI.Common/App/ApplicationData.cs

@@ -36,6 +36,8 @@ namespace Ryujinx.UI.App.Common
         public string Path { get; set; }
         public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
 
+        public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0;
+
         public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
 
         public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n") ?? LocalizedNever();

+ 4 - 5
src/Ryujinx.UI.Common/App/ApplicationLibrary.cs

@@ -789,16 +789,15 @@ namespace Ryujinx.UI.App.Common
                     using HttpClient httpClient = new HttpClient();
                     string ldnGameDataArrayString = await httpClient.GetStringAsync($"https://{ldnWebHost}/api/public_games");
                     ldnGameDataArray = JsonHelper.Deserialize(ldnGameDataArrayString, _ldnDataSerializerContext.IEnumerableLdnGameData);
-                    var evt = new LdnGameDataReceivedEventArgs
+                    LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
                     {
                         LdnData = ldnGameDataArray
-                    };
-                    LdnGameDataReceived?.Invoke(null, evt);
+                    });
                 }
                 catch (Exception ex)
                 {
                     Logger.Warning?.Print(LogClass.Application, $"Failed to fetch the public games JSON from the API. Player and game count in the game list will be unavailable.\n{ex.Message}");
-                    LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs()
+                    LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
                     {
                         LdnData = Array.Empty<LdnGameData>()
                     });
@@ -806,7 +805,7 @@ namespace Ryujinx.UI.App.Common
             }
             else
             {
-                LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs()
+                LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
                 {
                     LdnData = Array.Empty<LdnGameData>()
                 });

+ 24 - 0
src/Ryujinx.UI.Common/App/LdnGameDataList.cs

@@ -0,0 +1,24 @@
+using LibHac.Ns;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Ryujinx.UI.App.Common
+{
+    public class LdnGameDataArray
+    {
+        private readonly LdnGameData[] _ldnDatas;
+
+        public LdnGameDataArray(IEnumerable<LdnGameData> receivedData, ref ApplicationControlProperty acp)
+        {
+            LibHac.Common.FixedArrays.Array8<ulong> communicationId = acp.LocalCommunicationId;
+
+            _ldnDatas = receivedData.Where(game =>
+                communicationId.Items.Contains(Convert.ToUInt64(game.TitleId, 16))
+            ).ToArray();
+        }
+
+        public int PlayerCount => _ldnDatas.Sum(it => it.PlayerCount);
+        public int GameCount => _ldnDatas.Length;
+    }
+}

+ 4 - 2
src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs

@@ -9,6 +9,7 @@ using Avalonia.Threading;
 using DynamicData;
 using DynamicData.Binding;
 using FluentAvalonia.UI.Controls;
+using Gommon;
 using LibHac.Common;
 using LibHac.Ns;
 using Ryujinx.Ava.Common;
@@ -119,8 +120,9 @@ namespace Ryujinx.Ava.UI.ViewModels
 
         public ApplicationData ListSelectedApplication;
         public ApplicationData GridSelectedApplication;
-
-        public IEnumerable<LdnGameData> LastLdnGameData;
+        
+        // Key is Title ID
+        public SafeDictionary<string, LdnGameDataArray> LdnData = [];
 
         // The UI specifically uses a thicker bordered variant of the icon to avoid crunching out the border at lower resolutions.
         // For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.

+ 11 - 7
src/Ryujinx/UI/Windows/MainWindow.axaml.cs

@@ -167,24 +167,28 @@ namespace Ryujinx.Ava.UI.Windows
         {
             Dispatcher.UIThread.Post(() =>
             {
-                var ldnGameDataArray = e.LdnData;
-                ViewModel.LastLdnGameData = ldnGameDataArray;
+                var ldnGameDataArray = e.LdnData.ToList();
+                ViewModel.LdnData.Clear();
                 foreach (var application in ViewModel.Applications)
                 {
+                    ViewModel.LdnData[application.IdString] = new LdnGameDataArray(
+                        ldnGameDataArray,
+                        ref application.ControlHolder.Value
+                        );
+                    
                     UpdateApplicationWithLdnData(application);
                 }
+                
                 ViewModel.RefreshView();
             });
         }
 
         private void UpdateApplicationWithLdnData(ApplicationData application)
         {
-            if (application.ControlHolder.ByteSpan.Length > 0 && ViewModel.LastLdnGameData != null)
+            if (application.HasControlHolder && ViewModel.LdnData.TryGetValue(application.IdString, out var ldnGameDatas))
             {
-                IEnumerable<LdnGameData> ldnGameData = ViewModel.LastLdnGameData.Where(game => application.ControlHolder.Value.LocalCommunicationId.Items.Contains(Convert.ToUInt64(game.TitleId, 16)));
-
-                application.PlayerCount = ldnGameData.Sum(game => game.PlayerCount);
-                application.GameCount = ldnGameData.Count();
+                application.PlayerCount = ldnGameDatas.PlayerCount;
+                application.GameCount = ldnGameDatas.GameCount;
             }
             else
             {