using System.Collections.Generic; using Engine.Core; using Engine.Systems.Input; using SDL3; namespace Engine.Integration.SDL3; public class Sdl3KeyboardInputs : Behaviour, ISdl3EventProcessor, IButtonInputs { public IButtonInputs.InputEvent OnAnyButtonPressed { get; } = new(); public IButtonInputs.InputEvent OnAnyButtonReleased { get; } = new(); private readonly Dictionary.InputEvent> OnPressed = new(256); private readonly Dictionary.InputEvent> OnReleased = new(256); private readonly FastList currentlyPressedKeys = []; public void RegisterOnPress(SDL.Keycode key, IButtonInputs.InputEvent.EventHandler callback) { if (!OnPressed.TryGetValue(key, out IButtonInputs.InputEvent? delegateCallback)) { delegateCallback = new(); OnPressed.Add(key, delegateCallback); } delegateCallback.AddListener(callback); } public void UnregisterOnPress(SDL.Keycode key, IButtonInputs.InputEvent.EventHandler callback) { if (OnPressed.TryGetValue(key, out IButtonInputs.InputEvent? delegateCallback)) delegateCallback.RemoveListener(callback); } public void RegisterOnRelease(SDL.Keycode key, IButtonInputs.InputEvent.EventHandler callback) { if (!OnReleased.TryGetValue(key, out IButtonInputs.InputEvent? delegateCallback)) { delegateCallback = new(); OnReleased.Add(key, delegateCallback); } delegateCallback.AddListener(callback); } public void UnregisterOnRelease(SDL.Keycode key, IButtonInputs.InputEvent.EventHandler callback) { if (OnReleased.TryGetValue(key, out IButtonInputs.InputEvent? delegateCallback)) delegateCallback.RemoveListener(callback); } public bool IsPressed(SDL.Keycode button) => currentlyPressedKeys.Contains(button); public void Process(SDL.Event sdlEvent) { switch ((SDL.EventType)sdlEvent.Type) { case SDL.EventType.KeyDown: SDL.Keycode currentlyPressedKey = sdlEvent.Key.Key; if (IsPressed(currentlyPressedKey)) return; currentlyPressedKeys.Add(currentlyPressedKey); if (OnPressed.TryGetValue(currentlyPressedKey, out IButtonInputs.InputEvent? pressCallback)) pressCallback?.Invoke(this, new(currentlyPressedKey)); OnAnyButtonPressed?.Invoke(this, new(currentlyPressedKey)); return; case SDL.EventType.KeyUp: SDL.Keycode previouslyPressedKey = sdlEvent.Key.Key; if (!IsPressed(previouslyPressedKey)) return; currentlyPressedKeys.Remove(previouslyPressedKey); if (OnReleased.TryGetValue(previouslyPressedKey, out IButtonInputs.InputEvent? releaseCallback)) releaseCallback?.Invoke(this, new(previouslyPressedKey)); OnAnyButtonReleased?.Invoke(this, new(previouslyPressedKey)); return; } } }