155 lines
4.8 KiB
C#
155 lines
4.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using LiteNetLib;
|
|
using Microsoft.Xna.Framework.Input;
|
|
using Syntriax.Engine.Input;
|
|
using Syntriax.Engine.Network;
|
|
|
|
namespace Pong.Behaviours;
|
|
|
|
public class NetworkedKeyboardInputs : NetworkBehaviour, IButtonInputs<Keys>
|
|
{
|
|
private readonly Dictionary<Keys, Action<IButtonInputs<Keys>, Keys>?> OnPressed = new(256);
|
|
private readonly Dictionary<Keys, Action<IButtonInputs<Keys>, Keys>?> 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, Action<IButtonInputs<Keys>, Keys> callback)
|
|
{
|
|
if (OnPressed.TryGetValue(key, out var action))
|
|
{
|
|
action += callback;
|
|
OnPressed.Remove(key);
|
|
OnPressed.Add(key, action);
|
|
return;
|
|
}
|
|
|
|
OnPressed.Add(key, callback);
|
|
}
|
|
|
|
public void UnregisterOnPress(Keys key, Action<IButtonInputs<Keys>, Keys> callback)
|
|
{
|
|
if (OnPressed.TryGetValue(key, out var action))
|
|
action -= callback;
|
|
}
|
|
|
|
public void RegisterOnRelease(Keys key, Action<IButtonInputs<Keys>, Keys> callback)
|
|
{
|
|
if (OnReleased.TryGetValue(key, out var action))
|
|
{
|
|
action += callback;
|
|
OnReleased.Remove(key);
|
|
OnReleased.Add(key, action);
|
|
return;
|
|
}
|
|
|
|
OnReleased.Add(key, callback);
|
|
}
|
|
|
|
public void UnregisterOnRelease(Keys key, Action<IButtonInputs<Keys>, Keys> callback)
|
|
{
|
|
if (OnReleased.TryGetValue(key, out var action))
|
|
action -= callback;
|
|
}
|
|
|
|
protected override void OnUpdate()
|
|
{
|
|
if (!IsServer && !LocalAssigned)
|
|
return;
|
|
|
|
KeyboardState keyboardState = Keyboard.GetState();
|
|
keyboardState.GetPressedKeys(cachePressedCurrently);
|
|
cachePressedCurrentlyCount = keyboardState.GetPressedKeyCount();
|
|
|
|
for (int i = 0; i < cachePressedCurrentlyCount; i++)
|
|
{
|
|
Keys currentlyPressedKey = cachePressedCurrently[i];
|
|
|
|
if (!OnPressed.TryGetValue(currentlyPressedKey, out var action))
|
|
continue;
|
|
|
|
if (WasPressed(currentlyPressedKey))
|
|
continue;
|
|
|
|
action?.Invoke(this, currentlyPressedKey);
|
|
}
|
|
|
|
for (int i = 0; i < cachePressedPreviouslyCount; i++)
|
|
{
|
|
Keys previouslyPressedKey = cachePressedPreviously[i];
|
|
|
|
if (!OnReleased.TryGetValue(previouslyPressedKey, out var action))
|
|
continue;
|
|
|
|
if (IsPressed(previouslyPressedKey))
|
|
continue;
|
|
|
|
action?.Invoke(this, 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;
|
|
}
|
|
|
|
public bool WasPressed(Keys key)
|
|
{
|
|
for (int i = 0; i < cachePressedPreviouslyCount; i++)
|
|
if (cachePressedPreviously[i] == key)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
base.OnInitialize();
|
|
foreach (Keys key in Enum.GetValues(typeof(Keys)))
|
|
{
|
|
RegisterOnPress(key, (keys, keyVal) =>
|
|
{
|
|
if (!LocalAssigned && !IsServer)
|
|
return;
|
|
|
|
var netDataWriter = NetworkCommunicator.GetMessageWriter(this);
|
|
netDataWriter.Put(true);
|
|
netDataWriter.Put((int)key);
|
|
NetworkCommunicator.Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered);
|
|
});
|
|
RegisterOnRelease(key, (keys, keyVal) =>
|
|
{
|
|
if (!LocalAssigned && !IsServer)
|
|
return;
|
|
|
|
var netDataWriter = NetworkCommunicator.GetMessageWriter(this);
|
|
netDataWriter.Put(false);
|
|
netDataWriter.Put((int)key);
|
|
NetworkCommunicator.Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered);
|
|
});
|
|
}
|
|
}
|
|
|
|
protected override void OnMessageReceived(NetPacketReader reader, NetPeer peer)
|
|
{
|
|
bool isPressed = reader.GetBool();
|
|
Keys key = (Keys)reader.GetInt();
|
|
|
|
if (isPressed)
|
|
if (OnPressed.TryGetValue(key, out var action))
|
|
action?.Invoke(this, key);
|
|
if (!isPressed)
|
|
if (OnReleased.TryGetValue(key, out var action))
|
|
action?.Invoke(this, key);
|
|
}
|
|
}
|