diff --git a/Game/Behaviours/KeyboardInputsBehaviour.cs b/Game/Behaviours/KeyboardInputsBehaviour.cs index 46bf534..86d9351 100644 --- a/Game/Behaviours/KeyboardInputsBehaviour.cs +++ b/Game/Behaviours/KeyboardInputsBehaviour.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; - using Microsoft.Xna.Framework.Input; using Syntriax.Engine.Core; diff --git a/Game/Behaviours/NetworkedKeyboardInputs.cs b/Game/Behaviours/NetworkedKeyboardInputs.cs new file mode 100644 index 0000000..8169cde --- /dev/null +++ b/Game/Behaviours/NetworkedKeyboardInputs.cs @@ -0,0 +1,122 @@ +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 +{ + private readonly Dictionary, Keys>> OnPressed = new(256); + private readonly Dictionary, 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, Keys> callback) + { + if (OnPressed.TryGetValue(key, out var action)) + { + action += callback; + return; + } + + OnPressed.Add(key, callback); + } + + public void UnregisterOnPress(Keys key, Action, Keys> callback) + { + if (OnPressed.TryGetValue(key, out var action)) + action -= callback; + } + + public void RegisterOnRelease(Keys key, Action, Keys> callback) + { + if (OnReleased.TryGetValue(key, out var action)) + { + action += callback; + return; + } + + OnReleased.Add(key, callback); + } + + public void UnregisterOnRelease(Keys key, Action, 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 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); + } +}