misc: chore: move Rainbow updating to a separate task started/stopped as needed
Some checks are pending
Canary release job / Create tag (push) Waiting to run
Canary release job / Release for linux-arm64 (push) Waiting to run
Canary release job / Release for linux-x64 (push) Waiting to run
Canary release job / Release for win-x64 (push) Waiting to run
Canary release job / Release MacOS universal (push) Waiting to run

update gommon & use the Event class from it to allow easily clearing all handlers when the apphost exits to avoid leftover invalid event handlers in the rainbow event handler list.
More robust config application logic to ensure what needs to happen only happens once
This commit is contained in:
Evan Husted 2025-01-24 23:06:59 -06:00
parent 9b6afa0ea2
commit 3b5f6170d1
5 changed files with 68 additions and 31 deletions

View file

@ -42,7 +42,7 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Gommon" Version="2.7.0.2" />
<PackageVersion Include="Gommon" Version="2.7.1" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="Sep" Version="0.6.0" />
<PackageVersion Include="shaderc.net" Version="0.1.0" />

View file

@ -1,40 +1,62 @@
using System;
using Gommon;
using System;
using System.Drawing;
using System.Threading.Tasks;
namespace Ryujinx.Common.Utilities
{
public class Rainbow
public static class Rainbow
{
public static bool CyclingEnabled { get; set; }
public static void Enable()
{
if (!CyclingEnabled)
{
CyclingEnabled = true;
Executor.ExecuteBackgroundAsync(async () =>
{
while (CyclingEnabled)
{
await Task.Delay(15);
Tick();
}
});
}
}
public static void Disable()
{
CyclingEnabled = false;
}
public static float Speed { get; set; } = 1;
public static Color Color { get; private set; } = Color.Blue;
private static float _lastHue;
public static void Tick()
{
float currentHue = Color.GetHue();
float nextHue = currentHue;
Color = HsbToRgb((Color.GetHue() + Speed) / 360);
if (currentHue >= 360)
nextHue = 0;
else
nextHue += Speed;
Color = HsbToRgb(
nextHue / 360,
1,
1
);
_lastHue = currentHue;
RainbowColorUpdated?.Invoke(Color.ToArgb());
UpdatedHandler.Call(Color.ToArgb());
}
public static event Action<int> RainbowColorUpdated;
public static void Reset()
{
Color = Color.Blue;
UpdatedHandler.Clear();
}
private static Color HsbToRgb(float hue, float saturation, float brightness)
public static event Action<int> Updated
{
add => UpdatedHandler.Add(value);
remove => UpdatedHandler.Remove(value);
}
internal static Event<int> UpdatedHandler = new();
private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1)
{
int r = 0, g = 0, b = 0;
if (saturation == 0)

View file

@ -148,6 +148,8 @@ namespace Ryujinx.Input.SDL2
{
if (disposing && _gamepadHandle != nint.Zero)
{
Rainbow.Updated -= RainbowColorChanged;
SDL_GameControllerClose(_gamepadHandle);
_gamepadHandle = nint.Zero;
@ -233,6 +235,8 @@ namespace Ryujinx.Input.SDL2
SetLed((uint)packedRgb);
}
private bool _rainbowColorEnabled;
public void SetConfiguration(InputConfig configuration)
{
lock (_userMappingLock)
@ -243,13 +247,20 @@ namespace Ryujinx.Input.SDL2
{
if (_configuration.Led.TurnOffLed)
(this as IGamepad).ClearLed();
else if (_configuration.Led.UseRainbow)
Rainbow.RainbowColorUpdated += RainbowColorChanged;
else
SetLed(_configuration.Led.LedColor);
else switch (_configuration.Led.UseRainbow)
{
case true when !_rainbowColorEnabled:
Rainbow.Updated += RainbowColorChanged;
_rainbowColorEnabled = true;
break;
case false when _rainbowColorEnabled:
Rainbow.Updated -= RainbowColorChanged;
_rainbowColorEnabled = false;
break;
}
if (!_configuration.Led.UseRainbow)
Rainbow.RainbowColorUpdated -= RainbowColorChanged;
if (!_configuration.Led.TurnOffLed && !_rainbowColorEnabled)
SetLed(_configuration.Led.LedColor);
}
_buttonsUserMapping.Clear();

View file

@ -169,8 +169,6 @@ namespace Ryujinx.SDL2.Common
}
});
Rainbow.Tick();
waitHandle.Wait(WaitTimeMs);
}
}

View file

@ -502,6 +502,8 @@ namespace Ryujinx.Ava
_viewModel.Volume = ConfigurationState.Instance.System.AudioVolume.Value;
Rainbow.Enable();
MainLoop();
Exit();
@ -590,8 +592,12 @@ namespace Ryujinx.Ava
foreach (IGamepad gamepad in RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepads())
{
gamepad?.ClearLed();
gamepad?.Dispose();
}
Rainbow.Disable();
Rainbow.Reset();
_isStopped = true;
Stop();
}