using System; using System.Collections.Generic; using Microsoft.Xna.Framework.Input; namespace FNAF_Clone.Input; public static class InputManager { private static Dictionary> keyPressListeners = new(); private static Dictionary> keyHoldListeners = new(); // The bool is for enabling/disabling that method private static Dictionary> keyReleaseListeners = new(); private static KeyboardState oldState = Keyboard.GetState(); private static KeyboardState newState; // public static ConcurrentQueue inputEventQueue = new(); public delegate void KeypressHandler(KeyboardState state); // public static void StartListening() { // processInputThread.Start(); // Console.WriteLine("Started listening for input"); // } public static void NextInputCycle() { Queue 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.Item2.Enabled){ inputEventQueue.Enqueue(t.Item1); } if (t.Item2.RemoveOnNextTrigger){ pressHandlers.Remove(t); } }); } } if (keyHoldListeners.TryGetValue(key, out var holdHandlers)){ holdHandlers.ForEach(t => { if (t.Item2.Enabled){ inputEventQueue.Enqueue(t.Item1); } if (t.Item2.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.Item2.Enabled){ inputEventQueue.Enqueue(t.Item1); } if (t.Item2.RemoveOnNextTrigger){ releaseHandlers.Remove(t); } }); } }); oldState = newState; // Execute foreach (KeypressHandler handler in inputEventQueue){ handler(newState); } } // private static Thread processInputThread = new(() => { // // }); public static void AddListener(Keys key, KeypressHandler action, InputTiming timing, InputListenerHook hook) { Dictionary> workingDict; switch (timing){ case InputTiming.PRESS: workingDict = keyPressListeners; break; case InputTiming.HOLD: workingDict = keyHoldListeners; break; case InputTiming.RELEASE: workingDict = keyReleaseListeners; break; default: throw new ArgumentOutOfRangeException(nameof(timing), timing, null); } if (!workingDict.ContainsKey(key)){ workingDict.Add(key, new()); } workingDict[key].Add((action, hook)); } }