diff --git a/Assets/Scripts/Domain/CustomInput.cs b/Assets/Scripts/Domain/CustomInput.cs index 8354277..1609cb6 100644 --- a/Assets/Scripts/Domain/CustomInput.cs +++ b/Assets/Scripts/Domain/CustomInput.cs @@ -5,12 +5,17 @@ using Domain.Input; namespace Domain { public class CustomInput { private readonly Dictionary _readers = new(); + private readonly KeyHistory _history; public CustomInput() { + _history = new KeyHistory(); + _readers.Add(typeof(CedillaReader), new CedillaReader()); + _readers.Add(typeof(GeminadaReader), new GeminadaReader(_history)); } public void UpdateInput() { + _history.CheckPresses(); foreach (KeyValuePair reader in _readers) { reader.Value.UpdateInput(); } diff --git a/Assets/Scripts/Domain/Input/GeminadaReader.cs b/Assets/Scripts/Domain/Input/GeminadaReader.cs index 2eafe68..2da065b 100644 --- a/Assets/Scripts/Domain/Input/GeminadaReader.cs +++ b/Assets/Scripts/Domain/Input/GeminadaReader.cs @@ -3,7 +3,7 @@ using System.Linq; namespace Domain.Input { public class GeminadaReader : InputReader { - protected override int Key { get; } = 0x33; + protected sealed override int Key { get; } = 0x33; private int LKey { get; } = 76; private bool _lPressed; @@ -11,22 +11,24 @@ namespace Domain.Input { private bool _dotPressed; private bool _dotWasPressed; - private List _lastPresses; + private readonly KeyHistory _history; + private readonly List _desiredSequence; - public override void UpdateInput() { - if (UpdateLInput()) { - if (_lastPresses.Count == 0) { - _lastPresses.Add(LKey); - } else if (_lastPresses.Count >= 2) { - if (_lastPresses[^1] == Key && _lastPresses[^2] == LKey) { - IsPressed = true; - } - } - } - UpdateDotInput(); + public GeminadaReader(KeyHistory history) { + _history = history; + _desiredSequence = new List { LKey, Key, LKey }; } - private bool UpdateDotInput() { + public override void UpdateInput() { + if (UpdateDotInputDown()) { + _history.KeyPressed(Key); + } + + WasPressed = IsPressed; + IsPressed = _history.ContainsSequence(_desiredSequence); + } + + private bool UpdateDotInputDown() { _dotWasPressed = _dotPressed; short dotState = Win32API.GetAsyncKeyState(Key); @@ -40,7 +42,7 @@ namespace Domain.Input { return false; } - private bool UpdateLInput() { + private bool UpdateLInputDown() { _lWasPressed = _lPressed; short lState = Win32API.GetAsyncKeyState(LKey); diff --git a/Assets/Scripts/Domain/KeyHistory.cs b/Assets/Scripts/Domain/KeyHistory.cs index 3f60e8d..5bb66a0 100644 --- a/Assets/Scripts/Domain/KeyHistory.cs +++ b/Assets/Scripts/Domain/KeyHistory.cs @@ -1,27 +1,42 @@ using System.Collections.Generic; +using Extensions; namespace Domain { public class KeyHistory { - private readonly List _lastPresses = new(); - private readonly List _desiredSequence; + private readonly LimitedSizeList _lastPresses = new(10); - public KeyHistory(List desiredSequence) { - _desiredSequence = desiredSequence; - } + private readonly bool[] _isPressed = new bool[26]; + private readonly bool[] _wasPressed = new bool[26]; public void KeyPressed(int key) => _lastPresses.Add(key); - public void ClearPressed() => _lastPresses.Clear(); - public bool ContainsSequence() { - if (_lastPresses.Count < _desiredSequence.Count) + public void CheckPresses() { + const int aIndex = 0x41; + const int zIndex = 0x5A; + + for (int i = aIndex, j = 0; i <= zIndex; i++, j++) { + _wasPressed[j] = _isPressed[j]; + short state = Win32API.GetAsyncKeyState(i); + + if (!_wasPressed[j] && state != 0) { + _isPressed[j] = true; + KeyPressed(i); + }else if (_isPressed[j] && state == 0) { + _isPressed[j] = false; + } + } + } + + public bool ContainsSequence(List sequence) { + if (_lastPresses.List.Count < sequence.Count) return false; - for (int i = 0; i < _lastPresses.Count; i++) { - if (i >= _desiredSequence.Count) + for (int i = 0; i < _lastPresses.List.Count; i++) { + if (i >= sequence.Count) break; - int keyPressed = _lastPresses[_lastPresses.Count - 1 - i]; - int sequenceKey = _desiredSequence[_desiredSequence.Count - 1 - i]; + int keyPressed = _lastPresses.List[_lastPresses.List.Count - 1 - i]; + int sequenceKey = sequence[sequence.Count - 1 - i]; if (keyPressed != sequenceKey) { return false; diff --git a/Assets/Scripts/Domain/SantJordi.Domain.asmdef b/Assets/Scripts/Domain/SantJordi.Domain.asmdef index ee23999..fcbf179 100644 --- a/Assets/Scripts/Domain/SantJordi.Domain.asmdef +++ b/Assets/Scripts/Domain/SantJordi.Domain.asmdef @@ -1,3 +1,4 @@ { - "name": "SantJordi.Domain" + "name": "SantJordi.Domain", + "references":[ "GUID:b347d0ff97f738846abb5625028d64db" ] } diff --git a/Assets/Scripts/Extensions.meta b/Assets/Scripts/Extensions.meta new file mode 100644 index 0000000..5012044 --- /dev/null +++ b/Assets/Scripts/Extensions.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bfb91da35c9749c980ab26f8e6b48dbe +timeCreated: 1713127616 \ No newline at end of file diff --git a/Assets/Scripts/Extensions/LimitedSizeList.cs b/Assets/Scripts/Extensions/LimitedSizeList.cs new file mode 100644 index 0000000..0f7a629 --- /dev/null +++ b/Assets/Scripts/Extensions/LimitedSizeList.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Extensions { + public class LimitedSizeList { + public readonly List List; + private readonly int _maxSize; + + public LimitedSizeList(int maxSize) { + _maxSize = maxSize; + List = new List(maxSize); + } + + public void Add(T item) { + List.Add(item); + if (List.Count > _maxSize) { + List.RemoveAt(0); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Extensions/LimitedSizeList.cs.meta b/Assets/Scripts/Extensions/LimitedSizeList.cs.meta new file mode 100644 index 0000000..a3dd1ae --- /dev/null +++ b/Assets/Scripts/Extensions/LimitedSizeList.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bd4db2e2399447bdaa6b28d73a4fc7f9 +timeCreated: 1713127625 \ No newline at end of file diff --git a/Assets/Scripts/Extensions/SantJordi.Extensions.asmdef b/Assets/Scripts/Extensions/SantJordi.Extensions.asmdef new file mode 100644 index 0000000..1d1f7fa --- /dev/null +++ b/Assets/Scripts/Extensions/SantJordi.Extensions.asmdef @@ -0,0 +1,3 @@ +{ + "name": "SantJordi.Extensions" +} diff --git a/Assets/Scripts/Extensions/SantJordi.Extensions.asmdef.meta b/Assets/Scripts/Extensions/SantJordi.Extensions.asmdef.meta new file mode 100644 index 0000000..0fad0a3 --- /dev/null +++ b/Assets/Scripts/Extensions/SantJordi.Extensions.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b347d0ff97f738846abb5625028d64db +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Tests.meta b/Assets/Scripts/Tests.meta new file mode 100644 index 0000000..441f9e8 --- /dev/null +++ b/Assets/Scripts/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dede9b43c4aed9843a524ea11cb932a8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Tests/KeySequenceTests.cs b/Assets/Scripts/Tests/KeySequenceTests.cs new file mode 100644 index 0000000..3138f11 --- /dev/null +++ b/Assets/Scripts/Tests/KeySequenceTests.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using Domain; +using NUnit.Framework; + +public class KeySequenceTests { + [Test] + public void NoPresses_DontContain() { + List sequence = new() { 0x1, 0x2, 0x3 }; + KeyHistory history = new(); + + Assert.IsFalse(history.ContainsSequence(sequence)); + } + + [Test] + public void CorrectPresses_Contains() { + List sequence = new() { 0x1, 0x2, 0x3 }; + KeyHistory history = new(); + + history.KeyPressed(0x1); + history.KeyPressed(0x2); + history.KeyPressed(0x3); + + Assert.IsTrue(history.ContainsSequence(sequence)); + } + + [Test] + public void CorrectPresses_BeforeLast_DontContain() { + List sequence = new() { 0x1, 0x2, 0x3 }; + KeyHistory history = new(); + + history.KeyPressed(0x1); + history.KeyPressed(0x2); + history.KeyPressed(0x3); + history.KeyPressed(0x1); + + Assert.IsFalse(history.ContainsSequence(sequence)); + } + + [Test] + public void IncorrectPresses_DontContain() { + List sequence = new() { 0x1, 0x2, 0x3 }; + KeyHistory history = new(); + + history.KeyPressed(0x1); + history.KeyPressed(0x3); + history.KeyPressed(0x2); + + Assert.IsFalse(history.ContainsSequence(sequence)); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Tests/KeySequenceTests.cs.meta b/Assets/Scripts/Tests/KeySequenceTests.cs.meta new file mode 100644 index 0000000..84e9eaa --- /dev/null +++ b/Assets/Scripts/Tests/KeySequenceTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8ab5fe36e022dd4d9dbbb15c6198fb3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Tests/Tests.asmdef b/Assets/Scripts/Tests/Tests.asmdef new file mode 100644 index 0000000..768132f --- /dev/null +++ b/Assets/Scripts/Tests/Tests.asmdef @@ -0,0 +1,24 @@ +{ + "name": "Tests", + "rootNamespace": "", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "SantJordi.Domain" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Scripts/Tests/Tests.asmdef.meta b/Assets/Scripts/Tests/Tests.asmdef.meta new file mode 100644 index 0000000..fd6254b --- /dev/null +++ b/Assets/Scripts/Tests/Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e70aee605542b224b8274efcc111c230 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/View/CTrencadaInput.cs b/Assets/Scripts/View/CTrencadaInput.cs index 59ff2fb..4830403 100644 --- a/Assets/Scripts/View/CTrencadaInput.cs +++ b/Assets/Scripts/View/CTrencadaInput.cs @@ -21,7 +21,7 @@ namespace View { private void CheckInput() { _customInput.UpdateInput(); - if (_customInput.KeyDown(typeof(CedillaReader))) + if (_customInput.KeyDown(typeof(GeminadaReader))) _click.Execute(); }