Added support for mouse input. Removed redundant keyboard state paramater for KeypressHandler, replaced with static field updated every frame.
This commit is contained in:
parent
a2b524ee04
commit
182ebfc31c
1 changed files with 137 additions and 25 deletions
|
|
@ -1,23 +1,37 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Transactions;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
namespace MonoGameLibrary.Input;
|
namespace MonoGameLibrary.Input;
|
||||||
|
|
||||||
|
|
||||||
public static class InputManager {
|
public static class InputManager {
|
||||||
private static Dictionary<Keys, List<InputEntry>> keyPressListeners = new();
|
private static Dictionary<Keys, List<KeyboardInputEntry>> keyPressListeners = new();
|
||||||
private static Dictionary<Keys, List<InputEntry>> keyHoldListeners = new(); // The bool is for enabling/disabling that method
|
private static Dictionary<Keys, List<KeyboardInputEntry>> keyHoldListeners = new(); // The bool is for enabling/disabling that method
|
||||||
private static Dictionary<Keys, List<InputEntry>> keyReleaseListeners = new();
|
private static Dictionary<Keys, List<KeyboardInputEntry>> keyReleaseListeners = new();
|
||||||
|
|
||||||
private static Dictionary<string, InputEntry> labelDict = new();
|
private static Dictionary<string, InputEntry> labelDict = new();
|
||||||
|
|
||||||
private static KeyboardState oldState = Keyboard.GetState();
|
private static KeyboardState oldKBState = Keyboard.GetState();
|
||||||
private static KeyboardState newState;
|
private static KeyboardState newKBState;
|
||||||
|
public static KeyboardState KeyboardState => newKBState;
|
||||||
|
|
||||||
|
|
||||||
|
private static MouseState oldMouseState = Mouse.GetState();
|
||||||
|
private static MouseState newMouseState;
|
||||||
|
public static MouseState MouseState => newMouseState;
|
||||||
|
|
||||||
|
private static Dictionary<MouseButton, List<MouseInputEntry>> mousePressListeners = new();
|
||||||
|
private static Dictionary<MouseButton, List<MouseInputEntry>> mouseHoldListeners = new();
|
||||||
|
private static Dictionary<MouseButton, List<MouseInputEntry>> mouseReleaseListeners = new();
|
||||||
|
|
||||||
// public static ConcurrentQueue<Action> inputEventQueue = new();
|
// public static ConcurrentQueue<Action> inputEventQueue = new();
|
||||||
|
|
||||||
public delegate void KeypressHandler(KeyboardState state);
|
public delegate void KeypressHandler();
|
||||||
|
|
||||||
|
public delegate void MouseHandler();
|
||||||
|
|
||||||
private static int nextUnnamedId = 0;
|
private static int nextUnnamedId = 0;
|
||||||
|
|
||||||
|
|
@ -32,14 +46,14 @@ public static class InputManager {
|
||||||
public static void NextInputCycle() {
|
public static void NextInputCycle() {
|
||||||
Queue<KeypressHandler> inputEventQueue = new();
|
Queue<KeypressHandler> inputEventQueue = new();
|
||||||
|
|
||||||
// Read
|
// Read Keyboard
|
||||||
|
|
||||||
newState = Keyboard.GetState();
|
newKBState = Keyboard.GetState();
|
||||||
Keys[] pressed = newState.GetPressedKeys();
|
Keys[] pressed = newKBState.GetPressedKeys();
|
||||||
Keys[] pressedLastFrame = oldState.GetPressedKeys();
|
Keys[] pressedLastFrame = oldKBState.GetPressedKeys();
|
||||||
|
|
||||||
Array.ForEach(pressed, key => {
|
Array.ForEach(pressed, key => {
|
||||||
if (oldState.IsKeyUp(key)){
|
if (oldKBState.IsKeyUp(key)){
|
||||||
if (keyPressListeners.TryGetValue(key, out var pressHandlers)){
|
if (keyPressListeners.TryGetValue(key, out var pressHandlers)){
|
||||||
pressHandlers.ForEach(t => {
|
pressHandlers.ForEach(t => {
|
||||||
if (t.Enabled){
|
if (t.Enabled){
|
||||||
|
|
@ -69,7 +83,7 @@ public static class InputManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newState.IsKeyUp(key)){
|
if (newKBState.IsKeyUp(key)){
|
||||||
if (keyReleaseListeners.TryGetValue(key, out var releaseHandlers))
|
if (keyReleaseListeners.TryGetValue(key, out var releaseHandlers))
|
||||||
releaseHandlers.ForEach(t => {
|
releaseHandlers.ForEach(t => {
|
||||||
if (t.Enabled){
|
if (t.Enabled){
|
||||||
|
|
@ -81,12 +95,47 @@ public static class InputManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
oldState = newState;
|
oldKBState = newKBState;
|
||||||
|
|
||||||
|
// Read Mouse
|
||||||
|
|
||||||
|
newMouseState = Mouse.GetState();
|
||||||
|
|
||||||
|
List<MouseInputEntry> mouseHandlers = new List<MouseInputEntry>();
|
||||||
|
|
||||||
|
foreach (var button in ((MouseButton type, ButtonState current, ButtonState old)[])[
|
||||||
|
(MouseButton.LEFT, newMouseState.LeftButton, oldMouseState.LeftButton),
|
||||||
|
(MouseButton.RIGHT, newMouseState.RightButton, oldMouseState.RightButton),
|
||||||
|
(MouseButton.MIDDLE, newMouseState.MiddleButton, oldMouseState.MiddleButton)
|
||||||
|
])
|
||||||
|
{
|
||||||
|
if (button.current == ButtonState.Pressed){
|
||||||
|
if (button.old == ButtonState.Released){
|
||||||
|
mousePressListeners.TryGetValue(button.type, out var pressHandlers);
|
||||||
|
mouseHandlers.AddRange(pressHandlers ?? new List<MouseInputEntry>());
|
||||||
|
}
|
||||||
|
mouseHoldListeners.TryGetValue(button.type, out var holdHandlers);
|
||||||
|
mouseHandlers.AddRange(holdHandlers ?? new List<MouseInputEntry>());
|
||||||
|
}
|
||||||
|
else if (button.old == ButtonState.Pressed){
|
||||||
|
if (button.current == ButtonState.Released){
|
||||||
|
mouseReleaseListeners.TryGetValue(button.type, out var releaseHandlers);
|
||||||
|
mouseHandlers.AddRange(releaseHandlers ?? new List<MouseInputEntry>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseHandlers.ForEach(entry => inputEventQueue.Enqueue(entry.Action));
|
||||||
|
oldMouseState = newMouseState;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
|
|
||||||
foreach (KeypressHandler handler in inputEventQueue){
|
foreach (KeypressHandler handler in inputEventQueue){
|
||||||
handler(newState);
|
handler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,17 +147,31 @@ public static class InputManager {
|
||||||
if (label.StartsWith("!")){
|
if (label.StartsWith("!")){
|
||||||
throw new ArgumentException("Label cannot start with !");
|
throw new ArgumentException("Label cannot start with !");
|
||||||
}
|
}
|
||||||
InputEntry entry = new (label, key, action, timing, hook);
|
KeyboardInputEntry entry = new (label, key, action, timing, hook);
|
||||||
_addListener(entry);
|
_addListenerKB(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddListener(Keys key, KeypressHandler action, InputTiming timing, InputListenerHook hook) {
|
public static void AddListener(Keys key, KeypressHandler action, InputTiming timing, InputListenerHook hook) {
|
||||||
InputEntry entry = new ($"!{Enum.GetName(typeof(Keys), key)}Handler{nextUnnamedId++}", key, action, timing, hook);
|
KeyboardInputEntry entry = new ($"!{Enum.GetName(typeof(Keys), key)}Handler{nextUnnamedId++}", key, action, timing, hook);
|
||||||
_addListener(entry);
|
_addListenerKB(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void _addListener(InputEntry entry) {
|
public static void AddListener(string label, MouseButton button, KeypressHandler action, InputTiming timing, InputListenerHook hook) {
|
||||||
Dictionary<Keys, List<InputEntry>> workingDict;
|
if (label.StartsWith("!")){
|
||||||
|
throw new ArgumentException("Label cannot start with !");
|
||||||
|
}
|
||||||
|
MouseInputEntry entry = new (label, button, action, timing, hook);
|
||||||
|
_addListenerMouse(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddListener(MouseButton button, KeypressHandler action, InputTiming timing,
|
||||||
|
InputListenerHook hook) {
|
||||||
|
MouseInputEntry entry = new ($"!{Enum.GetName(typeof(MouseButton), button)}Handler{nextUnnamedId++}", button, action, timing, hook);
|
||||||
|
_addListenerMouse(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void _addListenerKB(KeyboardInputEntry entry) {
|
||||||
|
Dictionary<Keys, List<KeyboardInputEntry>> workingDict;
|
||||||
|
|
||||||
switch (entry.Timing){
|
switch (entry.Timing){
|
||||||
case InputTiming.PRESS:
|
case InputTiming.PRESS:
|
||||||
|
|
@ -133,27 +196,76 @@ public static class InputManager {
|
||||||
labelDict.Add(entry.Label, entry);
|
labelDict.Add(entry.Label, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void _addListenerMouse(MouseInputEntry entry) {
|
||||||
|
Dictionary<MouseButton, List<MouseInputEntry>> workingDict;
|
||||||
|
|
||||||
|
switch (entry.Timing){
|
||||||
|
case InputTiming.PRESS:
|
||||||
|
workingDict = mousePressListeners;
|
||||||
|
break;
|
||||||
|
case InputTiming.HOLD:
|
||||||
|
workingDict = mouseHoldListeners;
|
||||||
|
break;
|
||||||
|
case InputTiming.RELEASE:
|
||||||
|
workingDict = mouseReleaseListeners;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(entry.Timing), entry.Timing, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!workingDict.ContainsKey(entry.Button)){
|
||||||
|
workingDict.Add(entry.Button, new());
|
||||||
|
}
|
||||||
|
|
||||||
|
workingDict[entry.Button].Add(entry);
|
||||||
|
|
||||||
|
labelDict.Add(entry.Label, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static InputEntry GetEntry(string label) {
|
public static InputEntry GetEntry(string label) {
|
||||||
return labelDict[label];
|
return labelDict[label];
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InputEntry {
|
public abstract class InputEntry {
|
||||||
|
|
||||||
public string Label;
|
public string Label;
|
||||||
public Keys Key;
|
|
||||||
public KeypressHandler Action;
|
public KeypressHandler Action;
|
||||||
public InputTiming Timing;
|
public InputTiming Timing;
|
||||||
public InputListenerHook Hook;
|
public InputListenerHook Hook;
|
||||||
|
|
||||||
public bool Enabled => Hook.Enabled;
|
public bool Enabled => Hook.Enabled;
|
||||||
|
|
||||||
public InputEntry(string label, Keys key, KeypressHandler action, InputTiming timing, InputListenerHook hook) {
|
public InputEntry(string label, KeypressHandler action, InputTiming timing, InputListenerHook hook) {
|
||||||
Key = key;
|
|
||||||
Action = action;
|
Action = action;
|
||||||
Timing = timing;
|
Timing = timing;
|
||||||
Hook = hook;
|
Hook = hook;
|
||||||
Label = label;
|
Label = label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class KeyboardInputEntry : InputEntry {
|
||||||
|
public Keys Key;
|
||||||
|
|
||||||
|
public KeyboardInputEntry(string label, Keys key, KeypressHandler action, InputTiming timing, InputListenerHook hook) : base(label, action, timing, hook) {
|
||||||
|
Key = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MouseInputEntry : InputEntry {
|
||||||
|
public MouseButton Button;
|
||||||
|
|
||||||
|
public MouseInputEntry(string label, MouseButton button, KeypressHandler action, InputTiming timing, InputListenerHook hook) : base(label, action, timing, hook) {
|
||||||
|
Button = button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MouseButton {
|
||||||
|
RIGHT,
|
||||||
|
LEFT,
|
||||||
|
MIDDLE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// private static List<InputEntry> inputQueue = new();
|
// private static List<InputEntry> inputQueue = new();
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue