0
0
mirror of https://github.com/jellyfin/jellyfin-uwp.git synced 2025-04-16 17:36:00 +00:00
Files
jellyfin-uwp/Jellyfin/Utils/GamepadManager.cs
IAmUser4574 807ea30e8e refactor: consolidated Gamepad logic into GamepadManager
feat: object for tracking Gamepad state
feat: detecting B button press per individual gamepad states
2025-02-15 20:01:02 -06:00

103 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Gaming.Input;
using Windows.System;
using Windows.UI.Xaml;
namespace Jellyfin.Utils
{
public sealed class GamepadManager
{
private readonly Dictionary<Gamepad, GamepadState> _gamepadStates = new Dictionary<Gamepad, GamepadState>();
private const int ButtonPressCooldownMs = 250;
private readonly DispatcherQueue _dispatcherQueue;
private readonly DispatcherTimer _gamepadPollingTimer;
public event Action OnBackPressed;
public GamepadManager()
{
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
Gamepad.GamepadAdded += Gamepad_Added;
Gamepad.GamepadRemoved += Gamepad_Removed;
_gamepadPollingTimer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(10),
};
_gamepadPollingTimer.Tick += GamepadPollingTimer_Tick;
_gamepadPollingTimer.Start();
}
private void Gamepad_Added(object sender, Gamepad e)
{
if (!_gamepadStates.ContainsKey(e))
{
_gamepadStates[e] = new GamepadState();
}
}
private void Gamepad_Removed(object sender, Gamepad e)
{
_gamepadStates.Remove(e);
}
private void GamepadPollingTimer_Tick(object sender, object e)
{
if (_dispatcherQueue.HasThreadAccess)
{
ProcessGamepadInput();
}
else
{
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.High, ProcessGamepadInput);
}
}
private void ProcessGamepadInput()
{
foreach (Gamepad gamepad in _gamepadStates.Keys)
{
GamepadState gamepadState = _gamepadStates[gamepad];
GamepadReading reading = gamepad.GetCurrentReading();
bool isBPressed = (reading.Buttons & GamepadButtons.B) == GamepadButtons.B;
if (isBPressed && !gamepadState.WasBPressed && gamepadState.ButtonCooldownTimer.ElapsedMilliseconds >= ButtonPressCooldownMs) // press detected
{
OnBackPressed?.Invoke();
gamepadState.WasBPressed = true;
gamepadState.ButtonCooldownTimer.Restart();
}
else if (!isBPressed)
{
gamepadState.WasBPressed = false;
}
}
}
public void Dispose()
{
_gamepadPollingTimer.Stop();
_gamepadPollingTimer.Tick -= GamepadPollingTimer_Tick;
Gamepad.GamepadAdded -= Gamepad_Added;
Gamepad.GamepadRemoved -= Gamepad_Removed;
}
}
public sealed class GamepadState
{
public bool WasBPressed { get; set; } // track previous state of B button
public Stopwatch ButtonCooldownTimer { get; set; } // tracks time since last B button press
public GamepadState()
{
WasBPressed = false;
ButtonCooldownTimer = new Stopwatch();
ButtonCooldownTimer.Start();
}
}
}