From 726f1f3f112e9b8947f1b35ea659717604bfdd31 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Thu, 22 Jul 2021 14:39:26 +1000 Subject: [PATCH] Move types from Input to top-level in Client.Common and cleanup --- .../input/ClientInputFocus.cs | 15 -- .../input/InputCoalescerControllers.cs | 31 ++++ src/BizHawk.Client.Common/input/InputEvent.cs | 69 +++++++++ .../input/MiscInputEnums.cs | 26 ++++ .../inputAdapters/InputManager.cs | 2 +- .../CustomControls/InputWidget.cs | 3 +- src/BizHawk.Client.EmuHawk/Input/Input.cs | 141 ------------------ src/BizHawk.Client.EmuHawk/MainForm.cs | 30 ++-- .../config/InputCompositeWidget.cs | 12 +- 9 files changed, 151 insertions(+), 178 deletions(-) delete mode 100644 src/BizHawk.Client.Common/input/ClientInputFocus.cs create mode 100644 src/BizHawk.Client.Common/input/InputCoalescerControllers.cs create mode 100644 src/BizHawk.Client.Common/input/InputEvent.cs create mode 100644 src/BizHawk.Client.Common/input/MiscInputEnums.cs diff --git a/src/BizHawk.Client.Common/input/ClientInputFocus.cs b/src/BizHawk.Client.Common/input/ClientInputFocus.cs deleted file mode 100644 index 94578ba98d..0000000000 --- a/src/BizHawk.Client.Common/input/ClientInputFocus.cs +++ /dev/null @@ -1,15 +0,0 @@ -#nullable enable - -using System; - -namespace BizHawk.Client.Common -{ - [Flags] - public enum ClientInputFocus - { - None = 0, - Mouse = 1, - Keyboard = 2, - Pad = 4 - } -} diff --git a/src/BizHawk.Client.Common/input/InputCoalescerControllers.cs b/src/BizHawk.Client.Common/input/InputCoalescerControllers.cs new file mode 100644 index 0000000000..2cfc1bdd8f --- /dev/null +++ b/src/BizHawk.Client.Common/input/InputCoalescerControllers.cs @@ -0,0 +1,31 @@ +#nullable enable + +using System.Linq; + +namespace BizHawk.Client.Common +{ + public class InputCoalescer : SimpleController + { + protected virtual void ProcessSubsets(string button, bool state) {} + + public void Receive(InputEvent ie) + { + var state = ie.EventType is InputEventType.Press; + var button = ie.LogicalButton.ToString(); + Buttons[button] = state; + ProcessSubsets(button, state); + if (state) return; + // when a button is released, all modified variants of it are released as well + foreach (var k in Buttons.Keys.Where(k => k.EndsWith($"+{ie.LogicalButton.Button}")).ToList()) Buttons[k] = false; + } + } + + public sealed class ControllerInputCoalescer : InputCoalescer + { + protected override void ProcessSubsets(string button, bool state) + { + // For controller input, we want Shift+X to register as both Shift and X (for Keyboard controllers) + foreach (var s in button.Split('+')) Buttons[s] = state; + } + } +} diff --git a/src/BizHawk.Client.Common/input/InputEvent.cs b/src/BizHawk.Client.Common/input/InputEvent.cs new file mode 100644 index 0000000000..ae842802bd --- /dev/null +++ b/src/BizHawk.Client.Common/input/InputEvent.cs @@ -0,0 +1,69 @@ +#nullable enable + +using System; + +namespace BizHawk.Client.Common +{ + [Flags] + public enum ClientInputFocus + { + None = 0, + Mouse = 1, + Keyboard = 2, + Pad = 4 + } + + public class InputEvent + { + public InputEventType EventType; + + public LogicalButton LogicalButton; + + public ClientInputFocus Source; + + public override string ToString() => $"{EventType}:{LogicalButton}"; + } + + public enum InputEventType + { + Press, Release + } + + public readonly struct LogicalButton + { + public static bool operator ==(LogicalButton lhs, LogicalButton rhs) + => lhs.Button == rhs.Button && lhs.Modifiers == rhs.Modifiers; + + public static bool operator !=(LogicalButton lhs, LogicalButton rhs) => !(lhs == rhs); + + public bool Alt => (Modifiers & ModifierKey.Alt) != 0; + + public readonly string Button; + + public bool Control => (Modifiers & ModifierKey.Control) != 0; + + public readonly ModifierKey Modifiers; + + public bool Shift => (Modifiers & ModifierKey.Shift) != 0; + + public LogicalButton(string button, ModifierKey modifiers) + { + Button = button; + Modifiers = modifiers; + } + + public override readonly bool Equals(object? obj) => obj is not null && (LogicalButton) obj == this; //TODO safe type check? + + public override readonly int GetHashCode() => Button.GetHashCode() ^ Modifiers.GetHashCode(); + + public override readonly string ToString() + { + var ret = ""; + if (Control) ret += "Ctrl+"; + if (Alt) ret += "Alt+"; + if (Shift) ret += "Shift+"; + ret += Button; + return ret; + } + } +} diff --git a/src/BizHawk.Client.Common/input/MiscInputEnums.cs b/src/BizHawk.Client.Common/input/MiscInputEnums.cs new file mode 100644 index 0000000000..e4a288b09b --- /dev/null +++ b/src/BizHawk.Client.Common/input/MiscInputEnums.cs @@ -0,0 +1,26 @@ +using System; + +namespace BizHawk.Client.Common +{ + public enum AllowInput + { + None = 0, + All = 1, + OnlyController = 2 + } + + [Flags] + public enum ModifierKey + { + /// The bitmask to extract modifiers from a key value. + Modifiers = -65536, + /// No key pressed. + None = 0, + /// The SHIFT modifier key. + Shift = 65536, + /// The CTRL modifier key. + Control = 131072, + /// The ALT modifier key. + Alt = 262144, + } +} diff --git a/src/BizHawk.Client.Common/inputAdapters/InputManager.cs b/src/BizHawk.Client.Common/inputAdapters/InputManager.cs index 96e91f53fb..9fe2f93986 100644 --- a/src/BizHawk.Client.Common/inputAdapters/InputManager.cs +++ b/src/BizHawk.Client.Common/inputAdapters/InputManager.cs @@ -43,7 +43,7 @@ namespace BizHawk.Client.Common // Input state for game controller inputs are coalesced here // This relies on a client specific implementation! - public SimpleController ControllerInputCoalescer { get; set; } + public ControllerInputCoalescer ControllerInputCoalescer { get; set; } public Controller ClientControls { get; set; } diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputWidget.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputWidget.cs index f479b8dde6..f2381c2117 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/InputWidget.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputWidget.cs @@ -4,6 +4,7 @@ using System.Drawing; using System.Linq; using System.Windows.Forms; +using BizHawk.Client.Common; using BizHawk.Common; namespace BizHawk.Client.EmuHawk @@ -14,7 +15,7 @@ namespace BizHawk.Client.EmuHawk private readonly Timer _timer = new Timer(); private readonly List _bindings = new List(); - private Input.InputEvent _lastPress; + private InputEvent _lastPress; public InputCompositeWidget CompositeWidget { get; set; } diff --git a/src/BizHawk.Client.EmuHawk/Input/Input.cs b/src/BizHawk.Client.EmuHawk/Input/Input.cs index d4f454256b..eac60d8b5b 100644 --- a/src/BizHawk.Client.EmuHawk/Input/Input.cs +++ b/src/BizHawk.Client.EmuHawk/Input/Input.cs @@ -11,64 +11,8 @@ using BizHawk.Client.Common; namespace BizHawk.Client.EmuHawk { - // coalesces events back into instantaneous states - public class InputCoalescer : SimpleController - { - public void Receive(Input.InputEvent ie) - { - bool state = ie.EventType == Input.InputEventType.Press; - - string button = ie.LogicalButton.ToString(); - Buttons[button] = state; - - //when a button is released, all modified variants of it are released as well - if (!state) - { - var releases = Buttons.Where(kvp => kvp.Key.Contains("+") && kvp.Key.EndsWith(ie.LogicalButton.Button)).ToArray(); - foreach (var kvp in releases) - Buttons[kvp.Key] = false; - } - } - } - - public class ControllerInputCoalescer : SimpleController - { - public void Receive(Input.InputEvent ie) - { - bool state = ie.EventType == Input.InputEventType.Press; - - string button = ie.LogicalButton.ToString(); - Buttons[button] = state; - - //For controller input, we want Shift+X to register as both Shift and X (for Keyboard controllers) - string[] subgroups = button.Split('+'); - if (subgroups.Length > 0) - { - foreach (string s in subgroups) - { - Buttons[s] = state; - } - } - - //when a button is released, all modified variants of it are released as well - if (!state) - { - var releases = Buttons.Where((kvp) => kvp.Key.Contains("+") && kvp.Key.EndsWith(ie.LogicalButton.Button)).ToArray(); - foreach (var kvp in releases) - Buttons[kvp.Key] = false; - } - } - } - public class Input { - public enum AllowInput - { - None = 0, - All = 1, - OnlyController = 2 - } - /// /// If your form needs this kind of input focus, be sure to say so. /// Really, this only makes sense for mouse, but I've started building it out for other things @@ -83,30 +27,6 @@ namespace BizHawk.Client.EmuHawk private readonly HashSet _wantingMouseFocus = new HashSet(); - [Flags] - public enum ModifierKey - { - // Summary: - // The bitmask to extract modifiers from a key value. - Modifiers = -65536, - // - // Summary: - // No key pressed. - None = 0, - // - // Summary: - // The SHIFT modifier key. - Shift = 65536, - // - // Summary: - // The CTRL modifier key. - Control = 131072, - // - // Summary: - // The ALT modifier key. - Alt = 262144 - } - public static Input Instance; private readonly Thread _updateThread; @@ -138,67 +58,6 @@ namespace BizHawk.Client.EmuHawk _updateThread.Start(); } - public enum InputEventType - { - Press, Release - } - public struct LogicalButton - { - public LogicalButton(string button, ModifierKey modifiers) - { - Button = button; - Modifiers = modifiers; - } - public readonly string Button; - public readonly ModifierKey Modifiers; - - public bool Alt => (Modifiers & ModifierKey.Alt) != 0; - public bool Control => (Modifiers & ModifierKey.Control) != 0; - public bool Shift => (Modifiers & ModifierKey.Shift) != 0; - - public override string ToString() - { - string ret = ""; - if (Control) ret += "Ctrl+"; - if (Alt) ret += "Alt+"; - if (Shift) ret += "Shift+"; - ret += Button; - return ret; - } - public override bool Equals(object obj) - { - if (obj is null) - { - return false; - } - - var other = (LogicalButton)obj; - return other == this; - } - public override int GetHashCode() - { - return Button.GetHashCode() ^ Modifiers.GetHashCode(); - } - public static bool operator ==(LogicalButton lhs, LogicalButton rhs) - { - return lhs.Button == rhs.Button && lhs.Modifiers == rhs.Modifiers; - } - public static bool operator !=(LogicalButton lhs, LogicalButton rhs) - { - return !(lhs == rhs); - } - } - public class InputEvent - { - public LogicalButton LogicalButton; - public InputEventType EventType; - public ClientInputFocus Source; - public override string ToString() - { - return $"{EventType}:{LogicalButton}"; - } - } - private readonly Dictionary _modifierState = new Dictionary(); private readonly WorkingDictionary _lastState = new WorkingDictionary(); private readonly WorkingDictionary _axisValues = new WorkingDictionary(); diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index 6bc291e74a..026c967804 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -447,14 +447,14 @@ namespace BizHawk.Client.EmuHawk { null => Config.AcceptBackgroundInput // none of our forms are focused, check the background input config ? Config.AcceptBackgroundInputControllerOnly - ? Input.AllowInput.OnlyController - : Input.AllowInput.All - : Input.AllowInput.None, - TAStudio when yieldAlt => Input.AllowInput.None, - FormBase { BlocksInputWhenFocused: false } => Input.AllowInput.All, - ControllerConfig => Input.AllowInput.All, - HotkeyConfig => Input.AllowInput.All, - _ => Input.AllowInput.None + ? AllowInput.OnlyController + : AllowInput.All + : AllowInput.None, + TAStudio when yieldAlt => AllowInput.None, + FormBase { BlocksInputWhenFocused: false } => AllowInput.All, + ControllerConfig => AllowInput.All, + HotkeyConfig => AllowInput.All, + _ => AllowInput.None } ); InitControls(); @@ -701,7 +701,7 @@ namespace BizHawk.Client.EmuHawk // handle events and dispatch as a hotkey action, or a hotkey button, or an input button // ...but prepare haptics first, those get read in ProcessInput - var finalHostController = (ControllerInputCoalescer) InputManager.ControllerInputCoalescer; + var finalHostController = InputManager.ControllerInputCoalescer; InputManager.ActiveController.PrepareHapticsForHost(finalHostController); ProcessInput( _hotkeyCoalescer, @@ -982,7 +982,7 @@ namespace BizHawk.Client.EmuHawk Input.Instance.Adapter.SetHaptics(finalHostController.GetHapticsSnapshot()); // loop through all available events - Input.InputEvent ie; + InputEvent ie; while ((ie = Input.Instance.DequeueEvent()) != null) { // useful debugging: @@ -995,7 +995,7 @@ namespace BizHawk.Client.EmuHawk if (triggers.Count == 0) { // Maybe it is a system alt-key which hasn't been overridden - if (ie.EventType == Input.InputEventType.Press) + if (ie.EventType is InputEventType.Press) { if (ie.LogicalButton.Alt && ie.LogicalButton.Button.Length == 1) { @@ -1026,7 +1026,7 @@ namespace BizHawk.Client.EmuHawk finalHostController.Receive(ie); handled = false; - if (ie.EventType == Input.InputEventType.Press) + if (ie.EventType is InputEventType.Press) { handled = triggers.Aggregate(handled, (current, trigger) => current | CheckHotkey(trigger)); } @@ -1043,7 +1043,7 @@ namespace BizHawk.Client.EmuHawk if (!activeControllerHasBinding(ie.LogicalButton.ToString())) { handled = false; - if (ie.EventType == Input.InputEventType.Press) + if (ie.EventType is InputEventType.Press) { handled = triggers.Aggregate(false, (current, trigger) => current | CheckHotkey(trigger)); } @@ -1058,7 +1058,7 @@ namespace BizHawk.Client.EmuHawk break; case 2: // Hotkeys override Input handled = false; - if (ie.EventType == Input.InputEventType.Press) + if (ie.EventType is InputEventType.Press) { handled = triggers.Aggregate(false, (current, trigger) => current | CheckHotkey(trigger)); } @@ -2110,7 +2110,7 @@ namespace BizHawk.Client.EmuHawk } InputManager.ClientControls = controls; - InputManager.ControllerInputCoalescer = new ControllerInputCoalescer(); // ctor initialises values for host haptics + InputManager.ControllerInputCoalescer = new(); // ctor initialises values for host haptics _autofireNullControls = new AutofireController( Emulator, Config.AutofireOn, diff --git a/src/BizHawk.Client.EmuHawk/config/InputCompositeWidget.cs b/src/BizHawk.Client.EmuHawk/config/InputCompositeWidget.cs index 71ada81f95..91c6fbdef2 100644 --- a/src/BizHawk.Client.EmuHawk/config/InputCompositeWidget.cs +++ b/src/BizHawk.Client.EmuHawk/config/InputCompositeWidget.cs @@ -1,6 +1,8 @@ using System; using System.Windows.Forms; +using BizHawk.Client.Common; + namespace BizHawk.Client.EmuHawk { public partial class InputCompositeWidget : UserControl @@ -80,24 +82,24 @@ namespace BizHawk.Client.EmuHawk private void DropdownMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { - Input.ModifierKey mods = new Input.ModifierKey(); + var mods = ModifierKey.None; if ((ModifierKeys & Keys.Shift) != 0) { - mods |= Input.ModifierKey.Shift; + mods |= ModifierKey.Shift; } if ((ModifierKeys & Keys.Control) != 0) { - mods |= Input.ModifierKey.Control; + mods |= ModifierKey.Control; } if ((ModifierKeys & Keys.Alt) != 0) { - mods |= Input.ModifierKey.Alt; + mods |= ModifierKey.Alt; } - var lb = new Input.LogicalButton(e.ClickedItem.Text, mods); + LogicalButton lb = new(e.ClickedItem.Text, mods); widget.SetBinding(lb.ToString()); }