using System; using System.Collections.Generic; using Microsoft.Xna.Framework.Input; using Engine.Core; using Engine.Integration.MonoGame; using Engine.Systems.Input; using MyUniverse.Shared.Behaviours.Abstract; namespace MyUniverse.Platforms.Desktop; public class DesktopInputs : BehaviourBase, IEnterUniverse, IExitUniverse, IGameInputs { 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 Dictionary keyMappingReversed = []; private readonly Dictionary keyMapping = new() { { Keys.Space, IGameInputs.Button.Interact } }; private KeyboardInputs keyboardInputs = null!; public void EnterUniverse(IUniverse universe) { keyboardInputs = BehaviourController.GetOrAddBehaviour(); keyboardInputs.OnAnyButtonPressed.AddListener(AnyPressCallback); keyboardInputs.OnAnyButtonReleased.AddListener(AnyReleaseCallback); foreach ((Keys key, IGameInputs.Button button) in keyMapping) keyboardInputs.RegisterOnPress(key, PressCallback); foreach ((Keys key, IGameInputs.Button button) in keyMapping) keyboardInputs.RegisterOnRelease(key, ReleaseCallback); } public void ExitUniverse(IUniverse universe) { keyboardInputs.OnAnyButtonPressed.RemoveListener(AnyPressCallback); keyboardInputs.OnAnyButtonReleased.RemoveListener(AnyReleaseCallback); foreach ((Keys key, IGameInputs.Button button) in keyMapping) keyboardInputs.UnregisterOnPress(key, PressCallback); foreach ((Keys key, IGameInputs.Button button) in keyMapping) keyboardInputs.UnregisterOnRelease(key, ReleaseCallback); } private void PressCallback(IButtonInputs sender, IButtonInputs.ButtonCallbackArguments args) { if (!keyMapping.TryGetValue(args.Button, out IGameInputs.Button button)) return; if (!OnPressed.TryGetValue(button, out IButtonInputs.InputEvent? @event)) return; @event.Invoke(this, new(button)); } private void ReleaseCallback(IButtonInputs sender, IButtonInputs.ButtonCallbackArguments args) { if (!keyMapping.TryGetValue(args.Button, out IGameInputs.Button button)) return; if (!OnReleased.TryGetValue(button, out IButtonInputs.InputEvent? @event)) return; @event.Invoke(this, new(button)); } private void AnyReleaseCallback(IButtonInputs sender, IButtonInputs.ButtonCallbackArguments args) { if (keyMapping.TryGetValue(args.Button, out IGameInputs.Button button)) OnAnyButtonPressed?.Invoke(this, new(button)); } private void AnyPressCallback(IButtonInputs sender, IButtonInputs.ButtonCallbackArguments args) { if (keyMapping.TryGetValue(args.Button, out IGameInputs.Button button)) OnAnyButtonPressed?.Invoke(this, new(button)); } public void RegisterOnPress(IGameInputs.Button button, IButtonInputs.InputEvent.EventHandler callback) { if (!OnPressed.TryGetValue(button, out IButtonInputs.InputEvent? @event)) { @event = new(); OnPressed.Add(button, @event); } @event.AddListener(callback); } public void UnregisterOnPress(IGameInputs.Button button, IButtonInputs.InputEvent.EventHandler callback) { if (OnPressed.TryGetValue(button, out IButtonInputs.InputEvent? @event)) @event.RemoveListener(callback); } public void RegisterOnRelease(IGameInputs.Button button, IButtonInputs.InputEvent.EventHandler callback) { if (!OnReleased.TryGetValue(button, out IButtonInputs.InputEvent? @event)) { @event = new(); OnReleased.Add(button, @event); } @event.AddListener(callback); } public void UnregisterOnRelease(IGameInputs.Button button, IButtonInputs.InputEvent.EventHandler callback) { if (OnReleased.TryGetValue(button, out IButtonInputs.InputEvent? @event)) @event.RemoveListener(callback); } public bool IsPressed(IGameInputs.Button button) { if (!keyMappingReversed.TryGetValue(button, out Keys key)) throw new($"{Enum.GetName(button)} is not mapped correctly"); return keyboardInputs.IsPressed(key); } public DesktopInputs() { foreach ((Keys key, IGameInputs.Button button) in keyMapping) keyMappingReversed.Add(button, key); } }