111 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
 | 
						|
using Microsoft.Xna.Framework.Input;
 | 
						|
 | 
						|
using Engine.Core;
 | 
						|
using Engine.Systems.Input;
 | 
						|
 | 
						|
namespace Engine.Integration.MonoGame;
 | 
						|
 | 
						|
public class KeyboardInputs : Behaviour, IButtonInputs<Keys>, IUpdate
 | 
						|
{
 | 
						|
    public IButtonInputs<Keys>.InputEvent OnAnyButtonPressed { get; } = new();
 | 
						|
    public IButtonInputs<Keys>.InputEvent OnAnyButtonReleased { get; } = new();
 | 
						|
 | 
						|
    private readonly Dictionary<Keys, IButtonInputs<Keys>.InputEvent> OnPressed = new(256);
 | 
						|
    private readonly Dictionary<Keys, IButtonInputs<Keys>.InputEvent> OnReleased = new(256);
 | 
						|
 | 
						|
    private int cachePressedCurrentlyCount = 0;
 | 
						|
    private readonly Keys[] cachePressedCurrently = new Keys[256];
 | 
						|
 | 
						|
    private int cachePressedPreviouslyCount = 0;
 | 
						|
    private readonly Keys[] cachePressedPreviously = new Keys[256];
 | 
						|
 | 
						|
    public void RegisterOnPress(Keys key, IButtonInputs<Keys>.InputEvent.EventHandler callback)
 | 
						|
    {
 | 
						|
        if (!OnPressed.TryGetValue(key, out IButtonInputs<Keys>.InputEvent? delegateCallback))
 | 
						|
        {
 | 
						|
            delegateCallback = new();
 | 
						|
            OnPressed.Add(key, delegateCallback);
 | 
						|
        }
 | 
						|
 | 
						|
        delegateCallback.AddListener(callback);
 | 
						|
    }
 | 
						|
 | 
						|
    public void UnregisterOnPress(Keys key, IButtonInputs<Keys>.InputEvent.EventHandler callback)
 | 
						|
    {
 | 
						|
        if (OnPressed.TryGetValue(key, out IButtonInputs<Keys>.InputEvent? delegateCallback))
 | 
						|
            delegateCallback.RemoveListener(callback);
 | 
						|
    }
 | 
						|
 | 
						|
    public void RegisterOnRelease(Keys key, IButtonInputs<Keys>.InputEvent.EventHandler callback)
 | 
						|
    {
 | 
						|
        if (!OnReleased.TryGetValue(key, out IButtonInputs<Keys>.InputEvent? delegateCallback))
 | 
						|
        {
 | 
						|
            delegateCallback = new();
 | 
						|
            OnReleased.Add(key, delegateCallback);
 | 
						|
        }
 | 
						|
 | 
						|
        delegateCallback.AddListener(callback);
 | 
						|
    }
 | 
						|
 | 
						|
    public void UnregisterOnRelease(Keys key, IButtonInputs<Keys>.InputEvent.EventHandler callback)
 | 
						|
    {
 | 
						|
        if (OnReleased.TryGetValue(key, out IButtonInputs<Keys>.InputEvent? delegateCallback))
 | 
						|
            delegateCallback.RemoveListener(callback);
 | 
						|
    }
 | 
						|
 | 
						|
    public void Update()
 | 
						|
    {
 | 
						|
        KeyboardState keyboardState = Keyboard.GetState();
 | 
						|
        keyboardState.GetPressedKeys(cachePressedCurrently);
 | 
						|
        cachePressedCurrentlyCount = keyboardState.GetPressedKeyCount();
 | 
						|
 | 
						|
        for (int i = 0; i < cachePressedCurrentlyCount; i++)
 | 
						|
        {
 | 
						|
            Keys currentlyPressedKey = cachePressedCurrently[i];
 | 
						|
 | 
						|
            if (WasPressed(currentlyPressedKey))
 | 
						|
                continue;
 | 
						|
 | 
						|
            if (OnPressed.TryGetValue(currentlyPressedKey, out IButtonInputs<Keys>.InputEvent? callback))
 | 
						|
                callback?.Invoke(this, new(currentlyPressedKey));
 | 
						|
 | 
						|
            OnAnyButtonPressed?.Invoke(this, new(currentlyPressedKey));
 | 
						|
        }
 | 
						|
 | 
						|
        for (int i = 0; i < cachePressedPreviouslyCount; i++)
 | 
						|
        {
 | 
						|
            Keys previouslyPressedKey = cachePressedPreviously[i];
 | 
						|
 | 
						|
            if (IsPressed(previouslyPressedKey))
 | 
						|
                continue;
 | 
						|
 | 
						|
            if (OnReleased.TryGetValue(previouslyPressedKey, out IButtonInputs<Keys>.InputEvent? callback))
 | 
						|
                callback?.Invoke(this, new(previouslyPressedKey));
 | 
						|
 | 
						|
            OnAnyButtonReleased?.Invoke(this, new(previouslyPressedKey));
 | 
						|
        }
 | 
						|
 | 
						|
        Array.Copy(cachePressedCurrently, cachePressedPreviously, cachePressedCurrentlyCount);
 | 
						|
        cachePressedPreviouslyCount = cachePressedCurrentlyCount;
 | 
						|
    }
 | 
						|
 | 
						|
    public bool IsPressed(Keys key)
 | 
						|
    {
 | 
						|
        for (int i = 0; i < cachePressedCurrentlyCount; i++)
 | 
						|
            if (cachePressedCurrently[i] == key)
 | 
						|
                return true;
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    private bool WasPressed(Keys key)
 | 
						|
    {
 | 
						|
        for (int i = 0; i < cachePressedPreviouslyCount; i++)
 | 
						|
            if (cachePressedPreviously[i] == key)
 | 
						|
                return true;
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
}
 |