From 824643e143f7d8e8dc9599d57ef5ff3398f4b0c9 Mon Sep 17 00:00:00 2001 From: Babib3l Date: Sat, 30 May 2026 20:33:50 +0000 Subject: [PATCH] Fix : Fix controller Stick visualizer perfomance (#119) This PR aims to fix a bug inside the settings window that caused the Controller Stick visualizer to run at extremely degraded performance when the selected profile had a rainbow LED configuration: Old behaviour : New / updated behaviour : The issue was that the input settings page automatically subscribed controllers to rainbow LED updates when a saved profile with rainbow LEDs enabled was loaded. Reopening input settings on a non-default controller profile could immediately start the rainbow LED update loop from the settings UI, which caused the stick visualizer to become sluggish or jittery on affected controllers. The preview handler is now only registered when the rainbow LED option is changed in the settings UI, and it uses a stable handler so duplicate callbacks are not stacked. Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/119 --- .../Input/ControllerInputViewModel.cs | 49 ++++++++++++------- .../UI/ViewModels/Input/InputViewModel.cs | 5 -- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs index 2df530cb7..2a3ec07b6 100644 --- a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs @@ -2,6 +2,7 @@ using Avalonia.Svg.Skia; using CommunityToolkit.Mvvm.ComponentModel; using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Views.Input; +using Ryujinx.Common.Helper; using Ryujinx.Common.Utilities; using Ryujinx.UI.Views.Input; @@ -59,32 +60,46 @@ namespace Ryujinx.Ava.UI.ViewModels.Input public partial SvgImage Image { get; set; } public InputViewModel ParentModel { get; } + private readonly RefEvent.Handler _rainbowLedHandler; + public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer) { ParentModel = model; Visualizer = visualizer; + _rainbowLedHandler = SetRainbowLed; + model.NotifyChangesEvent += OnParentModelChanged; OnParentModelChanged(); - config.PropertyChanged += (_, args) => - { - if (args.PropertyName is nameof(Config.UseRainbowLed)) - { - if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true }) - Rainbow.Updated += (ref color) => ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb()); - else - { - Rainbow.Reset(); - - if (Config.TurnOffLed) - ParentModel.SelectedGamepad.ClearLed(); - else - ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32()); - } - } - }; + config.PropertyChanged += OnConfigPropertyChanged; Config = config; } + private void OnConfigPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs args) + { + if (args.PropertyName is nameof(Config.UseRainbowLed)) + { + if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true }) + { + Rainbow.Updated -= _rainbowLedHandler; + Rainbow.Updated += _rainbowLedHandler; + } + else + { + Rainbow.Reset(); + + if (Config.TurnOffLed) + ParentModel.SelectedGamepad.ClearLed(); + else + ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32()); + } + } + } + + private void SetRainbowLed(ref System.Drawing.Color color) + { + ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb()); + } + public async void ShowMotionConfig() { await MotionInputView.Show(this); diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index 945b84a33..3b1014b9e 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -23,7 +23,6 @@ using Ryujinx.Input.SDL3; using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Drawing; using System.IO; using System.Linq; using System.Text.Json; @@ -81,10 +80,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input field = value; - if ((field?.Features & GamepadFeaturesFlag.Led) != 0 && - ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true }) - Rainbow.Updated += (ref Color color) => field.SetLed((uint)color.ToArgb()); - OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed)); } }