From 2a6f41713e00a1deb1ad9a783c964c20ad0c322a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Tue, 16 Apr 2024 17:55:13 +0200 Subject: [PATCH] feat: special key reading --- Assets/Scripts/Domain/Input/AObertaReader.cs | 2 +- .../Domain/Input/SequentialInputReader.cs | 20 +++++- Assets/Scripts/Domain/KeyHistory.cs | 65 +++++++++++++++++-- Assets/Scripts/Extensions/LimitedSizeList.cs | 14 +++- Assets/Scripts/Tests/KeySequenceTests.cs | 51 +++++++++++++++ 5 files changed, 144 insertions(+), 8 deletions(-) diff --git a/Assets/Scripts/Domain/Input/AObertaReader.cs b/Assets/Scripts/Domain/Input/AObertaReader.cs index 7fbd8a1..f813c91 100644 --- a/Assets/Scripts/Domain/Input/AObertaReader.cs +++ b/Assets/Scripts/Domain/Input/AObertaReader.cs @@ -3,6 +3,6 @@ using System.Linq; namespace Domain.Input { public class AObertaReader : SequentialInputReader { - public AObertaReader(KeyHistory history) : base(history, new List{ 0xBA, 0x41 }) { } + public AObertaReader(KeyHistory history) : base(history, new List{ 0xBA, 0x41 }, 0x10, false) { } } } \ No newline at end of file diff --git a/Assets/Scripts/Domain/Input/SequentialInputReader.cs b/Assets/Scripts/Domain/Input/SequentialInputReader.cs index 0832de8..871b91c 100644 --- a/Assets/Scripts/Domain/Input/SequentialInputReader.cs +++ b/Assets/Scripts/Domain/Input/SequentialInputReader.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using UnityEngine; namespace Domain.Input { public abstract class SequentialInputReader : InputReader { @@ -7,14 +8,31 @@ namespace Domain.Input { private readonly KeyHistory _history; private readonly List _desiredSequence; + private readonly bool _useSpecial; + private readonly int _specialKey; + private readonly bool _mustContain; + protected SequentialInputReader(KeyHistory history, List desiredSequence) { + _useSpecial = false; _history = history; _desiredSequence = desiredSequence; } + protected SequentialInputReader(KeyHistory history, List desiredSequence, int specialKey, bool mustContain) { + _useSpecial = true; + _history = history; + _desiredSequence = desiredSequence; + + _specialKey = specialKey; + _mustContain = mustContain; + } + public override void UpdateInput() { WasPressed = IsPressed; - IsPressed = _history.ContainsSequence(_desiredSequence); + if (_useSpecial) + IsPressed = _history.ContainsSequence(_desiredSequence, _specialKey, _mustContain); + else + IsPressed = _history.ContainsSequence(_desiredSequence); } } } \ No newline at end of file diff --git a/Assets/Scripts/Domain/KeyHistory.cs b/Assets/Scripts/Domain/KeyHistory.cs index 9269aeb..d8029cb 100644 --- a/Assets/Scripts/Domain/KeyHistory.cs +++ b/Assets/Scripts/Domain/KeyHistory.cs @@ -1,15 +1,28 @@ using System.Collections.Generic; using Extensions; +using UnityEngine; namespace Domain { public class KeyHistory { private readonly LimitedSizeList _lastPresses = new(10); + private readonly LimitedSizeList _lastPressesWithSpecial = new(20); - private readonly int[] _customKeys = { 191, 51, 222, 186, 0xBA }; - private readonly bool[] _isPressed = new bool[26 + 6]; - private readonly bool[] _wasPressed = new bool[26 + 6]; + private const int AlphabetSize = 26; + private const int CustomKeysSize = 5; + private const int SpecialKeysSize = 1; - public void KeyPressed(int key) => _lastPresses.Add(key); + private readonly int[] _customKeys = { 191, 51, 222, 186 }; + private readonly int[] _specialKeys = { 0x10 }; + private readonly bool[] _isPressed = new bool[AlphabetSize + CustomKeysSize + SpecialKeysSize]; + private readonly bool[] _wasPressed = new bool[AlphabetSize + CustomKeysSize + SpecialKeysSize]; + + public void KeyPressed(int key, bool isSpecial = false) { + if (!isSpecial) + _lastPresses.Add(key); + _lastPressesWithSpecial.Add(key); + + Debug.Log(_lastPressesWithSpecial); + } public void CheckPresses() { const int aIndex = 0x41; @@ -28,7 +41,7 @@ namespace Domain { } for (int i = 0; i < _customKeys.Length; i++) { - int pressIndex = 26 + i; + int pressIndex = AlphabetSize + i; _wasPressed[pressIndex] = _isPressed[pressIndex]; short state = Win32API.GetAsyncKeyState(_customKeys[i]); @@ -39,6 +52,19 @@ namespace Domain { _isPressed[pressIndex] = false; } } + + for (int i = 0; i < _specialKeys.Length; i++) { + int pressIndex = AlphabetSize + CustomKeysSize + i; + _wasPressed[pressIndex] = _isPressed[pressIndex]; + short state = Win32API.GetAsyncKeyState(_specialKeys[i]); + + if (!_wasPressed[pressIndex] && state != 0) { + _isPressed[pressIndex] = true; + KeyPressed(_specialKeys[i], true); + }else if (_isPressed[pressIndex] && state == 0) { + _isPressed[pressIndex] = false; + } + } } public bool ContainsSequence(List sequence) { @@ -57,6 +83,35 @@ namespace Domain { } } + _lastPresses.List.Clear(); + _lastPressesWithSpecial.List.Clear(); + return true; + } + + public bool ContainsSequence(List sequence, int beginning, bool mustAppear) { + if (_lastPressesWithSpecial.List.Count < sequence.Count + 1) { + if (mustAppear) + return false; + } else { + if (_lastPressesWithSpecial.List[^(sequence.Count + 1)] != beginning && mustAppear) + return false; + if (_lastPressesWithSpecial.List[^(sequence.Count + 1)] == beginning && !mustAppear) + return false; + } + + for (int i = 0; i < _lastPressesWithSpecial.List.Count; i++) { + if (i >= sequence.Count) + break; + + int keyPressed = _lastPressesWithSpecial.List[_lastPressesWithSpecial.List.Count - 1 - i]; + int sequenceKey = sequence[sequence.Count - 1 - i]; + + if (keyPressed != sequenceKey) { + return false; + } + } + + _lastPressesWithSpecial.List.Clear(); _lastPresses.List.Clear(); return true; } diff --git a/Assets/Scripts/Extensions/LimitedSizeList.cs b/Assets/Scripts/Extensions/LimitedSizeList.cs index 0f7a629..bd61d60 100644 --- a/Assets/Scripts/Extensions/LimitedSizeList.cs +++ b/Assets/Scripts/Extensions/LimitedSizeList.cs @@ -1,5 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using System.Text; namespace Extensions { public class LimitedSizeList { @@ -17,5 +19,15 @@ namespace Extensions { List.RemoveAt(0); } } + + public override string ToString() { + StringBuilder result = new(); + + foreach (T element in List) { + result.AppendLine(element.ToString()); + } + + return result.ToString(); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Tests/KeySequenceTests.cs b/Assets/Scripts/Tests/KeySequenceTests.cs index 3138f11..2de7072 100644 --- a/Assets/Scripts/Tests/KeySequenceTests.cs +++ b/Assets/Scripts/Tests/KeySequenceTests.cs @@ -47,4 +47,55 @@ public class KeySequenceTests { Assert.IsFalse(history.ContainsSequence(sequence)); } + + [Test] + public void BeginsWithSpecial_MustContain_Contains() { + List sequence = new() { 0x1, 0x2, 0x3 }; + KeyHistory history = new(); + + history.KeyPressed(0x5, true); + history.KeyPressed(0x1); + history.KeyPressed(0x2); + history.KeyPressed(0x3); + + Assert.IsTrue(history.ContainsSequence(sequence, 0x5, true)); + } + + [Test] + public void DoesntBeginWithSpecial_MustContain_DontContain() { + List sequence = new() { 0x1, 0x2, 0x3 }; + KeyHistory history = new(); + + history.KeyPressed(0x1); + history.KeyPressed(0x1); + history.KeyPressed(0x2); + history.KeyPressed(0x3); + + Assert.IsFalse(history.ContainsSequence(sequence, 0x5, true)); + } + + [Test] + public void BeginsWithSpecial_MustntContain_DontContain() { + List sequence = new() { 0x1, 0x2, 0x3 }; + KeyHistory history = new(); + + history.KeyPressed(0x5, true); + history.KeyPressed(0x1); + history.KeyPressed(0x2); + history.KeyPressed(0x3); + + Assert.IsFalse(history.ContainsSequence(sequence, 0x5, false)); + } + + [Test] + public void DoesntBeginWithSpecial_MustntContain_Contains() { + List sequence = new() { 0x1, 0x2, 0x3 }; + KeyHistory history = new(); + + history.KeyPressed(0x1); + history.KeyPressed(0x2); + history.KeyPressed(0x3); + + Assert.IsTrue(history.ContainsSequence(sequence, 0x5, false)); + } } \ No newline at end of file