Added input management, added lables to input handler entries, added filtering by label
This commit is contained in:
parent
7366d5cb22
commit
a2b524ee04
5 changed files with 180 additions and 0 deletions
2
MonoGameLibrary.sln.DotSettings.user
Normal file
2
MonoGameLibrary.sln.DotSettings.user
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKeys_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa69b121f85054691b2a8d28643003c23136600_003F08_003F1a47fbcb_003FKeys_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||||
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Content;
|
using Microsoft.Xna.Framework.Content;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using MonoGameLibrary.Input;
|
||||||
|
|
||||||
namespace MonoGameLibrary;
|
namespace MonoGameLibrary;
|
||||||
|
|
||||||
|
|
@ -88,4 +89,9 @@ public class Core : Game
|
||||||
// Create the sprite batch instance.
|
// Create the sprite batch instance.
|
||||||
spriteBatch = new SpriteBatch(graphicsDevice);
|
spriteBatch = new SpriteBatch(graphicsDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Update(GameTime gameTime) {
|
||||||
|
InputManager.NextInputCycle();
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
6
MonoGameLibrary/Input/InputListenerHook.cs
Normal file
6
MonoGameLibrary/Input/InputListenerHook.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace MonoGameLibrary.Input;
|
||||||
|
|
||||||
|
public class InputListenerHook(bool enabled, bool oneTimeOnly = false) {
|
||||||
|
public bool Enabled { get; set; } = enabled;
|
||||||
|
public bool RemoveOnNextTrigger { get; set; } = oneTimeOnly;
|
||||||
|
}
|
||||||
159
MonoGameLibrary/Input/InputManager.cs
Normal file
159
MonoGameLibrary/Input/InputManager.cs
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
|
namespace MonoGameLibrary.Input;
|
||||||
|
|
||||||
|
|
||||||
|
public static class InputManager {
|
||||||
|
private static Dictionary<Keys, List<InputEntry>> keyPressListeners = new();
|
||||||
|
private static Dictionary<Keys, List<InputEntry>> keyHoldListeners = new(); // The bool is for enabling/disabling that method
|
||||||
|
private static Dictionary<Keys, List<InputEntry>> keyReleaseListeners = new();
|
||||||
|
|
||||||
|
private static Dictionary<string, InputEntry> labelDict = new();
|
||||||
|
|
||||||
|
private static KeyboardState oldState = Keyboard.GetState();
|
||||||
|
private static KeyboardState newState;
|
||||||
|
|
||||||
|
// public static ConcurrentQueue<Action> inputEventQueue = new();
|
||||||
|
|
||||||
|
public delegate void KeypressHandler(KeyboardState state);
|
||||||
|
|
||||||
|
private static int nextUnnamedId = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// public static void StartListening() {
|
||||||
|
// processInputThread.Start();
|
||||||
|
// Console.WriteLine("Started listening for input");
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static void NextInputCycle() {
|
||||||
|
Queue<KeypressHandler> inputEventQueue = new();
|
||||||
|
|
||||||
|
// Read
|
||||||
|
|
||||||
|
newState = Keyboard.GetState();
|
||||||
|
Keys[] pressed = newState.GetPressedKeys();
|
||||||
|
Keys[] pressedLastFrame = oldState.GetPressedKeys();
|
||||||
|
|
||||||
|
Array.ForEach(pressed, key => {
|
||||||
|
if (oldState.IsKeyUp(key)){
|
||||||
|
if (keyPressListeners.TryGetValue(key, out var pressHandlers)){
|
||||||
|
pressHandlers.ForEach(t => {
|
||||||
|
if (t.Enabled){
|
||||||
|
inputEventQueue.Enqueue(t.Action);
|
||||||
|
}
|
||||||
|
if (t.Hook.RemoveOnNextTrigger){
|
||||||
|
pressHandlers.Remove(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyHoldListeners.TryGetValue(key, out var holdHandlers)){
|
||||||
|
holdHandlers.ForEach(t => {
|
||||||
|
if (t.Enabled){
|
||||||
|
inputEventQueue.Enqueue(t.Action);
|
||||||
|
}
|
||||||
|
if (t.Hook.RemoveOnNextTrigger){
|
||||||
|
holdHandlers.Remove(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Array.ForEach(pressedLastFrame, key => {
|
||||||
|
if (!keyReleaseListeners.ContainsKey(key)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newState.IsKeyUp(key)){
|
||||||
|
if (keyReleaseListeners.TryGetValue(key, out var releaseHandlers))
|
||||||
|
releaseHandlers.ForEach(t => {
|
||||||
|
if (t.Enabled){
|
||||||
|
inputEventQueue.Enqueue(t.Action);
|
||||||
|
}
|
||||||
|
if (t.Hook.RemoveOnNextTrigger){
|
||||||
|
releaseHandlers.Remove(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
oldState = newState;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
|
||||||
|
foreach (KeypressHandler handler in inputEventQueue){
|
||||||
|
handler(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static Thread processInputThread = new(() => {
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
|
||||||
|
public static void AddListener(string label, Keys key, KeypressHandler action, InputTiming timing, InputListenerHook hook) {
|
||||||
|
if (label.StartsWith("!")){
|
||||||
|
throw new ArgumentException("Label cannot start with !");
|
||||||
|
}
|
||||||
|
InputEntry entry = new (label, key, action, timing, hook);
|
||||||
|
_addListener(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
_addListener(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void _addListener(InputEntry entry) {
|
||||||
|
Dictionary<Keys, List<InputEntry>> workingDict;
|
||||||
|
|
||||||
|
switch (entry.Timing){
|
||||||
|
case InputTiming.PRESS:
|
||||||
|
workingDict = keyPressListeners;
|
||||||
|
break;
|
||||||
|
case InputTiming.HOLD:
|
||||||
|
workingDict = keyHoldListeners;
|
||||||
|
break;
|
||||||
|
case InputTiming.RELEASE:
|
||||||
|
workingDict = keyReleaseListeners;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(entry.Timing), entry.Timing, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!workingDict.ContainsKey(entry.Key)){
|
||||||
|
workingDict.Add(entry.Key, new());
|
||||||
|
}
|
||||||
|
|
||||||
|
workingDict[entry.Key].Add(entry);
|
||||||
|
|
||||||
|
labelDict.Add(entry.Label, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputEntry GetEntry(string label) {
|
||||||
|
return labelDict[label];
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InputEntry {
|
||||||
|
|
||||||
|
public string Label;
|
||||||
|
public Keys Key;
|
||||||
|
public KeypressHandler Action;
|
||||||
|
public InputTiming Timing;
|
||||||
|
public InputListenerHook Hook;
|
||||||
|
|
||||||
|
public bool Enabled => Hook.Enabled;
|
||||||
|
|
||||||
|
public InputEntry(string label, Keys key, KeypressHandler action, InputTiming timing, InputListenerHook hook) {
|
||||||
|
Key = key;
|
||||||
|
Action = action;
|
||||||
|
Timing = timing;
|
||||||
|
Hook = hook;
|
||||||
|
Label = label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// private static List<InputEntry> inputQueue = new();
|
||||||
|
}
|
||||||
7
MonoGameLibrary/Input/InputTiming.cs
Normal file
7
MonoGameLibrary/Input/InputTiming.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace MonoGameLibrary.Input;
|
||||||
|
|
||||||
|
public enum InputTiming {
|
||||||
|
PRESS,
|
||||||
|
HOLD,
|
||||||
|
RELEASE
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue