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; public class DesktopInputs : BehaviourBase, IEnterUniverse, IExitUniverse, IGameInputs { public Event, IButtonInputs.ButtonCallbackArguments> OnAnyButtonPressed { get; } = new(); public Event, IButtonInputs.ButtonCallbackArguments> OnAnyButtonReleased { get; } = new(); private readonly Dictionary, IButtonInputs.ButtonCallbackArguments>> OnPressed = new(256); private readonly Dictionary, IButtonInputs.ButtonCallbackArguments>> 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 Event, IButtonInputs.ButtonCallbackArguments>? @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 Event, IButtonInputs.ButtonCallbackArguments>? @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, Event, IButtonInputs.ButtonCallbackArguments>.EventHandler callback) { if (!OnPressed.TryGetValue(button, out Event, IButtonInputs.ButtonCallbackArguments>? @event)) { @event = new(); OnPressed.Add(button, @event); } @event.AddListener(callback); } public void UnregisterOnPress(IGameInputs.Button button, Event, IButtonInputs.ButtonCallbackArguments>.EventHandler callback) { if (OnPressed.TryGetValue(button, out Event, IButtonInputs.ButtonCallbackArguments>? @event)) @event.RemoveListener(callback); } public void RegisterOnRelease(IGameInputs.Button button, Event, IButtonInputs.ButtonCallbackArguments>.EventHandler callback) { if (!OnReleased.TryGetValue(button, out Event, IButtonInputs.ButtonCallbackArguments>? @event)) { @event = new(); OnReleased.Add(button, @event); } @event.AddListener(callback); } public void UnregisterOnRelease(IGameInputs.Button button, Event, IButtonInputs.ButtonCallbackArguments>.EventHandler callback) { if (OnReleased.TryGetValue(button, out Event, IButtonInputs.ButtonCallbackArguments>? @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); } }