From 9c1a6c45a0d4c0ab808294525259e5452b19ccd2 Mon Sep 17 00:00:00 2001 From: dougp Date: Wed, 5 Dec 2018 14:45:13 -0500 Subject: [PATCH 01/47] PUBLISH: 0.0.13-preview --- Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs | 2 +- Packages/com.unity.inputsystem/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs index ffe087500d..ba668046d9 100644 --- a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs +++ b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs @@ -4,7 +4,7 @@ // Keep this in sync with "Packages/com.unity.inputsystem/package.json". // NOTE: Unfortunately, System.Version doesn't use semantic versioning so we can't include // "-preview" suffixes here. -[assembly: AssemblyVersion("0.0.12")] +[assembly: AssemblyVersion("0.0.13")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests")] diff --git a/Packages/com.unity.inputsystem/package.json b/Packages/com.unity.inputsystem/package.json index 18d25a60b3..368c9b4c0f 100755 --- a/Packages/com.unity.inputsystem/package.json +++ b/Packages/com.unity.inputsystem/package.json @@ -1,7 +1,7 @@ { "name": "com.unity.inputsystem", "displayName": "Input System", - "version": "0.0.12-preview", + "version": "0.0.13-preview", "unity": "2018.2", "description": "A new input system.", "keywords": [ From ecd6941ef1e84ebfc0de2ef63e0d017f266c576f Mon Sep 17 00:00:00 2001 From: dougp Date: Tue, 11 Dec 2018 14:23:37 -0500 Subject: [PATCH 02/47] Bump date. --- Packages/com.unity.inputsystem/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index b71aab49ef..f1ec359088 100755 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [0.0.14-preview] - 2018-12-?? +## [0.0.14-preview] - 2018-12-11 ### Changed From 0b46a673f5f07a7853367ee2cd9cc96f2d5cb8c5 Mon Sep 17 00:00:00 2001 From: dougp Date: Tue, 11 Dec 2018 14:28:12 -0500 Subject: [PATCH 03/47] PUBLISH: 0.0.14-preview --- Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs | 2 +- Packages/com.unity.inputsystem/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs index ba668046d9..c38daf53e2 100644 --- a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs +++ b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs @@ -4,7 +4,7 @@ // Keep this in sync with "Packages/com.unity.inputsystem/package.json". // NOTE: Unfortunately, System.Version doesn't use semantic versioning so we can't include // "-preview" suffixes here. -[assembly: AssemblyVersion("0.0.13")] +[assembly: AssemblyVersion("0.0.14")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests")] diff --git a/Packages/com.unity.inputsystem/package.json b/Packages/com.unity.inputsystem/package.json index 368c9b4c0f..2efef44ba0 100755 --- a/Packages/com.unity.inputsystem/package.json +++ b/Packages/com.unity.inputsystem/package.json @@ -1,7 +1,7 @@ { "name": "com.unity.inputsystem", "displayName": "Input System", - "version": "0.0.13-preview", + "version": "0.0.14-preview", "unity": "2018.2", "description": "A new input system.", "keywords": [ From bdb556e64749c2dbd7218e31c080d48f3053388f Mon Sep 17 00:00:00 2001 From: dougp Date: Wed, 19 Dec 2018 15:34:43 -0500 Subject: [PATCH 04/47] PUBLISH: 0.1.1 --- Packages/com.unity.inputsystem/CHANGELOG.md | 2 +- Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs | 2 +- Packages/com.unity.inputsystem/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index cbe33b2488..195b3c1d58 100755 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to the input system package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [0.1.0-preview] - 12/19/2018 +## [0.1.1-preview] - 2018-12-19 NOTE: The minimum version requirement for the new input system has been bumped to 2018.3. The previous minum requirement of 2018.2 is no longer supported. diff --git a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs index a1299e7bcc..9697ef26dc 100644 --- a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs +++ b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs @@ -4,7 +4,7 @@ // Keep this in sync with "Packages/com.unity.inputsystem/package.json". // NOTE: Unfortunately, System.Version doesn't use semantic versioning so we can't include // "-preview" suffixes here. -[assembly: AssemblyVersion("0.1.0")] +[assembly: AssemblyVersion("0.1.1")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests")] diff --git a/Packages/com.unity.inputsystem/package.json b/Packages/com.unity.inputsystem/package.json index 5f138af242..3761b747ba 100755 --- a/Packages/com.unity.inputsystem/package.json +++ b/Packages/com.unity.inputsystem/package.json @@ -1,7 +1,7 @@ { "name": "com.unity.inputsystem", "displayName": "Input System", - "version": "0.1.0-preview", + "version": "0.1.1-preview", "unity": "2018.3", "description": "A new input system which can be used as a more extensible and customizable alternative to Unity's classic input system in UnityEngine.Input.", "keywords": [ From fde6b76552fb683ad8a738b60dc6699e715ca0c2 Mon Sep 17 00:00:00 2001 From: dougp Date: Wed, 19 Dec 2018 16:32:17 -0500 Subject: [PATCH 05/47] PUBLISH: 0.1.2-preview --- Packages/com.unity.inputsystem/CHANGELOG.md | 2 +- .../InputSystem/AssemblyInfo.cs | 2 +- .../Editor/InputSettingsProvider.cs | 10 +- .../InputSystem/InputManager.cs | 24 +- .../Tests/InputSystem/CoreTests_Actions.cs | 9690 ++++++++--------- Packages/com.unity.inputsystem/package.json | 7 +- README.md | 9 +- 7 files changed, 4873 insertions(+), 4871 deletions(-) diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 195b3c1d58..72c730a2ed 100755 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to the input system package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [0.1.1-preview] - 2018-12-19 +## [0.1.2-preview] - 2018-12-19 NOTE: The minimum version requirement for the new input system has been bumped to 2018.3. The previous minum requirement of 2018.2 is no longer supported. diff --git a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs index 9697ef26dc..b66febbba9 100644 --- a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs +++ b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs @@ -4,7 +4,7 @@ // Keep this in sync with "Packages/com.unity.inputsystem/package.json". // NOTE: Unfortunately, System.Version doesn't use semantic versioning so we can't include // "-preview" suffixes here. -[assembly: AssemblyVersion("0.1.1")] +[assembly: AssemblyVersion("0.1.2")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests")] diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/InputSettingsProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/InputSettingsProvider.cs index 3cb5d39fc0..a157a1a3e4 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/InputSettingsProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/InputSettingsProvider.cs @@ -4,11 +4,11 @@ using System.Linq; using UnityEditor; using UnityEditorInternal; -using UnityEngine.Experimental.Input.Utilities; - -////TODO: detect if new input backends are enabled and put UI in here to enable them if needed - -////TODO: keywords (2019.1+) +using UnityEngine.Experimental.Input.Utilities; + +////TODO: detect if new input backends are enabled and put UI in here to enable them if needed + +////TODO: keywords (2019.1+) #pragma warning disable CS0414 namespace UnityEngine.Experimental.Input.Editor { diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs index f6ffdbbc33..0f8789978f 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs @@ -2271,16 +2271,16 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev else if (updateType == InputUpdateType.BeforeRender) { isBeforeRenderUpdate = true; - } - - // See if we're supposed to only take events up to a certain time. - // NOTE: We do not require the events in the queue to be sorted. Instead, we will walk over - // all events in the buffer each time. Note that if there are multiple events for the same - // device, it depends on the producer of these events to queue them in correct order. - // Otherwise, once an event with a newer timestamp has been processed, events coming later - // in the buffer and having older timestamps will get rejected. - - var timesliceTime = m_Runtime.currentTime; + } + + // See if we're supposed to only take events up to a certain time. + // NOTE: We do not require the events in the queue to be sorted. Instead, we will walk over + // all events in the buffer each time. Note that if there are multiple events for the same + // device, it depends on the producer of these events to queue them in correct order. + // Otherwise, once an event with a newer timestamp has been processed, events coming later + // in the buffer and having older timestamps will get rejected. + + var timesliceTime = m_Runtime.currentTime; #if UNITY_2019_1_OR_NEWER var timesliceEvents = false; timesliceEvents = gameIsPlayingAndHasFocus && m_Settings.timesliceEvents; // We never timeslice for editor updates. @@ -2298,8 +2298,8 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev InputUpdate.s_LastFixedUpdateTime = timesliceTime; } #endif - - // Early out if there's no events to process. + + // Early out if there's no events to process. if (eventBuffer.eventCount <= 0) { if (buffersToUseForUpdate != updateType) diff --git a/Packages/com.unity.inputsystem/Tests/InputSystem/CoreTests_Actions.cs b/Packages/com.unity.inputsystem/Tests/InputSystem/CoreTests_Actions.cs index 928c3cb270..47b64fa45d 100644 --- a/Packages/com.unity.inputsystem/Tests/InputSystem/CoreTests_Actions.cs +++ b/Packages/com.unity.inputsystem/Tests/InputSystem/CoreTests_Actions.cs @@ -1,4845 +1,4845 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text.RegularExpressions; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.Experimental.Input; -using UnityEngine.Experimental.Input.Composites; -using UnityEngine.Experimental.Input.Controls; -using UnityEngine.Experimental.Input.Interactions; -using UnityEngine.Experimental.Input.Layouts; -using UnityEngine.Experimental.Input.LowLevel; -using UnityEngine.Experimental.Input.Processors; -using UnityEngine.TestTools; -using UnityEngine.TestTools.Utils; -using UnityEngine.TestTools.Constraints; -using Is = UnityEngine.TestTools.Constraints.Is; -using Property = NUnit.Framework.PropertyAttribute; - -#pragma warning disable CS0649 -[SuppressMessage("ReSharper", "AccessToStaticMemberViaDerivedType")] -partial class CoreTests -{ - [Test] - [Category("Actions")] - public void Actions_CanTargetSingleControl() - { - var gamepad = InputSystem.AddDevice(); - var action = new InputAction(binding: "/leftStick"); - - Assert.That(action.controls, Has.Count.EqualTo(1)); - Assert.That(action.controls, Has.Exactly(1).SameAs(gamepad.leftStick)); - } - - [Test] - [Category("Actions")] - public void Actions_CanTargetMultipleControls() - { - var gamepad = InputSystem.AddDevice(); - var action = new InputAction(binding: "/*stick"); - - Assert.That(action.controls, Has.Count.EqualTo(2)); - Assert.That(action.controls, Has.Exactly(1).SameAs(gamepad.leftStick)); - Assert.That(action.controls, Has.Exactly(1).SameAs(gamepad.rightStick)); - - // Make sure that if we actuate both controls in a single event, we still - // get them to come through as two separate triggers. - - var receivedControls = new List(); - action.performed += ctx => { receivedControls.Add(ctx.control); }; - - action.Enable(); - - InputSystem.QueueStateEvent(gamepad, new GamepadState {leftStick = Vector2.left, rightStick = Vector2.right}); - InputSystem.Update(); - - Assert.That(receivedControls, Has.Count.EqualTo(2)); - Assert.That(receivedControls, Has.Exactly(1).SameAs(gamepad.leftStick)); - Assert.That(receivedControls, Has.Exactly(1).SameAs(gamepad.rightStick)); - } - - [Test] - [Category("Actions")] - [Ignore("TODO")] - public void TODO_Actions_WhenSeveralBindingsResolveToSameControl_ThenWhatDoWeDoXXX() - { - Assert.Fail(); - } - - [Test] - [Category("Actions")] - [Ignore("TODO")] - public void TODO_Actions_CanLayerMapsOnTopOfEachOther() - { - // Make up a layered control scheme three levels deep. - /* - var fpsControls = new InputActionMap("fpsControls"); - var moveAction = fpsControls.AddAction("move"); - var shootAction = fpsControls.AddAction("shoot"); - var lookAction = fpsControls.AddAction("look"); - var sniperControls = new InputActionMap("sniper", extend: fpsControls); - var scopeAction = sniperControls.AddAction("scope"); - var swapScopeControls = new InputActionMap("swapScope", extend: sniperControls); - - swapScopeControls.AddBinding(); - - // Information from 'baseMap' coming through on 'derivedMap'. - Assert.That(sniperControls.actions, Has.Count.EqualTo(1)); - Assert.That(sniperControls["action"], Is.TypeOf()); - Assert.That(sniperControls["action"], Is.Not.SameAs(baseAction)); - Assert.That(sniperControls["action"].actionMap, Is.SameAs(derivedMap)); - Assert.That(sniperControls["action"].bindings, Has.Count.EqualTo(1)); - Assert.That(sniperControls["action"].bindings[0].path, Is.EqualTo("/buttonSouth")); - - // Information from 'baseMap' coming through on 'derivedFromDerivedMap'. - Assert.That(derivedFromDerivedMap.actions, Has.Count.EqualTo(1)); - Assert.That(derivedFromDerivedMap["action"], Is.TypeOf()); - Assert.That(derivedFromDerivedMap["action"], Is.Not.SameAs(baseAction)); - Assert.That(derivedFromDerivedMap["action"].actionMap, Is.SameAs(derivedFromDerivedMap)); - Assert.That(derivedFromDerivedMap["action"].bindings, Has.Count.EqualTo(1)); - Assert.That(derivedFromDerivedMap["action"].bindings[0].path, Is.EqualTo("/buttonSouth")); - */ - - Assert.Fail(); - } - - [Test] - [Category("Actions")] - [Ignore("TODO")] - public void TODO_Actions_MapsCanBeBasedOnOtherMaps() - { - var baseMap = new InputActionMap("Base"); - var baseAction = baseMap.AddAction("action", binding: "/buttonSouth"); - var derivedMap = new InputActionMap("Derived", extend: baseMap); - var derivedFromDerivedMap = new InputActionMap("DerivedFromDerived", extend: derivedMap); - - //NO! We want to set up bindings on the *existing* action - // But how can we have the same action answer with different bindings depending on context? - // Should we remove the per-action control and device arrays? How do singleton actions deal with that then? - // Alternatively, we can change how you connect to endpoints such that you don't go to an individual action - // to connect to it. - // It may really make sense to completely divorce delivery from InputAction and make that a pure configuration object. - - // Or... we simply don't list actions from the base in the derived map... I.e. a map will only list the - // information *directly* defined in the map. Explicit lookups could still take bases into account. - // But then, how do you query the bindings for an action in a derived map? - - // Or... we actually *do* replicate the information from the base in the derived map but triggering actions in - // a derived map also triggers actions in the base map - - // Information from 'baseMap' coming through on 'derivedMap'. - Assert.That(derivedMap.actions, Has.Count.EqualTo(1)); - Assert.That(derivedMap["action"], Is.TypeOf()); - Assert.That(derivedMap["action"], Is.Not.SameAs(baseAction)); - Assert.That(derivedMap["action"].actionMap, Is.SameAs(derivedMap)); - Assert.That(derivedMap["action"].bindings, Has.Count.EqualTo(1)); - Assert.That(derivedMap["action"].bindings[0].path, Is.EqualTo("/buttonSouth")); - - // Information from 'baseMap' coming through on 'derivedFromDerivedMap'. - Assert.That(derivedFromDerivedMap.actions, Has.Count.EqualTo(1)); - Assert.That(derivedFromDerivedMap["action"], Is.TypeOf()); - Assert.That(derivedFromDerivedMap["action"], Is.Not.SameAs(baseAction)); - Assert.That(derivedFromDerivedMap["action"].actionMap, Is.SameAs(derivedFromDerivedMap)); - Assert.That(derivedFromDerivedMap["action"].bindings, Has.Count.EqualTo(1)); - Assert.That(derivedFromDerivedMap["action"].bindings[0].path, Is.EqualTo("/buttonSouth")); - } - - [Test] - [Category("Actions")] - [Ignore("TODO")] - public void TODO_Actions_MapsCanBeBasedOnOtherMaps_AndPickUpChangesMadeToTheirBaseMaps() - { - Assert.Fail(); - } - - [Test] - [Category("Actions")] - [Ignore("TODO")] - public void TODO_Actions_MapsCanBeBasedOnOtherMaps_AndAddBindingsToActionsDefinedInBaseMaps() - { - var baseMap = new InputActionMap("Base"); - var action = baseMap.AddAction("action", binding: "/buttonSouth"); - - var derivedMap = new InputActionMap("Derived", extend: baseMap); - derivedMap.AddBinding("/buttonNorth", action: "action"); - - var gamepad = InputSystem.AddDevice(); - - var actionWasPerformed = false; - action.performed += _ => actionWasPerformed = true; - - derivedMap.Enable(); - - InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.North)); - InputSystem.Update(); - - Assert.That(actionWasPerformed); - } - - [Test] - [Category("Actions")] - public void Actions_WhenEnabled_TriggerNotification() - { - var map = new InputActionMap("map"); - var action1 = map.AddAction("action1"); - var action2 = map.AddAction("action2"); - new InputActionMap("map2").AddAction("action3"); // Noise. - - InputActionChange? receivedChange = null; - object receivedObject = null; - InputSystem.onActionChange += - (obj, change) => - { - Assert.That(receivedChange, Is.Null); - receivedChange = change; - receivedObject = obj; - }; - - // Enable map. - // Does to trigger a notification for each action in the map. - map.Enable(); - - Assert.That(receivedChange.HasValue); - Assert.That(receivedChange.Value, Is.EqualTo(InputActionChange.ActionMapEnabled)); - Assert.That(receivedObject, Is.SameAs(map)); - - receivedChange = null; - receivedObject = null; - - // Enabling action in map should not trigger notification. - action1.Enable(); - - Assert.That(receivedChange, Is.Null); - - // Disable map. - map.Disable(); - - Assert.That(receivedChange.HasValue); - Assert.That(receivedChange.Value, Is.EqualTo(InputActionChange.ActionMapDisabled)); - Assert.That(receivedObject, Is.SameAs(map)); - - receivedChange = null; - receivedObject = null; - - // Enable single action. - action2.Enable(); - - Assert.That(receivedChange.HasValue); - Assert.That(receivedChange.Value, Is.EqualTo(InputActionChange.ActionEnabled)); - Assert.That(receivedObject, Is.SameAs(action2)); - - receivedChange = null; - receivedObject = null; - - // Disable single action. - action2.Disable(); - - Assert.That(receivedChange.HasValue); - Assert.That(receivedChange.Value, Is.EqualTo(InputActionChange.ActionDisabled)); - Assert.That(receivedObject, Is.SameAs(action2)); - - receivedChange = null; - receivedObject = null; - - // Disabling single action that isn't enabled should not trigger notification. - action2.Disable(); - - Assert.That(receivedChange, Is.Null); - } - - [Test] - [Category("Actions")] - public void Actions_WhenEnabled_GoesIntoWaitingPhase() - { - InputSystem.AddDevice("Gamepad"); - - var action = new InputAction(binding: "/gamepad/leftStick"); - action.Enable(); - - Assert.That(action.phase, Is.EqualTo(InputActionPhase.Waiting)); - } - - [Test] - [Category("Actions")] - public void Actions_CanReadValueFromAction() - { - var action = new InputAction(binding: "/buttonSouth"); - var gamepad = InputSystem.AddDevice(); - - action.Enable(); - - float? receivedValue = null; - action.performed += - ctx => - { - Assert.That(receivedValue, Is.Null); - receivedValue = ctx.ReadValue(); - }; - - InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.South)); - InputSystem.Update(); - - Assert.That(receivedValue, Is.EqualTo(1).Within(0.00001)); - } - - // Some code needs to be able to just generically transfer values from A to B. For this, the - // generic ReadValue() API isn't sufficient. - [Test] - [Category("Actions")] - public unsafe void Actions_CanReadValueFromAction_WithoutKnowingValueType() - { - var action = new InputAction(); - action.AddBinding("/leftStick"); - action.AddCompositeBinding("Dpad") - .With("Up", "/w") - .With("Down", "/s") - .With("Left", "/a") - .With("Right", "/d"); - - var gamepad = InputSystem.AddDevice(); - var keyboard = InputSystem.AddDevice(); - - action.Enable(); - - byte[] receivedValueData = null; - - action.performed += - ctx => - { - Assert.That(receivedValueData, Is.Null); - Assert.That(ctx.valueType, Is.EqualTo(typeof(Vector2))); - Assert.That(ctx.valueSizeInBytes, Is.EqualTo(sizeof(Vector2))); - - var sizeInBytes = ctx.valueSizeInBytes; - receivedValueData = new byte[sizeInBytes]; - fixed(byte* dataPtr = receivedValueData) - { - ctx.ReadValue(dataPtr, sizeInBytes); - } - }; - - InputSystem.QueueStateEvent(gamepad, new GamepadState {leftStick = new Vector2(0.123f, 0.234f)}); - InputSystem.Update(); - - Assert.That(receivedValueData, Has.Length.EqualTo(sizeof(Vector2))); - Assert.That(BitConverter.ToSingle(receivedValueData, 0), - Is.EqualTo(new StickDeadzoneProcessor().Process(new Vector2(0.123f, 0.234f), gamepad.leftStick).x).Within(0.00001)); - Assert.That(BitConverter.ToSingle(receivedValueData, 4), - Is.EqualTo(new StickDeadzoneProcessor().Process(new Vector2(0.123f, 0.234f), gamepad.leftStick).y).Within(0.00001)); - - receivedValueData = null; - - InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.W, Key.A)); - InputSystem.Update(); - - Assert.That(receivedValueData, Has.Length.EqualTo(sizeof(Vector2))); - Assert.That(BitConverter.ToSingle(receivedValueData, 0), - Is.EqualTo((Vector2.up + Vector2.left).normalized.x).Within(0.00001)); - Assert.That(BitConverter.ToSingle(receivedValueData, 4), - Is.EqualTo((Vector2.up + Vector2.left).normalized.y).Within(0.00001)); - } - - [Test] - [Category("Actions")] - public void Actions_ReadingValueOfIncorrectType_ThrowsHelpfulException() - { - var action = new InputAction(binding: "/buttonSouth"); - var gamepad = InputSystem.AddDevice(); - - action.Enable(); - - var receivedCall = false; - action.performed += - ctx => - { - receivedCall = true; - Assert.That(() => ctx.ReadValue(), - Throws.InvalidOperationException.With.Message.Contains("buttonSouth") - .And.With.Message.Contains("float") - .And.With.Message.Contains("Vector2")); - }; - - InputSystem.QueueStateEvent(gamepad, new GamepadState().WithButton(GamepadButton.South)); - InputSystem.Update(); - - Assert.That(receivedCall, Is.True); - } - - [Test] - [Category("Actions")] - public void Actions_CanCreateActionsWithoutAnActionMap() - { - var action = new InputAction(); - - Assert.That(action.actionMap, Is.Null); - } - - [Test] - [Category("Actions")] - public void Actions_PathLeadingNowhereIsIgnored() - { - var action = new InputAction(binding: "nothing"); - - Assert.DoesNotThrow(() => action.Enable()); - } - - [Test] - [Category("Actions")] - public void Actions_StartOutInDisabledPhase() - { - var action = new InputAction(); - - Assert.That(action.phase, Is.EqualTo(InputActionPhase.Disabled)); - } - - [Test] - [Category("Actions")] - public void Actions_LooseActionHasNoMap() - { - var action = new InputAction(); - action.Enable(); // Force to create private action set. - - Assert.That(action.actionMap, Is.Null); - } - - [Test] - [Category("Actions")] - public void Actions_ActionIsPerformedWhenSourceControlChangesValue() - { - var gamepad = InputSystem.AddDevice(); - - var receivedCalls = 0; - InputAction receivedAction = null; - InputControl receivedControl = null; - - var action = new InputAction(binding: "/gamepad/leftStick"); - action.performed += - ctx => - { - ++receivedCalls; - receivedAction = ctx.action; - receivedControl = ctx.control; - - Assert.That(action.phase, Is.EqualTo(InputActionPhase.Performed)); - }; - action.Enable(); - - var state = new GamepadState - { - leftStick = new Vector2(0.5f, 0.5f) - }; - InputSystem.QueueStateEvent(gamepad, state); - InputSystem.Update(); - - Assert.That(receivedCalls, Is.EqualTo(1)); - Assert.That(receivedAction, Is.SameAs(action)); - Assert.That(receivedControl, Is.SameAs(gamepad.leftStick)); - - // Action should be waiting again. - Assert.That(action.phase, Is.EqualTo(InputActionPhase.Waiting)); - } - - [Test] - [Category("Actions")] - public void Actions_CanListenForStateChangeOnEntireDevice() - { - var gamepad = InputSystem.AddDevice(); - - var receivedCalls = 0; - InputControl receivedControl = null; - - var action = new InputAction(binding: "/gamepad"); - action.performed += - ctx => - { - ++receivedCalls; - receivedControl = ctx.control; - }; - action.Enable(); - - var state = new GamepadState - { - rightTrigger = 0.5f - }; - InputSystem.QueueStateEvent(gamepad, state); - InputSystem.Update(); - - Assert.That(receivedCalls, Is.EqualTo(1)); - Assert.That(receivedControl, - Is.SameAs(gamepad)); // We do not drill down to find the actual control that changed. - } - - [Test] - [Category("Actions")] - public void Actions_CanMonitorTriggeredActionsOnActionMap() - { - var gamepad = InputSystem.AddDevice(); - - var map = new InputActionMap(); - var action = map.AddAction("action", "//leftTrigger"); - - var wasTriggered = false; - InputAction receivedAction = null; - InputControl receivedControl = null; - map.actionTriggered += - ctx => - { - Assert.That(wasTriggered, Is.False); - wasTriggered = true; - receivedAction = ctx.action; - receivedControl = ctx.control; - }; - - map.Enable(); - - InputSystem.QueueStateEvent(gamepad, new GamepadState {leftTrigger = 0.5f}); - InputSystem.Update(); - - Assert.That(wasTriggered); - Assert.That(receivedAction, Is.SameAs(action)); - Assert.That(receivedControl, Is.SameAs(gamepad.leftTrigger)); - } - - [Test] - [Category("Actions")] - public void Actions_WhenTriggered_TriggerNotification() - { - var gamepad = InputSystem.AddDevice(); - - var action = new InputAction(binding: "/leftTrigger"); - action.Enable(); - - var receivedPerformed = false; - action.performed += ctx => receivedPerformed = true; - - InputAction receivedAction = null; - InputActionChange? receivedChange = null; - InputSystem.onActionChange += - (a, c) => - { - Assert.That(receivedAction, Is.Null); - Assert.That(receivedPerformed, Is.False); // Notification must come *before* callback. - - receivedAction = (InputAction)a; - receivedChange = c; - - // lastXXX state on action must have been updated. - Assert.That(receivedAction.lastTriggerControl, Is.SameAs(gamepad.leftTrigger)); - }; - - InputSystem.QueueStateEvent(gamepad, new GamepadState { leftTrigger = 0.5f }); - InputSystem.Update(); - - Assert.That(receivedChange, Is.EqualTo(InputActionChange.ActionTriggered)); - Assert.That(receivedAction, Is.SameAs(action)); - } - - [Test] - [Category("Actions")] - [Property("TimesliceEvents", "Off")] - public void Actions_CanRecordActionsAsEvents() - { - var action = new InputAction(); - action.AddBinding("/leftStick"); - action.AddBinding("/rightStick"); - action.AddCompositeBinding("dpad") - .With("Up", "/w") - .With("Down", "/s") - .With("Left", "/a") - .With("Right", "/d"); - - var gamepad = InputSystem.AddDevice(); - var keyboard = InputSystem.AddDevice(); - - action.Enable(); - - using (var queue = new InputActionTrace()) - { - action.performed += queue.RecordAction; - - var state = new GamepadState {leftStick = new Vector2(0.123f, 0.234f)}; - InputSystem.QueueStateEvent(gamepad, state, 0.1234); - state.rightStick = new Vector2(0.345f, 0.456f); - InputSystem.QueueStateEvent(gamepad, state, 0.2345); - InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.W), 0.0987); - InputSystem.Update(); - - Assert.That(queue.count, Is.EqualTo(3)); - - var events = queue.ToArray(); - - Assert.That(events, Has.Length.EqualTo(3)); - Assert.That(events[0].control, Is.SameAs(gamepad.leftStick)); - Assert.That(events[1].control, Is.SameAs(gamepad.rightStick)); - Assert.That(events[2].control, Is.SameAs(keyboard.wKey)); - Assert.That(events[0].time, Is.EqualTo(0.1234).Within(0.00001)); - Assert.That(events[1].time, Is.EqualTo(0.2345).Within(0.00001)); - Assert.That(events[2].time, Is.EqualTo(0.0987).Within(0.00001)); - Assert.That(events[0].action, Is.SameAs(action)); - Assert.That(events[1].action, Is.SameAs(action)); - Assert.That(events[2].action, Is.SameAs(action)); - Assert.That(events[0].phase, Is.EqualTo(InputActionPhase.Performed)); - Assert.That(events[1].phase, Is.EqualTo(InputActionPhase.Performed)); - Assert.That(events[2].phase, Is.EqualTo(InputActionPhase.Performed)); - Assert.That(events[0].ReadValue(), - Is.EqualTo(new StickDeadzoneProcessor().Process(new Vector2(0.123f, 0.234f), gamepad.leftStick)) - .Using(Vector2EqualityComparer.Instance)); - Assert.That(events[1].ReadValue(), - Is.EqualTo(new StickDeadzoneProcessor().Process(new Vector2(0.345f, 0.456f), gamepad.rightStick)) - .Using(Vector2EqualityComparer.Instance)); - Assert.That(events[2].ReadValue(), Is.EqualTo(Vector2.up).Using(Vector2EqualityComparer.Instance)); - - queue.Clear(); - - Assert.That(queue.count, Is.Zero); - Assert.That(queue.ToArray(), Is.Empty); - } - } - - // Actions are able to observe every state change, even if the changes occur within - // the same frame. - [Test] - [Category("Actions")] - public void Actions_PressingAndReleasingButtonInSameUpdate_StillTriggersAction() - { - var gamepad = InputSystem.AddDevice(); - var action = new InputAction(binding: "//