Преглед изворни кода

HLE: Run Play Report event handlers in a dedicated .NET thread

Evan Husted пре 1 година
родитељ
комит
5ab50680b4

+ 9 - 2
src/Ryujinx.Horizon/HorizonStatic.cs

@@ -2,14 +2,21 @@ using MsgPack;
 using Ryujinx.Horizon.Common;
 using Ryujinx.Memory;
 using System;
+using System.Threading;
 
 namespace Ryujinx.Horizon
 {
     public static class HorizonStatic
     {
-        internal static void HandlePlayReport(MessagePackObject report) => PlayReportPrinted?.Invoke(report);
+        internal static void HandlePlayReport(MessagePackObject report) => 
+            new Thread(() => PlayReport?.Invoke(report))
+            {
+                Name = "HLE.PlayReportEvent", 
+                IsBackground = true,
+                Priority = ThreadPriority.AboveNormal
+            }.Start();
         
-        public static event Action<MessagePackObject> PlayReportPrinted;
+        public static event Action<MessagePackObject> PlayReport;
         
         [ThreadStatic]
         private static HorizonOptions _options;

+ 2 - 0
src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs

@@ -1,3 +1,4 @@
+using Gommon;
 using MsgPack;
 using MsgPack.Serialization;
 using Ryujinx.Common.Logging;
@@ -11,6 +12,7 @@ using Ryujinx.Horizon.Sdk.Sf;
 using Ryujinx.Horizon.Sdk.Sf.Hipc;
 using System;
 using System.Text;
+using System.Threading;
 using ApplicationId = Ryujinx.Horizon.Sdk.Ncm.ApplicationId;
 
 namespace Ryujinx.Horizon.Prepo.Ipc

+ 1 - 1
src/Ryujinx/DiscordIntegrationModule.cs

@@ -56,7 +56,7 @@ namespace Ryujinx.Ava
 
             ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
             TitleIDs.CurrentApplication.Event += (_, e) => Use(e.NewValue);
-            HorizonStatic.PlayReportPrinted += HandlePlayReport;
+            HorizonStatic.PlayReport += HandlePlayReport;
         }
 
         private static void Update(object sender, ReactiveEventArgs<bool> evnt)

+ 0 - 124
src/Ryujinx/Utilities/PlayReport.cs

@@ -85,128 +85,4 @@ namespace Ryujinx.Ava.Utilities
                 _ => PlayReportFormattedValue.ForceReset
             };
     }
-
-    #region Analyzer implementation
-    
-    public class PlayReportAnalyzer
-    {
-        private readonly List<PlayReportGameSpec> _specs = [];
-
-        public PlayReportAnalyzer AddSpec(string titleId, Func<PlayReportGameSpec, PlayReportGameSpec> transform)
-        {
-            _specs.Add(transform(new PlayReportGameSpec { TitleIds = [titleId] }));
-            return this;
-        }
-        
-        public PlayReportAnalyzer AddSpec(string titleId, Action<PlayReportGameSpec> transform)
-        {
-            _specs.Add(new PlayReportGameSpec { TitleIds = [titleId] }.Apply(transform));
-            return this;
-        }
-        
-        public PlayReportAnalyzer AddSpec(IEnumerable<string> titleIds, Func<PlayReportGameSpec, PlayReportGameSpec> transform)
-        {
-            _specs.Add(transform(new PlayReportGameSpec { TitleIds = [..titleIds] }));
-            return this;
-        }
-        
-        public PlayReportAnalyzer AddSpec(IEnumerable<string> titleIds, Action<PlayReportGameSpec> transform)
-        {
-            _specs.Add(new PlayReportGameSpec { TitleIds = [..titleIds] }.Apply(transform));
-            return this;
-        }
-
-        public PlayReportFormattedValue Run(string runningGameId, ApplicationMetadata appMeta, MessagePackObject playReport)
-        {
-            if (!playReport.IsDictionary) 
-                return PlayReportFormattedValue.Unhandled;
-
-            if (!_specs.TryGetFirst(s => runningGameId.EqualsAnyIgnoreCase(s.TitleIds), out PlayReportGameSpec spec))
-                return PlayReportFormattedValue.Unhandled;
-
-            foreach (PlayReportValueFormatterSpec formatSpec in spec.Analyses.OrderBy(x => x.Priority))
-            {
-                if (!playReport.AsDictionary().TryGetValue(formatSpec.ReportKey, out MessagePackObject valuePackObject))
-                    continue;
-
-                PlayReportValue value = new()
-                {
-                    Application = appMeta, 
-                    PackedValue = valuePackObject
-                };
-
-                return formatSpec.ValueFormatter(ref value);
-            }
-            
-            return PlayReportFormattedValue.Unhandled;
-        }
-        
-    }
-
-    public class PlayReportGameSpec
-    {
-        public required string[] TitleIds { get; init; }
-        public List<PlayReportValueFormatterSpec> Analyses { get; } = [];
-
-        public PlayReportGameSpec AddValueFormatter(string reportKey, PlayReportValueFormatter valueFormatter)
-        {
-            Analyses.Add(new PlayReportValueFormatterSpec
-            {
-                Priority = Analyses.Count,
-                ReportKey = reportKey, 
-                ValueFormatter = valueFormatter
-            });
-            return this;
-        }
-        
-        public PlayReportGameSpec AddValueFormatter(int priority, string reportKey, PlayReportValueFormatter valueFormatter)
-        {
-            Analyses.Add(new PlayReportValueFormatterSpec
-            {
-                Priority = priority,
-                ReportKey = reportKey, 
-                ValueFormatter = valueFormatter
-            });
-            return this;
-        }
-    }
-
-    public readonly struct PlayReportValue
-    {
-        public ApplicationMetadata Application { get; init; }
-        
-        public MessagePackObject PackedValue { get; init; }
-
-        public object BoxedValue => PackedValue.ToObject();
-    }
-
-    public struct PlayReportFormattedValue
-    {
-        public bool Handled { get; private init; }
-        
-        public bool Reset { get; private init; }
-        
-        public string FormattedString { get; private init; }
-
-        public static implicit operator PlayReportFormattedValue(string formattedValue)
-            => new() { Handled = true, FormattedString = formattedValue };
-
-        public static PlayReportFormattedValue Unhandled => default;
-        public static PlayReportFormattedValue ForceReset => new() { Handled = true, Reset = true };
-
-        public static PlayReportValueFormatter AlwaysResets = AlwaysResetsImpl;
-        
-        private static PlayReportFormattedValue AlwaysResetsImpl(ref PlayReportValue _) => ForceReset;
-    }
-
-    public struct PlayReportValueFormatterSpec
-    {
-        public required int Priority { get; init; }
-        public required string ReportKey { get; init; }
-        public PlayReportValueFormatter ValueFormatter { get; init; }
-    }
-
-    public delegate PlayReportFormattedValue PlayReportValueFormatter(ref PlayReportValue value);
-
-    #endregion
 }

+ 129 - 0
src/Ryujinx/Utilities/PlayReportAnalyzer.cs

@@ -0,0 +1,129 @@
+using Gommon;
+using MsgPack;
+using Ryujinx.Ava.Utilities.AppLibrary;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Ryujinx.Ava.Utilities
+{
+    public class PlayReportAnalyzer
+    {
+        private readonly List<PlayReportGameSpec> _specs = [];
+
+        public PlayReportAnalyzer AddSpec(string titleId, Func<PlayReportGameSpec, PlayReportGameSpec> transform)
+        {
+            _specs.Add(transform(new PlayReportGameSpec { TitleIds = [titleId] }));
+            return this;
+        }
+        
+        public PlayReportAnalyzer AddSpec(string titleId, Action<PlayReportGameSpec> transform)
+        {
+            _specs.Add(new PlayReportGameSpec { TitleIds = [titleId] }.Apply(transform));
+            return this;
+        }
+        
+        public PlayReportAnalyzer AddSpec(IEnumerable<string> titleIds, Func<PlayReportGameSpec, PlayReportGameSpec> transform)
+        {
+            _specs.Add(transform(new PlayReportGameSpec { TitleIds = [..titleIds] }));
+            return this;
+        }
+        
+        public PlayReportAnalyzer AddSpec(IEnumerable<string> titleIds, Action<PlayReportGameSpec> transform)
+        {
+            _specs.Add(new PlayReportGameSpec { TitleIds = [..titleIds] }.Apply(transform));
+            return this;
+        }
+
+        public PlayReportFormattedValue Run(string runningGameId, ApplicationMetadata appMeta, MessagePackObject playReport)
+        {
+            if (!playReport.IsDictionary) 
+                return PlayReportFormattedValue.Unhandled;
+
+            if (!_specs.TryGetFirst(s => runningGameId.EqualsAnyIgnoreCase(s.TitleIds), out PlayReportGameSpec spec))
+                return PlayReportFormattedValue.Unhandled;
+
+            foreach (PlayReportValueFormatterSpec formatSpec in spec.Analyses.OrderBy(x => x.Priority))
+            {
+                if (!playReport.AsDictionary().TryGetValue(formatSpec.ReportKey, out MessagePackObject valuePackObject))
+                    continue;
+
+                PlayReportValue value = new()
+                {
+                    Application = appMeta, 
+                    PackedValue = valuePackObject
+                };
+
+                return formatSpec.ValueFormatter(ref value);
+            }
+            
+            return PlayReportFormattedValue.Unhandled;
+        }
+        
+    }
+
+    public class PlayReportGameSpec
+    {
+        public required string[] TitleIds { get; init; }
+        public List<PlayReportValueFormatterSpec> Analyses { get; } = [];
+
+        public PlayReportGameSpec AddValueFormatter(string reportKey, PlayReportValueFormatter valueFormatter)
+        {
+            Analyses.Add(new PlayReportValueFormatterSpec
+            {
+                Priority = Analyses.Count,
+                ReportKey = reportKey, 
+                ValueFormatter = valueFormatter
+            });
+            return this;
+        }
+        
+        public PlayReportGameSpec AddValueFormatter(int priority, string reportKey, PlayReportValueFormatter valueFormatter)
+        {
+            Analyses.Add(new PlayReportValueFormatterSpec
+            {
+                Priority = priority,
+                ReportKey = reportKey, 
+                ValueFormatter = valueFormatter
+            });
+            return this;
+        }
+    }
+
+    public readonly struct PlayReportValue
+    {
+        public ApplicationMetadata Application { get; init; }
+        
+        public MessagePackObject PackedValue { get; init; }
+
+        public object BoxedValue => PackedValue.ToObject();
+    }
+
+    public struct PlayReportFormattedValue
+    {
+        public bool Handled { get; private init; }
+        
+        public bool Reset { get; private init; }
+        
+        public string FormattedString { get; private init; }
+
+        public static implicit operator PlayReportFormattedValue(string formattedValue)
+            => new() { Handled = true, FormattedString = formattedValue };
+
+        public static PlayReportFormattedValue Unhandled => default;
+        public static PlayReportFormattedValue ForceReset => new() { Handled = true, Reset = true };
+
+        public static PlayReportValueFormatter AlwaysResets = AlwaysResetsImpl;
+        
+        private static PlayReportFormattedValue AlwaysResetsImpl(ref PlayReportValue _) => ForceReset;
+    }
+
+    public struct PlayReportValueFormatterSpec
+    {
+        public required int Priority { get; init; }
+        public required string ReportKey { get; init; }
+        public PlayReportValueFormatter ValueFormatter { get; init; }
+    }
+
+    public delegate PlayReportFormattedValue PlayReportValueFormatter(ref PlayReportValue value);
+}