From 71d8cfd23230a70092d464f546829d3de347330e Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 29 Jan 2025 20:51:55 -0600 Subject: [PATCH] misc: chore: Pass rainbow color by reference in the event instead of passing around a packed int. --- src/Ryujinx.Common/Helpers/RefEvent.cs | 58 +++++++++++++++++++ src/Ryujinx.Common/Utilities/Rainbow.cs | 7 ++- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- .../Input/ControllerInputViewModel.cs | 6 +- .../UI/ViewModels/Input/InputViewModel.cs | 4 +- 5 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 src/Ryujinx.Common/Helpers/RefEvent.cs diff --git a/src/Ryujinx.Common/Helpers/RefEvent.cs b/src/Ryujinx.Common/Helpers/RefEvent.cs new file mode 100644 index 000000000..f339dfb7c --- /dev/null +++ b/src/Ryujinx.Common/Helpers/RefEvent.cs @@ -0,0 +1,58 @@ +using Gommon; +using System.Collections.Generic; +using System.Threading; + +namespace Ryujinx.Common.Helper +{ + public class RefEvent + { + public delegate void Handler(ref T arg); + + private readonly Lock _subLock = new(); + private readonly List _subscriptions = []; + + public bool HasSubscribers + { + get + { + lock (_subLock) + return _subscriptions.Count != 0; + } + } + + public IReadOnlyList Subscriptions + { + get + { + lock (_subLock) + return _subscriptions; + } + } + + public void Add(Handler subscriber) + { + Guard.Require(subscriber, nameof(subscriber)); + lock (_subLock) + _subscriptions.Add(subscriber); + } + + public void Remove(Handler subscriber) + { + Guard.Require(subscriber, nameof(subscriber)); + lock (_subLock) + _subscriptions.Remove(subscriber); + } + + public void Clear() + { + lock (_subLock) + _subscriptions.Clear(); + } + + public void Call(ref T arg) + { + foreach (Handler subscription in Subscriptions) + subscription(ref arg); + } + } +} diff --git a/src/Ryujinx.Common/Utilities/Rainbow.cs b/src/Ryujinx.Common/Utilities/Rainbow.cs index a3db94925..eb1c187c4 100644 --- a/src/Ryujinx.Common/Utilities/Rainbow.cs +++ b/src/Ryujinx.Common/Utilities/Rainbow.cs @@ -1,4 +1,5 @@ using Gommon; +using Ryujinx.Common.Helper; using System; using System.Drawing; using System.Threading; @@ -55,7 +56,7 @@ namespace Ryujinx.Common.Utilities { _color = HsbToRgb((_color.GetHue() + Speed) / 360); - _updatedHandler.Call(_color.ToArgb()); + _updatedHandler.Call(ref _color); } } @@ -67,13 +68,13 @@ namespace Ryujinx.Common.Utilities _color = Color.Blue; } - public static event Action Updated + public static event RefEvent.Handler Updated { add => _updatedHandler.Add(value); remove => _updatedHandler.Remove(value); } - private static readonly Event _updatedHandler = new(); + private static readonly RefEvent _updatedHandler = new(); private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1) { diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 4c93d9d7b..3b243eed0 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -111,7 +111,7 @@ namespace Ryujinx.Input.SDL2 byte blue = packedRgb > 0 ? (byte)(packedRgb % 256) : (byte)0; if (SDL_GameControllerSetLED(_gamepadHandle, red, green, blue) != 0) - Logger.Error?.Print(LogClass.Hid, "LED is not supported on this game controller."); + Logger.Error?.Print(LogClass.Hid, "LED setting failed; probably in the middle of disconnecting."); } private GamepadFeaturesFlag GetFeaturesFlag() diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs index 42daa2f49..2b644cffa 100644 --- a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs @@ -1,12 +1,10 @@ using Avalonia.Svg.Skia; using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using FluentAvalonia.UI.Controls; -using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Views.Input; using Ryujinx.Common.Utilities; using Ryujinx.UI.Views.Input; +using System.Drawing; namespace Ryujinx.Ava.UI.ViewModels.Input { @@ -54,7 +52,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input if (args.PropertyName is nameof(Config.UseRainbowLed)) { if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true }) - Rainbow.Updated += color => ParentModel.SelectedGamepad.SetLed((uint)color); + Rainbow.Updated += (ref Color color) => ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb()); else { Rainbow.Reset(); diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index 6cc7744d8..5b7bcfd32 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -20,10 +20,10 @@ using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.Input; -using Ryujinx.Input.SDL2; using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Drawing; using System.IO; using System.Linq; using System.Text.Json; @@ -69,7 +69,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input _selectedGamepad = value; if (ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true }) - Rainbow.Updated += color => _selectedGamepad.SetLed((uint)color); + Rainbow.Updated += (ref Color color) => _selectedGamepad.SetLed((uint)color.ToArgb()); OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed)); }