From 2f1498d2b0fae2c6e9f9a8f02b393a7914e63eaf Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Thu, 12 Jan 2023 14:19:02 +0100 Subject: [PATCH 01/31] Adding dependency to a provider package --- Packages/com.unity.inputsystem/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/package.json b/Packages/com.unity.inputsystem/package.json index aac6406678..ec2da987f2 100755 --- a/Packages/com.unity.inputsystem/package.json +++ b/Packages/com.unity.inputsystem/package.json @@ -15,6 +15,7 @@ "xr" ], "dependencies" : { - "com.unity.modules.uielements": "1.0.0" + "com.unity.modules.uielements": "1.0.0", + "com.unity.inputsystem.forui": "1.0.0" } } \ No newline at end of file From c6da50d9ffb487c96e536132b8f824d90905e545 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Wed, 15 Mar 2023 15:47:34 +0100 Subject: [PATCH 02/31] wip --- .../InputSystem/Plugins/InputForUI.meta | 8 +++ .../Plugins/InputForUI/AssemblyInfo.cs | 3 + .../Plugins/InputForUI/AssemblyInfo.cs.meta | 11 ++++ .../InputForUI/InputSystemForUI.asmdef | 15 +++++ .../InputForUI/InputSystemForUI.asmdef.meta | 7 ++ .../Plugins/InputForUI/InputSystemProvider.cs | 65 +++++++++++++++++++ .../InputForUI/InputSystemProvider.cs.meta | 11 ++++ Packages/com.unity.inputsystem/package.json | 3 +- 8 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI.meta create mode 100644 Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs create mode 100644 Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs.meta create mode 100644 Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemForUI.asmdef create mode 100644 Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemForUI.asmdef.meta create mode 100644 Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs create mode 100644 Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs.meta diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI.meta b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI.meta new file mode 100644 index 0000000000..7fc981398a --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 96500a17645c67442a0ccdca007e6d28 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs new file mode 100644 index 0000000000..570168457b --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("UnityEngine.InputForUIVisualizer")] diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs.meta new file mode 100644 index 0000000000..fc5bea2c78 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65c861c7ef9bee2479c728694e87ea45 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemForUI.asmdef b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemForUI.asmdef new file mode 100644 index 0000000000..b1326b2bfa --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemForUI.asmdef @@ -0,0 +1,15 @@ +{ + "name": "Unity.InputSystem.ForUI", + "references": [ + "Unity.InputSystem" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemForUI.asmdef.meta b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemForUI.asmdef.meta new file mode 100644 index 0000000000..2a814154e4 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemForUI.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 09dcc9c0126b6b34ab2a877b8f2277f5 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs new file mode 100644 index 0000000000..e156e6a60c --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -0,0 +1,65 @@ +using UnityEditor; +using UnityEngine; +using UnityEngine.InputForUI; +using Event = UnityEngine.InputForUI.Event; +using EventProvider = UnityEngine.InputForUI.EventProvider; + +namespace InputSystem.Plugins.InputForUI +{ +#if UNITY_EDITOR + [InitializeOnLoad] +#endif + internal class InputSystemProvider : IEventProviderImpl + { + private InputEventPartialProvider _inputEventPartialProvider; + + static InputSystemProvider() + { + // disable for now + EventProvider.SetInputSystemProvider(new InputSystemProvider()); + } + + [RuntimeInitializeOnLoadMethod(loadType: RuntimeInitializeLoadType.SubsystemRegistration)] + private static void Bootstrap() + { + // will invoke static class constructor + } + + public void Initialize() + { + _inputEventPartialProvider ??= new InputEventPartialProvider(); + _inputEventPartialProvider.Initialize(); + } + + public void Shutdown() + { + } + + public void Update() + { + _inputEventPartialProvider.Update(); + + // TODO implement action mapping to axes + } + + public void OnFocusChanged(bool focus) + { + _inputEventPartialProvider.OnFocusChanged(focus); + } + + public bool RequestCurrentState(Event.Type type) + { + if (_inputEventPartialProvider.RequestCurrentState(type)) + return true; + + switch (type) + { + // TODO + default: + return false; + } + } + + public uint playerCount => 1; // TODO + } +} diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs.meta new file mode 100644 index 0000000000..227d101fac --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6965b068653ebe45986cb10b38854d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.inputsystem/package.json b/Packages/com.unity.inputsystem/package.json index ec2da987f2..aac6406678 100755 --- a/Packages/com.unity.inputsystem/package.json +++ b/Packages/com.unity.inputsystem/package.json @@ -15,7 +15,6 @@ "xr" ], "dependencies" : { - "com.unity.modules.uielements": "1.0.0", - "com.unity.inputsystem.forui": "1.0.0" + "com.unity.modules.uielements": "1.0.0" } } \ No newline at end of file From 9ee7492b022640e792c03c197cc447f81496a51f Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Mon, 20 Mar 2023 17:37:56 +0100 Subject: [PATCH 03/31] wip --- .../Plugins/InputForUI/InputSystemProvider.cs | 194 +++++++++++++++++- 1 file changed, 191 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index e156e6a60c..fbfcba2cef 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -1,7 +1,13 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; +using Unity.IntegerTime; using UnityEditor; using UnityEngine; using UnityEngine.InputForUI; +using UnityEngine.InputSystem; using Event = UnityEngine.InputForUI.Event; +using EventModifiers = UnityEngine.InputForUI.EventModifiers; using EventProvider = UnityEngine.InputForUI.EventProvider; namespace InputSystem.Plugins.InputForUI @@ -13,10 +19,15 @@ internal class InputSystemProvider : IEventProviderImpl { private InputEventPartialProvider _inputEventPartialProvider; + private Configuration _cfg; + + private List _events = new List(); + static InputSystemProvider() { - // disable for now - EventProvider.SetInputSystemProvider(new InputSystemProvider()); + // TODO check if input system is enabled before doing this + // enable me to test! + // EventProvider.SetInputSystemProvider(new InputSystemProvider()); } [RuntimeInitializeOnLoadMethod(loadType: RuntimeInitializeLoadType.SubsystemRegistration)] @@ -25,21 +36,37 @@ private static void Bootstrap() // will invoke static class constructor } + private EventModifiers _eventModifiers => _inputEventPartialProvider._eventModifiers; + + private DiscreteTime _currentTime => (DiscreteTime)Time.timeAsRational; + + private const uint kDefaultPlayerId = 0u; + public void Initialize() { _inputEventPartialProvider ??= new InputEventPartialProvider(); _inputEventPartialProvider.Initialize(); + + // TODO should UITK somehow override this? + _cfg = Configuration.GetDefaultConfiguration(); + RegisterActions(_cfg); } public void Shutdown() { + UnregisterActions(_cfg); + + _inputEventPartialProvider.Shutdown(); + _inputEventPartialProvider = null; } public void Update() { _inputEventPartialProvider.Update(); - // TODO implement action mapping to axes + foreach (var ev in _events) // TODO sort them + EventProvider.Dispatch(ev); + _events.Clear(); } public void OnFocusChanged(bool focus) @@ -61,5 +88,166 @@ public bool RequestCurrentState(Event.Type type) } public uint playerCount => 1; // TODO + + private void DispatchFromCallback(in Event ev) + { + _events.Add(ev); + } + + private void OnPointerPerformed(InputAction.CallbackContext ctx) + { + // Debug.Log($"Pointer performed {ctx.control.name}"); + + var position = ctx.ReadValue(); + var delta = Vector2.zero; + var targetDisplay = 0; + + DispatchFromCallback(Event.From(new PointerEvent + { + type = PointerEvent.Type.PointerMoved, + pointerIndex = 0, + position = position, + deltaPosition = delta, + scroll = Vector2.zero, + displayIndex = targetDisplay, + tilt = Vector2.zero, + twist = 0.0f, + pressure = 0.0f, + isInverted = false, + button = 0, + //buttonsState = _mouseState.ButtonsState, + clickCount = 0, + timestamp = _currentTime, + eventSource = EventSource.Mouse, + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); + } + + private void OnMovePerformed(InputAction.CallbackContext ctx) + { + var direction = NavigationEvent.DetermineMoveDirection(ctx.ReadValue()); + if (direction == NavigationEvent.Direction.None) + return; + // _navigationEventRepeatHelper.Reset(); + + // TODO repeat rate + DispatchFromCallback(Event.From(new NavigationEvent + { + type = NavigationEvent.Type.Move, + direction = direction, + timestamp = _currentTime, + eventSource = EventSource.Unspecified, // TODO + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); + } + + private void OnSubmitPerformed(InputAction.CallbackContext ctx) + { + // TODO repeat rate + DispatchFromCallback(Event.From(new NavigationEvent + { + type = NavigationEvent.Type.Submit, + direction = NavigationEvent.Direction.None, + timestamp = _currentTime, + eventSource = EventSource.Unspecified, // TODO + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); + } + + private void OnCancelPerformed(InputAction.CallbackContext ctx) + { + // TODO repeat rate + DispatchFromCallback(Event.From(new NavigationEvent + { + type = NavigationEvent.Type.Cancel, + direction = NavigationEvent.Direction.None, + timestamp = _currentTime, + eventSource = EventSource.Unspecified, // TODO + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); + } + + private void RegisterActions(Configuration cfg) + { + if (cfg.PointAction.action != null) + cfg.PointAction.action.performed += OnPointerPerformed; + + if (cfg.MoveAction.action != null) + cfg.MoveAction.action.performed += OnMovePerformed; + + if (cfg.SubmitAction.action != null) + cfg.SubmitAction.action.performed += OnSubmitPerformed; + + if (cfg.CancelAction.action != null) + cfg.CancelAction.action.performed += OnCancelPerformed; + + cfg.InputActionAsset.Enable(); + } + + private void UnregisterActions(Configuration cfg) + { + if (cfg.PointAction.action != null) + cfg.PointAction.action.performed -= OnPointerPerformed; + + if (cfg.MoveAction.action != null) + cfg.MoveAction.action.performed -= OnMovePerformed; + + if (cfg.SubmitAction.action != null) + cfg.SubmitAction.action.performed -= OnSubmitPerformed; + + if (cfg.CancelAction.action != null) + cfg.CancelAction.action.performed -= OnCancelPerformed; + + cfg.InputActionAsset.Disable(); + } + + public struct Configuration + { + public InputActionAsset InputActionAsset; + public InputActionReference PointAction; + public InputActionReference MoveAction; + public InputActionReference SubmitAction; + public InputActionReference CancelAction; + public InputActionReference LeftClickAction; + public InputActionReference MiddleClickAction; + public InputActionReference RightClickAction; + public InputActionReference ScrollWheelAction; + //public InputActionReference TrackedDevicePositionAction; + //public InputActionReference TrackedDeviceOrientationAction; + + // public float InputActionsPerSecond; + // public float RepeatDelay; + + public IEnumerable InputActionReferences() + { + yield return PointAction; + } + + public static Configuration GetDefaultConfiguration() + { + // TODO doesn't work in player builds + //var asset = (InputActionAsset)AssetDatabase.LoadAssetAtPath("Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/DefaultInputActions.inputactions", typeof(InputActionAsset)); + var asset = new DefaultInputActions().asset; + + return new Configuration + { + InputActionAsset = asset, + PointAction = InputActionReference.Create(asset.FindAction("UI/Point")), + MoveAction = InputActionReference.Create(asset.FindAction("UI/Navigate")), + SubmitAction = InputActionReference.Create(asset.FindAction("UI/Submit")), + CancelAction = InputActionReference.Create(asset.FindAction("UI/Cancel")), + LeftClickAction = InputActionReference.Create(asset.FindAction("UI/Click")), + MiddleClickAction = InputActionReference.Create(asset.FindAction("UI/MiddleClick")), + RightClickAction = InputActionReference.Create(asset.FindAction("UI/RightClick")), + ScrollWheelAction = InputActionReference.Create(asset.FindAction("UI/ScrollWheel")), + // InputActionsPerSecond = 10, + // RepeatDelay = 0.5f, + }; + } + } } } From 622d6dedc81f17b8dba252f7238d7c064a7f3c2f Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Mon, 20 Mar 2023 17:48:12 +0100 Subject: [PATCH 04/31] wip --- .../Plugins/InputForUI/InputSystemProvider.cs | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index fbfcba2cef..f5478c8c7f 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -170,6 +170,48 @@ private void OnCancelPerformed(InputAction.CallbackContext ctx) eventModifiers = _eventModifiers })); } + + private void OnLeftClickPerformed(InputAction.CallbackContext ctx) + { + } + + private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) + { + } + + private void OnRightClickPerformed(InputAction.CallbackContext ctx) + { + } + + private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) + { + // TODO + var position = Vector2.zero; + var delta = Vector2.zero; + var scroll = ctx.ReadValue(); + var targetDisplay = 0; + + DispatchFromCallback(Event.From(new PointerEvent + { + type = PointerEvent.Type.Scroll, + pointerIndex = 0, + position = position, + deltaPosition = delta, + scroll = scroll, + displayIndex = targetDisplay, + tilt = Vector2.zero, + twist = 0.0f, + pressure = 0.0f, + isInverted = false, + button = 0, + //buttonsState = _mouseState.ButtonsState, + clickCount = 0, + timestamp = _currentTime, + eventSource = EventSource.Mouse, + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); + } private void RegisterActions(Configuration cfg) { @@ -185,6 +227,20 @@ private void RegisterActions(Configuration cfg) if (cfg.CancelAction.action != null) cfg.CancelAction.action.performed += OnCancelPerformed; + if (cfg.LeftClickAction.action != null) + cfg.LeftClickAction.action.performed += OnLeftClickPerformed; + + if (cfg.MiddleClickAction.action != null) + cfg.MiddleClickAction.action.performed += OnMiddleClickPerformed; + + if (cfg.RightClickAction.action != null) + cfg.RightClickAction.action.performed += OnRightClickPerformed; + + if (cfg.ScrollWheelAction.action != null) + cfg.ScrollWheelAction.action.performed += OnScrollWheelPerformed; + + // When adding new one's don't forget to add them to UnregisterActions + cfg.InputActionAsset.Enable(); } @@ -201,7 +257,19 @@ private void UnregisterActions(Configuration cfg) if (cfg.CancelAction.action != null) cfg.CancelAction.action.performed -= OnCancelPerformed; - + + if (cfg.LeftClickAction.action != null) + cfg.LeftClickAction.action.performed -= OnLeftClickPerformed; + + if (cfg.MiddleClickAction.action != null) + cfg.MiddleClickAction.action.performed -= OnMiddleClickPerformed; + + if (cfg.RightClickAction.action != null) + cfg.RightClickAction.action.performed -= OnRightClickPerformed; + + if (cfg.ScrollWheelAction.action != null) + cfg.ScrollWheelAction.action.performed -= OnScrollWheelPerformed; + cfg.InputActionAsset.Disable(); } From 96ce804e175b7327ff270fd424b14ace51841afb Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Wed, 22 Mar 2023 11:19:05 +0100 Subject: [PATCH 05/31] wip --- .../Plugins/InputForUI/InputSystemProvider.cs | 179 +++++++++++------- 1 file changed, 111 insertions(+), 68 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index f5478c8c7f..4986ac784c 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -1,14 +1,14 @@ -using System; using System.Collections.Generic; -using JetBrains.Annotations; using Unity.IntegerTime; -using UnityEditor; using UnityEngine; using UnityEngine.InputForUI; using UnityEngine.InputSystem; using Event = UnityEngine.InputForUI.Event; using EventModifiers = UnityEngine.InputForUI.EventModifiers; using EventProvider = UnityEngine.InputForUI.EventProvider; +#if UNITY_EDITOR +using UnityEditor; +#endif namespace InputSystem.Plugins.InputForUI { @@ -21,13 +21,23 @@ internal class InputSystemProvider : IEventProviderImpl private Configuration _cfg; + private InputActionAsset _inputActionAsset; + private InputActionReference _pointAction; + private InputActionReference _moveAction; + private InputActionReference _submitAction; + private InputActionReference _cancelAction; + private InputActionReference _leftClickAction; + private InputActionReference _middleClickAction; + private InputActionReference _rightClickAction; + private InputActionReference _scrollWheelAction; + private List _events = new List(); static InputSystemProvider() { // TODO check if input system is enabled before doing this // enable me to test! - // EventProvider.SetInputSystemProvider(new InputSystemProvider()); + EventProvider.SetInputSystemProvider(new InputSystemProvider()); } [RuntimeInitializeOnLoadMethod(loadType: RuntimeInitializeLoadType.SubsystemRegistration)] @@ -173,6 +183,21 @@ private void OnCancelPerformed(InputAction.CallbackContext ctx) private void OnLeftClickPerformed(InputAction.CallbackContext ctx) { + +// var index = GetPointerStateIndexFor(ref context); +// if (index == -1) +// return; +// +// ref var state = ref GetPointerStateForIndex(index); +// bool wasPressed = state.leftButton.isPressed; +// state.leftButton.isPressed = context.ReadValueAsButton(); +// state.changedThisFrame = true; +// if (IgnoreNextClick(ref context, wasPressed)) +// state.leftButton.ignoreNextClick = true; +// #if UNITY_2023_1_OR_NEWER +// state.eventData.displayIndex = GetDisplayIndexFor(context.control); +// #endif +// } private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) @@ -215,103 +240,121 @@ private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) private void RegisterActions(Configuration cfg) { - if (cfg.PointAction.action != null) - cfg.PointAction.action.performed += OnPointerPerformed; - - if (cfg.MoveAction.action != null) - cfg.MoveAction.action.performed += OnMovePerformed; + _inputActionAsset = InputActionAsset.FromJson(cfg.InputActionAssetAsJson); + + _pointAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.PointAction)); + _moveAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.MoveAction)); + _submitAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.SubmitAction)); + _cancelAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.CancelAction)); + _leftClickAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.LeftClickAction)); + _middleClickAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.MiddleClickAction)); + _rightClickAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.RightClickAction)); + _scrollWheelAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.ScrollWheelAction)); + + if (_pointAction.action != null) + _pointAction.action.performed += OnPointerPerformed; + + if (_moveAction.action != null) + _moveAction.action.performed += OnMovePerformed; - if (cfg.SubmitAction.action != null) - cfg.SubmitAction.action.performed += OnSubmitPerformed; + if (_submitAction.action != null) + _submitAction.action.performed += OnSubmitPerformed; - if (cfg.CancelAction.action != null) - cfg.CancelAction.action.performed += OnCancelPerformed; + if (_cancelAction.action != null) + _cancelAction.action.performed += OnCancelPerformed; - if (cfg.LeftClickAction.action != null) - cfg.LeftClickAction.action.performed += OnLeftClickPerformed; + if (_leftClickAction.action != null) + _leftClickAction.action.performed += OnLeftClickPerformed; - if (cfg.MiddleClickAction.action != null) - cfg.MiddleClickAction.action.performed += OnMiddleClickPerformed; + if (_middleClickAction.action != null) + _middleClickAction.action.performed += OnMiddleClickPerformed; - if (cfg.RightClickAction.action != null) - cfg.RightClickAction.action.performed += OnRightClickPerformed; + if (_rightClickAction.action != null) + _rightClickAction.action.performed += OnRightClickPerformed; - if (cfg.ScrollWheelAction.action != null) - cfg.ScrollWheelAction.action.performed += OnScrollWheelPerformed; + if (_scrollWheelAction.action != null) + _scrollWheelAction.action.performed += OnScrollWheelPerformed; // When adding new one's don't forget to add them to UnregisterActions - cfg.InputActionAsset.Enable(); + _inputActionAsset.Enable(); } private void UnregisterActions(Configuration cfg) { - if (cfg.PointAction.action != null) - cfg.PointAction.action.performed -= OnPointerPerformed; + if (_pointAction.action != null) + _pointAction.action.performed -= OnPointerPerformed; - if (cfg.MoveAction.action != null) - cfg.MoveAction.action.performed -= OnMovePerformed; + if (_moveAction.action != null) + _moveAction.action.performed -= OnMovePerformed; - if (cfg.SubmitAction.action != null) - cfg.SubmitAction.action.performed -= OnSubmitPerformed; - - if (cfg.CancelAction.action != null) - cfg.CancelAction.action.performed -= OnCancelPerformed; + if (_submitAction.action != null) + _submitAction.action.performed -= OnSubmitPerformed; - if (cfg.LeftClickAction.action != null) - cfg.LeftClickAction.action.performed -= OnLeftClickPerformed; + if (_cancelAction.action != null) + _cancelAction.action.performed -= OnCancelPerformed; - if (cfg.MiddleClickAction.action != null) - cfg.MiddleClickAction.action.performed -= OnMiddleClickPerformed; + if (_leftClickAction.action != null) + _leftClickAction.action.performed -= OnLeftClickPerformed; - if (cfg.RightClickAction.action != null) - cfg.RightClickAction.action.performed -= OnRightClickPerformed; + if (_middleClickAction.action != null) + _middleClickAction.action.performed -= OnMiddleClickPerformed; - if (cfg.ScrollWheelAction.action != null) - cfg.ScrollWheelAction.action.performed -= OnScrollWheelPerformed; + if (_rightClickAction.action != null) + _rightClickAction.action.performed -= OnRightClickPerformed; - cfg.InputActionAsset.Disable(); + if (_scrollWheelAction.action != null) + _scrollWheelAction.action.performed -= OnScrollWheelPerformed; + + _pointAction = null; + _moveAction = null; + _submitAction = null; + _cancelAction = null; + _leftClickAction = null; + _middleClickAction = null; + _rightClickAction = null; + _scrollWheelAction = null; + + _inputActionAsset.Disable(); + UnityEngine.Object.Destroy(_inputActionAsset); // TODO check if this is ok } public struct Configuration { - public InputActionAsset InputActionAsset; - public InputActionReference PointAction; - public InputActionReference MoveAction; - public InputActionReference SubmitAction; - public InputActionReference CancelAction; - public InputActionReference LeftClickAction; - public InputActionReference MiddleClickAction; - public InputActionReference RightClickAction; - public InputActionReference ScrollWheelAction; - //public InputActionReference TrackedDevicePositionAction; - //public InputActionReference TrackedDeviceOrientationAction; + public string InputActionAssetAsJson; + public string PointAction; + public string MoveAction; + public string SubmitAction; + public string CancelAction; + public string LeftClickAction; + public string MiddleClickAction; + public string RightClickAction; + public string ScrollWheelAction; + //public string TrackedDevicePositionAction; + //public string TrackedDeviceOrientationAction; // public float InputActionsPerSecond; // public float RepeatDelay; - public IEnumerable InputActionReferences() - { - yield return PointAction; - } - public static Configuration GetDefaultConfiguration() { - // TODO doesn't work in player builds - //var asset = (InputActionAsset)AssetDatabase.LoadAssetAtPath("Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/DefaultInputActions.inputactions", typeof(InputActionAsset)); - var asset = new DefaultInputActions().asset; + // TODO this is a weird way of doing that, is there an easier way? + var asset = new DefaultInputActions(); + var json = asset.asset.ToJson(); + UnityEngine.Object.DestroyImmediate(asset.asset); // TODO just Dispose doesn't work in edit mode + // asset.Dispose(); return new Configuration { - InputActionAsset = asset, - PointAction = InputActionReference.Create(asset.FindAction("UI/Point")), - MoveAction = InputActionReference.Create(asset.FindAction("UI/Navigate")), - SubmitAction = InputActionReference.Create(asset.FindAction("UI/Submit")), - CancelAction = InputActionReference.Create(asset.FindAction("UI/Cancel")), - LeftClickAction = InputActionReference.Create(asset.FindAction("UI/Click")), - MiddleClickAction = InputActionReference.Create(asset.FindAction("UI/MiddleClick")), - RightClickAction = InputActionReference.Create(asset.FindAction("UI/RightClick")), - ScrollWheelAction = InputActionReference.Create(asset.FindAction("UI/ScrollWheel")), + InputActionAssetAsJson = json, + PointAction = "UI/Point", + MoveAction = "UI/Navigate", + SubmitAction = "UI/Submit", + CancelAction = "UI/Cancel", + LeftClickAction = "UI/Click", + MiddleClickAction = "UI/MiddleClick", + RightClickAction = "UI/RightClick", + ScrollWheelAction = "UI/ScrollWheel", // InputActionsPerSecond = 10, // RepeatDelay = 0.5f, }; From 0bf9bc2571eb478e5d1ca9bebbef65fa7a597574 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Wed, 22 Mar 2023 14:26:33 +0100 Subject: [PATCH 06/31] wip --- .../Plugins/InputForUI/InputSystemProvider.cs | 99 +++++++++++++++---- 1 file changed, 81 insertions(+), 18 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 4986ac784c..52d0a95745 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Unity.IntegerTime; using UnityEngine; @@ -32,6 +33,10 @@ internal class InputSystemProvider : IEventProviderImpl private InputActionReference _scrollWheelAction; private List _events = new List(); + + private PointerState _mouseState; + private PointerState _penState; + private PointerState _touchState; static InputSystemProvider() { @@ -99,6 +104,34 @@ public bool RequestCurrentState(Event.Type type) public uint playerCount => 1; // TODO + private EventSource GetEventSourceForCallback(InputAction.CallbackContext ctx) + { + var device = ctx.control.device; + + if (device is Touchscreen) + return EventSource.Touch; + if (device is Pen) + return EventSource.Pen; + if (device is Mouse) + return EventSource.Mouse; + if (device is Keyboard) + return EventSource.Keyboard; + return EventSource.Unspecified; + } + + private ref PointerState GetPointerStateForSource(EventSource eventSource) + { + switch (eventSource) + { + case EventSource.Touch: + return ref _touchState; + case EventSource.Pen: + return ref _penState; + default: + return ref _mouseState; + } + } + private void DispatchFromCallback(in Event ev) { _events.Add(ev); @@ -106,29 +139,31 @@ private void DispatchFromCallback(in Event ev) private void OnPointerPerformed(InputAction.CallbackContext ctx) { - // Debug.Log($"Pointer performed {ctx.control.name}"); + var eventSource = GetEventSourceForCallback(ctx); + ref var pointerState = ref GetPointerStateForSource(eventSource); var position = ctx.ReadValue(); - var delta = Vector2.zero; - var targetDisplay = 0; + var targetDisplay = 0; // TODO + var delta = pointerState.LastPositionValid ? position - pointerState.LastPosition : Vector2.zero; + pointerState.OnMove(_currentTime, position, targetDisplay); DispatchFromCallback(Event.From(new PointerEvent { type = PointerEvent.Type.PointerMoved, - pointerIndex = 0, + pointerIndex = 0, // TODO position = position, deltaPosition = delta, scroll = Vector2.zero, displayIndex = targetDisplay, - tilt = Vector2.zero, - twist = 0.0f, - pressure = 0.0f, - isInverted = false, + tilt = Vector2.zero, // TODO + twist = 0.0f, // TODO + pressure = 0.0f, // TODO + isInverted = false, // TODO button = 0, - //buttonsState = _mouseState.ButtonsState, + buttonsState = pointerState.ButtonsState, clickCount = 0, timestamp = _currentTime, - eventSource = EventSource.Mouse, + eventSource = eventSource, playerId = kDefaultPlayerId, eventModifiers = _eventModifiers })); @@ -180,9 +215,38 @@ private void OnCancelPerformed(InputAction.CallbackContext ctx) eventModifiers = _eventModifiers })); } - - private void OnLeftClickPerformed(InputAction.CallbackContext ctx) + + private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) { + ref var state = ref GetPointerStateForSource(eventSource); + + var wasPressed = state.ButtonsState.Get(button); + var isPressed = ctx.ReadValueAsButton(); + state.OnButtonChange(_currentTime, button, wasPressed, isPressed); + + // TODO ignore events and reset state based on order (touch->pen->mouse) + // TODO figure out pointer index for touch + + DispatchFromCallback(Event.From(new PointerEvent + { + type = isPressed ? PointerEvent.Type.ButtonPressed : PointerEvent.Type.ButtonReleased, + pointerIndex = 0, // TODO + position = state.LastPosition, + deltaPosition = Vector2.zero, + scroll = Vector2.zero, + displayIndex = state.LastDisplayIndex, + tilt = Vector2.zero, + twist = 0.0f, + pressure = 0.0f, + isInverted = false, + button = button, + buttonsState = state.ButtonsState, + clickCount = state.ClickCount, + timestamp = _currentTime, + eventSource = eventSource, + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); // var index = GetPointerStateIndexFor(ref context); // if (index == -1) @@ -198,15 +262,14 @@ private void OnLeftClickPerformed(InputAction.CallbackContext ctx) // state.eventData.displayIndex = GetDisplayIndexFor(context.control); // #endif // - } - private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) - { } - private void OnRightClickPerformed(InputAction.CallbackContext ctx) - { - } + private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); + + private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseMiddle); + + private void OnRightClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseRight); private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) { From 09295ea89feb225b958885b1c24b3ff5d85ab0a9 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Wed, 22 Mar 2023 15:28:12 +0100 Subject: [PATCH 07/31] wip --- .../Plugins/InputForUI/InputSystemProvider.cs | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 52d0a95745..58f6ac8200 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -4,6 +4,7 @@ using UnityEngine; using UnityEngine.InputForUI; using UnityEngine.InputSystem; +using UnityEngine.InputSystem.Controls; using Event = UnityEngine.InputForUI.Event; using EventModifiers = UnityEngine.InputForUI.EventModifiers; using EventProvider = UnityEngine.InputForUI.EventProvider; @@ -142,23 +143,31 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) var eventSource = GetEventSourceForCallback(ctx); ref var pointerState = ref GetPointerStateForSource(eventSource); + // Overall I'm not happy how leaky this is, we're using input actions to have flexibility to bind to different controls, + // but instead we just kinda abuse it to bind to different devices ... + var asPointerDevice = ctx.control.device is Pointer ? (Pointer)ctx.control.device : null; + var asPenDevice = ctx.control.device is Pen ? (Pen)ctx.control.device : null; + var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; + var position = ctx.ReadValue(); - var targetDisplay = 0; // TODO + var targetDisplay = asPointerDevice != null ? asPointerDevice.displayIndex.ReadValue() : 0; var delta = pointerState.LastPositionValid ? position - pointerState.LastPosition : Vector2.zero; pointerState.OnMove(_currentTime, position, targetDisplay); + // TODO ignore events and reset state based on order (touch->pen->mouse) + DispatchFromCallback(Event.From(new PointerEvent { type = PointerEvent.Type.PointerMoved, - pointerIndex = 0, // TODO + pointerIndex = asTouchControl != null ? asTouchControl.touchId.ReadValue() : 0, position = position, deltaPosition = delta, scroll = Vector2.zero, displayIndex = targetDisplay, - tilt = Vector2.zero, // TODO - twist = 0.0f, // TODO - pressure = 0.0f, // TODO - isInverted = false, // TODO + tilt = asPenDevice != null ? asPenDevice.tilt.ReadValue() : Vector2.zero, + twist = asPenDevice != null ? asPenDevice.twist.ReadValue() : 0.0f, + pressure = asPenDevice != null ? asPenDevice.pressure.ReadValue() : (asTouchControl != null ? asTouchControl.pressure.ReadValue() : 0.0f), + isInverted = asPenDevice != null ? asPenDevice.eraser.isPressed : false, // TODO any way to detect that pen is inverted but not touching? button = 0, buttonsState = pointerState.ButtonsState, clickCount = 0, @@ -247,22 +256,6 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event playerId = kDefaultPlayerId, eventModifiers = _eventModifiers })); - -// var index = GetPointerStateIndexFor(ref context); -// if (index == -1) -// return; -// -// ref var state = ref GetPointerStateForIndex(index); -// bool wasPressed = state.leftButton.isPressed; -// state.leftButton.isPressed = context.ReadValueAsButton(); -// state.changedThisFrame = true; -// if (IgnoreNextClick(ref context, wasPressed)) -// state.leftButton.ignoreNextClick = true; -// #if UNITY_2023_1_OR_NEWER -// state.eventData.displayIndex = GetDisplayIndexFor(context.control); -// #endif -// - } private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); From ee1978a7a0e79827eaace230305730abd1b7b791 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Tue, 28 Mar 2023 12:38:14 +0200 Subject: [PATCH 08/31] sorting of events and filtering of pointer events --- .../Plugins/InputForUI/InputSystemProvider.cs | 170 ++++++++++++------ 1 file changed, 114 insertions(+), 56 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 58f6ac8200..fc626615e7 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -34,10 +34,17 @@ internal class InputSystemProvider : IEventProviderImpl private InputActionReference _scrollWheelAction; private List _events = new List(); - + private PointerState _mouseState; + private bool _seenMouseEvents; + private PointerState _penState; + private bool _seenPenEvents; + private PointerState _touchState; + private bool _seenTouchEvents; + + private const float kSmallestReportedMovementSqrDist = 0.01f; static InputSystemProvider() { @@ -79,12 +86,29 @@ public void Shutdown() public void Update() { _inputEventPartialProvider.Update(); + + _events.Sort(SortEvents); + + foreach (var ev in _events) + { + // we need to ignore some pointer events based on priority (touch->pen->mouse) + // this is mostly used to filter out simulated input, e.g. when pen is active it also generates mouse input + if (_seenTouchEvents && ev.type == Event.Type.PointerEvent && ev.eventSource == EventSource.Pen) + _penState.Reset(); + else if ((_seenTouchEvents || _seenPenEvents) && ev.type == Event.Type.PointerEvent && (ev.eventSource == EventSource.Mouse || ev.eventSource == EventSource.Unspecified)) + _mouseState.Reset(); + else + EventProvider.Dispatch(ev); + } - foreach (var ev in _events) // TODO sort them - EventProvider.Dispatch(ev); _events.Clear(); } + private static int SortEvents(Event a, Event b) + { + return Event.Compare(a, b); + } + public void OnFocusChanged(bool focus) { _inputEventPartialProvider.OnFocusChanged(focus); @@ -105,6 +129,17 @@ public bool RequestCurrentState(Event.Type type) public uint playerCount => 1; // TODO + // copied from UIElementsRuntimeUtility.cs + private static Vector2 ScreenBottomLeftToPanelPosition(Vector2 position, int targetDisplay) + { + // Flip positions Y axis between input and UITK + var screenHeight = Screen.height; + if (targetDisplay > 0 && targetDisplay < Display.displays.Length) + screenHeight = Display.displays[targetDisplay].systemHeight; + position.y = screenHeight - position.y; + return position; + } + private EventSource GetEventSourceForCallback(InputAction.CallbackContext ctx) { var device = ctx.control.device; @@ -142,40 +177,63 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) { var eventSource = GetEventSourceForCallback(ctx); ref var pointerState = ref GetPointerStateForSource(eventSource); - + // Overall I'm not happy how leaky this is, we're using input actions to have flexibility to bind to different controls, // but instead we just kinda abuse it to bind to different devices ... var asPointerDevice = ctx.control.device is Pointer ? (Pointer)ctx.control.device : null; var asPenDevice = ctx.control.device is Pen ? (Pen)ctx.control.device : null; + var asTouchscreenDevice = ctx.control.device is Touchscreen ? (Touchscreen)ctx.control.device : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; - var position = ctx.ReadValue(); - var targetDisplay = asPointerDevice != null ? asPointerDevice.displayIndex.ReadValue() : 0; + if (asTouchControl != null) + _seenTouchEvents = true; + else if (asPenDevice != null) + _seenPenEvents = true; + else + _seenMouseEvents = true; + + var positionISX = ctx.ReadValue(); + var targetDisplay = asPointerDevice != null ? asPointerDevice.displayIndex.ReadValue() : (asTouchscreenDevice != null ? asTouchscreenDevice.displayIndex.ReadValue() : 0); + var position = ScreenBottomLeftToPanelPosition(positionISX, targetDisplay); var delta = pointerState.LastPositionValid ? position - pointerState.LastPosition : Vector2.zero; - pointerState.OnMove(_currentTime, position, targetDisplay); - // TODO ignore events and reset state based on order (touch->pen->mouse) + var tilt = asPenDevice != null ? asPenDevice.tilt.ReadValue() : Vector2.zero; + var twist = asPenDevice != null ? asPenDevice.twist.ReadValue() : 0.0f; + var pressure = asPenDevice != null + ? asPenDevice.pressure.ReadValue() + : (asTouchControl != null ? asTouchControl.pressure.ReadValue() : 0.0f); + var isInverted = asPenDevice != null + ? asPenDevice.eraser.isPressed + : false; // TODO any way to detect that pen is inverted but not touching? - DispatchFromCallback(Event.From(new PointerEvent + if (delta.sqrMagnitude >= kSmallestReportedMovementSqrDist) { - type = PointerEvent.Type.PointerMoved, - pointerIndex = asTouchControl != null ? asTouchControl.touchId.ReadValue() : 0, - position = position, - deltaPosition = delta, - scroll = Vector2.zero, - displayIndex = targetDisplay, - tilt = asPenDevice != null ? asPenDevice.tilt.ReadValue() : Vector2.zero, - twist = asPenDevice != null ? asPenDevice.twist.ReadValue() : 0.0f, - pressure = asPenDevice != null ? asPenDevice.pressure.ReadValue() : (asTouchControl != null ? asTouchControl.pressure.ReadValue() : 0.0f), - isInverted = asPenDevice != null ? asPenDevice.eraser.isPressed : false, // TODO any way to detect that pen is inverted but not touching? - button = 0, - buttonsState = pointerState.ButtonsState, - clickCount = 0, - timestamp = _currentTime, - eventSource = eventSource, - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers - })); + DispatchFromCallback(Event.From(new PointerEvent + { + type = PointerEvent.Type.PointerMoved, + pointerIndex = asTouchControl != null ? asTouchControl.touchId.ReadValue() : 0, + position = position, + deltaPosition = delta, + scroll = Vector2.zero, + displayIndex = targetDisplay, + tilt = tilt, + twist = twist, + pressure = pressure, + isInverted = isInverted, + button = 0, + buttonsState = pointerState.ButtonsState, + clickCount = 0, + timestamp = _currentTime, + eventSource = eventSource, + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); + + // only record if we send an event + pointerState.OnMove(_currentTime, position, targetDisplay); + } + else if(!pointerState.LastPositionValid) + pointerState.OnMove(_currentTime, position, targetDisplay); } private void OnMovePerformed(InputAction.CallbackContext ctx) @@ -227,35 +285,35 @@ private void OnCancelPerformed(InputAction.CallbackContext ctx) private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) { - ref var state = ref GetPointerStateForSource(eventSource); - - var wasPressed = state.ButtonsState.Get(button); - var isPressed = ctx.ReadValueAsButton(); - state.OnButtonChange(_currentTime, button, wasPressed, isPressed); - - // TODO ignore events and reset state based on order (touch->pen->mouse) - // TODO figure out pointer index for touch - - DispatchFromCallback(Event.From(new PointerEvent - { - type = isPressed ? PointerEvent.Type.ButtonPressed : PointerEvent.Type.ButtonReleased, - pointerIndex = 0, // TODO - position = state.LastPosition, - deltaPosition = Vector2.zero, - scroll = Vector2.zero, - displayIndex = state.LastDisplayIndex, - tilt = Vector2.zero, - twist = 0.0f, - pressure = 0.0f, - isInverted = false, - button = button, - buttonsState = state.ButtonsState, - clickCount = state.ClickCount, - timestamp = _currentTime, - eventSource = eventSource, - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers - })); + // ref var state = ref GetPointerStateForSource(eventSource); + // + // var wasPressed = state.ButtonsState.Get(button); + // var isPressed = ctx.ReadValueAsButton(); + // state.OnButtonChange(_currentTime, button, wasPressed, isPressed); + // + // // TODO ignore events and reset state based on order (touch->pen->mouse) + // // TODO figure out pointer index for touch + // + // DispatchFromCallback(Event.From(new PointerEvent + // { + // type = isPressed ? PointerEvent.Type.ButtonPressed : PointerEvent.Type.ButtonReleased, + // pointerIndex = 0, // TODO + // position = state.LastPosition, + // deltaPosition = Vector2.zero, + // scroll = Vector2.zero, + // displayIndex = state.LastDisplayIndex, + // tilt = Vector2.zero, + // twist = 0.0f, + // pressure = 0.0f, + // isInverted = false, + // button = button, + // buttonsState = state.ButtonsState, + // clickCount = state.ClickCount, + // timestamp = _currentTime, + // eventSource = eventSource, + // playerId = kDefaultPlayerId, + // eventModifiers = _eventModifiers + // })); } private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); From 19e79e2c80f14a32265781791e0c4661d7e56729 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Tue, 28 Mar 2023 17:04:42 +0200 Subject: [PATCH 09/31] pointer indices --- .../Plugins/InputForUI/InputSystemProvider.cs | 177 +++++++++++++++--- 1 file changed, 148 insertions(+), 29 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index fc626615e7..a6262e03bc 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -41,6 +41,9 @@ internal class InputSystemProvider : IEventProviderImpl private PointerState _penState; private bool _seenPenEvents; + private Dictionary _touchFingerIdToFingerIndex = new(); + private int _touchNextFingerIndex; + private int _aliveTouchesCount; private PointerState _touchState; private bool _seenTouchEvents; @@ -70,6 +73,20 @@ public void Initialize() _inputEventPartialProvider ??= new InputEventPartialProvider(); _inputEventPartialProvider.Initialize(); + _events.Clear(); + + _mouseState.Reset(); + _seenMouseEvents = false; + + _penState.Reset(); + _seenPenEvents = false; + + _touchFingerIdToFingerIndex.Clear(); + _touchNextFingerIndex = 0; + _aliveTouchesCount = 0; + _touchState.Reset(); + _seenTouchEvents = false; + // TODO should UITK somehow override this? _cfg = Configuration.GetDefaultConfiguration(); RegisterActions(_cfg); @@ -102,6 +119,16 @@ public void Update() } _events.Clear(); + + // it's very difficult to calculate is all touches are released to reset the counter + // so we proactively guarding for worst cases when either we get more cancellations then we expect, + // or something gets stuck and alive touches get increment beyond any reasonable values + if (_aliveTouchesCount <= 0 || _aliveTouchesCount >= 16) // safety guard + { + _touchNextFingerIndex = 0; + _aliveTouchesCount = 0; + _touchFingerIdToFingerIndex.Clear(); + } } private static int SortEvents(Event a, Event b) @@ -121,7 +148,27 @@ public bool RequestCurrentState(Event.Type type) switch (type) { + case Event.Type.PointerEvent: + { + if (_touchState.LastPositionValid) + EventProvider.Dispatch(Event.From(ToPointerStateEvent(_currentTime, _touchState, EventSource.Touch))); + if (_penState.LastPositionValid) + EventProvider.Dispatch(Event.From(ToPointerStateEvent(_currentTime, _penState, EventSource.Pen))); + if (_mouseState.LastPositionValid) + EventProvider.Dispatch(Event.From(ToPointerStateEvent(_currentTime, _mouseState, EventSource.Mouse))); + else + { + // TODO maybe it's reasonable to poll and dispatch mouse state here anyway? + } + + return _touchState.LastPositionValid || + _penState.LastPositionValid || + _mouseState.LastPositionValid; + } // TODO + case Event.Type.IMECompositionEvent: + //EventProvider.Dispatch(Event.From(ToIMECompositionEvent(currentTime, _compositionString))); + //return true; default: return false; } @@ -140,6 +187,31 @@ private static Vector2 ScreenBottomLeftToPanelPosition(Vector2 position, int tar return position; } + private PointerEvent ToPointerStateEvent(DiscreteTime currentTime, in PointerState state, EventSource eventSource) + { + return new PointerEvent + { + type = PointerEvent.Type.State, + pointerIndex = 0, + position = state.LastPosition, + deltaPosition = Vector2.zero, + scroll = Vector2.zero, + displayIndex = state.LastDisplayIndex, + // TODO + // tilt = eventSource == EventSource.Pen ? _lastPenData.tilt : Vector2.zero, + // twist = eventSource == EventSource.Pen ? _lastPenData.twist : 0.0f, + // pressure = eventSource == EventSource.Pen ? _lastPenData.pressure : 0.0f, + // isInverted = eventSource == EventSource.Pen && ((_lastPenData.penStatus & PenStatus.Inverted) != 0), + button = 0, + buttonsState = state.ButtonsState, + clickCount = 0, + timestamp = currentTime, + eventSource = eventSource, + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + }; + } + private EventSource GetEventSourceForCallback(InputAction.CallbackContext ctx) { var device = ctx.control.device; @@ -285,42 +357,71 @@ private void OnCancelPerformed(InputAction.CallbackContext ctx) private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) { - // ref var state = ref GetPointerStateForSource(eventSource); - // - // var wasPressed = state.ButtonsState.Get(button); - // var isPressed = ctx.ReadValueAsButton(); - // state.OnButtonChange(_currentTime, button, wasPressed, isPressed); - // - // // TODO ignore events and reset state based on order (touch->pen->mouse) - // // TODO figure out pointer index for touch - // - // DispatchFromCallback(Event.From(new PointerEvent - // { - // type = isPressed ? PointerEvent.Type.ButtonPressed : PointerEvent.Type.ButtonReleased, - // pointerIndex = 0, // TODO - // position = state.LastPosition, - // deltaPosition = Vector2.zero, - // scroll = Vector2.zero, - // displayIndex = state.LastDisplayIndex, - // tilt = Vector2.zero, - // twist = 0.0f, - // pressure = 0.0f, - // isInverted = false, - // button = button, - // buttonsState = state.ButtonsState, - // clickCount = state.ClickCount, - // timestamp = _currentTime, - // eventSource = eventSource, - // playerId = kDefaultPlayerId, - // eventModifiers = _eventModifiers - // })); + ref var state = ref GetPointerStateForSource(eventSource); + + var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; + var touchId = asTouchControl != null ? asTouchControl.touchId.ReadValue() : 0; + + var pointerIndex = 0; + if (asTouchControl != null && !_touchFingerIdToFingerIndex.TryGetValue(touchId, out pointerIndex)) + { + pointerIndex = _touchNextFingerIndex++; + _aliveTouchesCount++; + _touchFingerIdToFingerIndex.Add(touchId, pointerIndex); + } + + var wasPressed = state.ButtonsState.Get(button); + var isPressed = ctx.ReadValueAsButton(); + state.OnButtonChange(_currentTime, button, wasPressed, isPressed); + + if (asTouchControl != null && wasPressed && !isPressed) + _aliveTouchesCount--; + + DispatchFromCallback(Event.From(new PointerEvent + { + type = isPressed ? PointerEvent.Type.ButtonPressed : PointerEvent.Type.ButtonReleased, + pointerIndex = pointerIndex, + position = state.LastPosition, + deltaPosition = Vector2.zero, + scroll = Vector2.zero, + displayIndex = state.LastDisplayIndex, + tilt = Vector2.zero, + twist = 0.0f, + pressure = 0.0f, + isInverted = false, + button = button, + buttonsState = state.ButtonsState, + clickCount = state.ClickCount, + timestamp = _currentTime, + eventSource = eventSource, + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); + } + + private void OnClickCancelled(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) + { + ref var state = ref GetPointerStateForSource(eventSource); + + var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; + var touchId = asTouchControl != null ? asTouchControl.touchId.ReadValue() : 0; + + var wasPressed = state.ButtonsState.Get(button); + var isPressed = ctx.ReadValueAsButton(); + + if (asTouchControl != null && wasPressed && !isPressed && _touchFingerIdToFingerIndex.ContainsKey(touchId)) + _aliveTouchesCount--; } private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); + + private void OnLeftClickCancelled(InputAction.CallbackContext ctx) => OnClickCancelled(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseMiddle); + private void OnMiddleClickCancelled(InputAction.CallbackContext ctx) => OnClickCancelled(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); private void OnRightClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseRight); + private void OnRightClickCancelled(InputAction.CallbackContext ctx) => OnClickCancelled(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) { @@ -378,13 +479,22 @@ private void RegisterActions(Configuration cfg) _cancelAction.action.performed += OnCancelPerformed; if (_leftClickAction.action != null) + { _leftClickAction.action.performed += OnLeftClickPerformed; + _leftClickAction.action.canceled += OnLeftClickCancelled; + } if (_middleClickAction.action != null) + { _middleClickAction.action.performed += OnMiddleClickPerformed; + _middleClickAction.action.canceled += OnMiddleClickCancelled; + } if (_rightClickAction.action != null) + { _rightClickAction.action.performed += OnRightClickPerformed; + _rightClickAction.action.canceled += OnRightClickCancelled; + } if (_scrollWheelAction.action != null) _scrollWheelAction.action.performed += OnScrollWheelPerformed; @@ -409,13 +519,22 @@ private void UnregisterActions(Configuration cfg) _cancelAction.action.performed -= OnCancelPerformed; if (_leftClickAction.action != null) + { _leftClickAction.action.performed -= OnLeftClickPerformed; + _leftClickAction.action.canceled -= OnLeftClickCancelled; + } if (_middleClickAction.action != null) + { _middleClickAction.action.performed -= OnMiddleClickPerformed; + _middleClickAction.action.canceled -= OnMiddleClickCancelled; + } if (_rightClickAction.action != null) + { _rightClickAction.action.performed -= OnRightClickPerformed; + _rightClickAction.action.canceled -= OnRightClickCancelled; + } if (_scrollWheelAction.action != null) _scrollWheelAction.action.performed -= OnScrollWheelPerformed; From 404840cf2b4a8f8ee833ee5e5da68e7173b9cdba Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Tue, 28 Mar 2023 18:15:13 +0200 Subject: [PATCH 10/31] more robust scroll events --- .../Plugins/InputForUI/InputSystemProvider.cs | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index a6262e03bc..824313f705 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -425,26 +425,46 @@ private void OnClickCancelled(InputAction.CallbackContext ctx, EventSource event private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) { - // TODO + var scrollDelta = ctx.ReadValue(); + if (scrollDelta.sqrMagnitude < kSmallestReportedMovementSqrDist) + return; + + var eventSource = GetEventSourceForCallback(ctx); + ref var state = ref GetPointerStateForSource(eventSource); + var position = Vector2.zero; - var delta = Vector2.zero; - var scroll = ctx.ReadValue(); var targetDisplay = 0; + if (state.LastPositionValid) + { + position = state.LastPosition; + targetDisplay = state.LastDisplayIndex; + } + else if (eventSource == EventSource.Mouse && Mouse.current != null) + { + position = Mouse.current.position.ReadValue(); + targetDisplay = Mouse.current.displayIndex.ReadValue(); + } + + // Make it look similar to IMGUI event scroll values. + // TODO check how it behaves on macOS + scrollDelta.x /= 40.0f; + scrollDelta.y /= -40.0f; + DispatchFromCallback(Event.From(new PointerEvent { type = PointerEvent.Type.Scroll, pointerIndex = 0, position = position, - deltaPosition = delta, - scroll = scroll, + deltaPosition = Vector2.zero, + scroll = scrollDelta, displayIndex = targetDisplay, tilt = Vector2.zero, twist = 0.0f, pressure = 0.0f, isInverted = false, button = 0, - //buttonsState = _mouseState.ButtonsState, + buttonsState = state.ButtonsState, clickCount = 0, timestamp = _currentTime, eventSource = EventSource.Mouse, From dde508e591f3fb7399380c755477bc26858c437e Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Wed, 29 Mar 2023 11:28:57 +0200 Subject: [PATCH 11/31] forgot to reset state flags --- .../InputSystem/Plugins/InputForUI/InputSystemProvider.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 824313f705..ba780fccce 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -129,6 +129,10 @@ public void Update() _aliveTouchesCount = 0; _touchFingerIdToFingerIndex.Clear(); } + + _seenTouchEvents = false; + _seenPenEvents = false; + _seenMouseEvents = false; } private static int SortEvents(Event a, Event b) From cebfb548bed2161c970b6e9b5acfc37102744159 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Wed, 29 Mar 2023 15:29:29 +0200 Subject: [PATCH 12/31] trying out to use touchscreen for finger index --- .../Plugins/InputForUI/InputSystemProvider.cs | 55 ++++++------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index ba780fccce..1da75805aa 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -41,9 +41,6 @@ internal class InputSystemProvider : IEventProviderImpl private PointerState _penState; private bool _seenPenEvents; - private Dictionary _touchFingerIdToFingerIndex = new(); - private int _touchNextFingerIndex; - private int _aliveTouchesCount; private PointerState _touchState; private bool _seenTouchEvents; @@ -81,9 +78,6 @@ public void Initialize() _penState.Reset(); _seenPenEvents = false; - _touchFingerIdToFingerIndex.Clear(); - _touchNextFingerIndex = 0; - _aliveTouchesCount = 0; _touchState.Reset(); _seenTouchEvents = false; @@ -119,16 +113,6 @@ public void Update() } _events.Clear(); - - // it's very difficult to calculate is all touches are released to reset the counter - // so we proactively guarding for worst cases when either we get more cancellations then we expect, - // or something gets stuck and alive touches get increment beyond any reasonable values - if (_aliveTouchesCount <= 0 || _aliveTouchesCount >= 16) // safety guard - { - _touchNextFingerIndex = 0; - _aliveTouchesCount = 0; - _touchFingerIdToFingerIndex.Clear(); - } _seenTouchEvents = false; _seenPenEvents = false; @@ -260,6 +244,7 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) var asPenDevice = ctx.control.device is Pen ? (Pen)ctx.control.device : null; var asTouchscreenDevice = ctx.control.device is Touchscreen ? (Touchscreen)ctx.control.device : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; + var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); if (asTouchControl != null) _seenTouchEvents = true; @@ -287,7 +272,7 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) DispatchFromCallback(Event.From(new PointerEvent { type = PointerEvent.Type.PointerMoved, - pointerIndex = asTouchControl != null ? asTouchControl.touchId.ReadValue() : 0, + pointerIndex = pointerIndex, position = position, deltaPosition = delta, scroll = Vector2.zero, @@ -359,28 +344,30 @@ private void OnCancelPerformed(InputAction.CallbackContext ctx) })); } + private int FindPointerIndex(Touchscreen touchscreen, TouchControl touchControl) + { + if (touchscreen == null || touchControl == null) + return 0; + + for (var i = 0; i < touchscreen.touches.Count; ++i) + if (touchscreen.touches[i] == touchControl) + return i; + + return 0; + } + private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) { ref var state = ref GetPointerStateForSource(eventSource); + var asTouchscreenDevice = ctx.control.device is Touchscreen ? (Touchscreen)ctx.control.device : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; - var touchId = asTouchControl != null ? asTouchControl.touchId.ReadValue() : 0; - - var pointerIndex = 0; - if (asTouchControl != null && !_touchFingerIdToFingerIndex.TryGetValue(touchId, out pointerIndex)) - { - pointerIndex = _touchNextFingerIndex++; - _aliveTouchesCount++; - _touchFingerIdToFingerIndex.Add(touchId, pointerIndex); - } + var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); var wasPressed = state.ButtonsState.Get(button); var isPressed = ctx.ReadValueAsButton(); state.OnButtonChange(_currentTime, button, wasPressed, isPressed); - if (asTouchControl != null && wasPressed && !isPressed) - _aliveTouchesCount--; - DispatchFromCallback(Event.From(new PointerEvent { type = isPressed ? PointerEvent.Type.ButtonPressed : PointerEvent.Type.ButtonReleased, @@ -405,16 +392,6 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event private void OnClickCancelled(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) { - ref var state = ref GetPointerStateForSource(eventSource); - - var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; - var touchId = asTouchControl != null ? asTouchControl.touchId.ReadValue() : 0; - - var wasPressed = state.ButtonsState.Get(button); - var isPressed = ctx.ReadValueAsButton(); - - if (asTouchControl != null && wasPressed && !isPressed && _touchFingerIdToFingerIndex.ContainsKey(touchId)) - _aliveTouchesCount--; } private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); From a949f6b9eb2021a60fea96616d248e43833dccb9 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Wed, 29 Mar 2023 15:45:18 +0200 Subject: [PATCH 13/31] removing leftovers --- .../Plugins/InputForUI/InputSystemProvider.cs | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 1da75805aa..8475e816a1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -390,19 +390,9 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event })); } - private void OnClickCancelled(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) - { - } - private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); - - private void OnLeftClickCancelled(InputAction.CallbackContext ctx) => OnClickCancelled(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); - private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseMiddle); - private void OnMiddleClickCancelled(InputAction.CallbackContext ctx) => OnClickCancelled(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); - private void OnRightClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseRight); - private void OnRightClickCancelled(InputAction.CallbackContext ctx) => OnClickCancelled(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) { @@ -480,22 +470,13 @@ private void RegisterActions(Configuration cfg) _cancelAction.action.performed += OnCancelPerformed; if (_leftClickAction.action != null) - { _leftClickAction.action.performed += OnLeftClickPerformed; - _leftClickAction.action.canceled += OnLeftClickCancelled; - } if (_middleClickAction.action != null) - { _middleClickAction.action.performed += OnMiddleClickPerformed; - _middleClickAction.action.canceled += OnMiddleClickCancelled; - } if (_rightClickAction.action != null) - { _rightClickAction.action.performed += OnRightClickPerformed; - _rightClickAction.action.canceled += OnRightClickCancelled; - } if (_scrollWheelAction.action != null) _scrollWheelAction.action.performed += OnScrollWheelPerformed; @@ -520,22 +501,13 @@ private void UnregisterActions(Configuration cfg) _cancelAction.action.performed -= OnCancelPerformed; if (_leftClickAction.action != null) - { _leftClickAction.action.performed -= OnLeftClickPerformed; - _leftClickAction.action.canceled -= OnLeftClickCancelled; - } if (_middleClickAction.action != null) - { _middleClickAction.action.performed -= OnMiddleClickPerformed; - _middleClickAction.action.canceled -= OnMiddleClickCancelled; - } if (_rightClickAction.action != null) - { _rightClickAction.action.performed -= OnRightClickPerformed; - _rightClickAction.action.canceled -= OnRightClickCancelled; - } if (_scrollWheelAction.action != null) _scrollWheelAction.action.performed -= OnScrollWheelPerformed; From d26e4584028a3530c7d9b21ebf47aa8cabdbdcc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o?= Date: Wed, 5 Apr 2023 17:33:23 +0100 Subject: [PATCH 14/31] Add dispatch of navigation events for InputForUI (#1667) * Add dispatch of navigation events * Fix formatting * Unifies GetEventSource() for callback context and devices * Use DispatchFromCallback and clean todos --- .../Plugins/InputForUI/InputSystemProvider.cs | 187 ++++++++++++------ 1 file changed, 128 insertions(+), 59 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 8475e816a1..492c5ec453 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -33,7 +33,9 @@ internal class InputSystemProvider : IEventProviderImpl private InputActionReference _rightClickAction; private InputActionReference _scrollWheelAction; - private List _events = new List(); + InputAction _nextPreviousAction; + + List _events = new List(); private PointerState _mouseState; private bool _seenMouseEvents; @@ -46,6 +48,8 @@ internal class InputSystemProvider : IEventProviderImpl private const float kSmallestReportedMovementSqrDist = 0.01f; + private NavigationEventRepeatHelper repeatHelper = new(); + static InputSystemProvider() { // TODO check if input system is enabled before doing this @@ -62,30 +66,46 @@ private static void Bootstrap() private EventModifiers _eventModifiers => _inputEventPartialProvider._eventModifiers; private DiscreteTime _currentTime => (DiscreteTime)Time.timeAsRational; - + private const uint kDefaultPlayerId = 0u; public void Initialize() { _inputEventPartialProvider ??= new InputEventPartialProvider(); _inputEventPartialProvider.Initialize(); - + _events.Clear(); - + _mouseState.Reset(); _seenMouseEvents = false; _penState.Reset(); _seenPenEvents = false; - + _touchState.Reset(); _seenTouchEvents = false; - + // TODO should UITK somehow override this? _cfg = Configuration.GetDefaultConfiguration(); RegisterActions(_cfg); } + private void OnNextPreviousPerformed(InputAction.CallbackContext ctx) + { + if (ctx.control.device is Keyboard) + { + //TODO repeat rate + var keyboard = ctx.control.device as Keyboard; + DispatchFromCallback(Event.From(new NavigationEvent + { + type = NavigationEvent.Type.Move, + direction = keyboard.shiftKey.isPressed ? NavigationEvent.Direction.Previous : NavigationEvent.Direction.Next, + timestamp = _currentTime, + eventSource = EventSource.Keyboard, + })); + } + } + public void Shutdown() { UnregisterActions(_cfg); @@ -97,9 +117,13 @@ public void Shutdown() public void Update() { _inputEventPartialProvider.Update(); - + _events.Sort(SortEvents); + var currentTime = (DiscreteTime)Time.timeAsRational; + + DirectionNavigation(currentTime); + foreach (var ev in _events) { // we need to ignore some pointer events based on priority (touch->pen->mouse) @@ -113,12 +137,48 @@ public void Update() } _events.Clear(); - + _seenTouchEvents = false; _seenPenEvents = false; _seenMouseEvents = false; } + private void DirectionNavigation(DiscreteTime currentTime) + { + //TODO: Refactor as there is no need for having almost the same implementation in the IM and ISX? + var(move, axesButtonWerePressed) = ReadCurrentNavigationMoveVector(); + + var direction = NavigationEvent.DetermineMoveDirection(move); + + if (direction == NavigationEvent.Direction.None) + { + repeatHelper.Reset(); + } + else + { + if (repeatHelper.ShouldSendMoveEvent(currentTime, direction, axesButtonWerePressed)) + { + EventProvider.Dispatch(Event.From(new NavigationEvent + { + type = NavigationEvent.Type.Move, + direction = direction, + timestamp = currentTime, + eventSource = GetEventSource(_moveAction.action.activeControl.device), + playerId = kDefaultPlayerId, + eventModifiers = _eventModifiers + })); + } + } + } + + private (Vector2, bool) ReadCurrentNavigationMoveVector() + { + var move = _moveAction.action.ReadValue(); + // Check if the action was "pressed" this frame to deal with repeating events + var axisWasPressed = _moveAction.action.WasPressedThisFrame(); + return (move, axisWasPressed); + } + private static int SortEvents(Event a, Event b) { return Event.Compare(a, b); @@ -150,20 +210,20 @@ public bool RequestCurrentState(Event.Type type) } return _touchState.LastPositionValid || - _penState.LastPositionValid || - _mouseState.LastPositionValid; + _penState.LastPositionValid || + _mouseState.LastPositionValid; } // TODO case Event.Type.IMECompositionEvent: - //EventProvider.Dispatch(Event.From(ToIMECompositionEvent(currentTime, _compositionString))); - //return true; + //EventProvider.Dispatch(Event.From(ToIMECompositionEvent(currentTime, _compositionString))); + //return true; default: return false; } } public uint playerCount => 1; // TODO - + // copied from UIElementsRuntimeUtility.cs private static Vector2 ScreenBottomLeftToPanelPosition(Vector2 position, int targetDisplay) { @@ -174,7 +234,7 @@ private static Vector2 ScreenBottomLeftToPanelPosition(Vector2 position, int tar position.y = screenHeight - position.y; return position; } - + private PointerEvent ToPointerStateEvent(DiscreteTime currentTime, in PointerState state, EventSource eventSource) { return new PointerEvent @@ -199,11 +259,15 @@ private PointerEvent ToPointerStateEvent(DiscreteTime currentTime, in PointerSta eventModifiers = _eventModifiers }; } - - private EventSource GetEventSourceForCallback(InputAction.CallbackContext ctx) + + private EventSource GetEventSource(InputAction.CallbackContext ctx) { var device = ctx.control.device; + return GetEventSource(device); + } + private EventSource GetEventSource(InputDevice device) + { if (device is Touchscreen) return EventSource.Touch; if (device is Pen) @@ -212,6 +276,9 @@ private EventSource GetEventSourceForCallback(InputAction.CallbackContext ctx) return EventSource.Mouse; if (device is Keyboard) return EventSource.Keyboard; + if (device is Gamepad) + return EventSource.Gamepad; + return EventSource.Unspecified; } @@ -227,7 +294,7 @@ private ref PointerState GetPointerStateForSource(EventSource eventSource) return ref _mouseState; } } - + private void DispatchFromCallback(in Event ev) { _events.Add(ev); @@ -235,9 +302,9 @@ private void DispatchFromCallback(in Event ev) private void OnPointerPerformed(InputAction.CallbackContext ctx) { - var eventSource = GetEventSourceForCallback(ctx); + var eventSource = GetEventSource(ctx); ref var pointerState = ref GetPointerStateForSource(eventSource); - + // Overall I'm not happy how leaky this is, we're using input actions to have flexibility to bind to different controls, // but instead we just kinda abuse it to bind to different devices ... var asPointerDevice = ctx.control.device is Pointer ? (Pointer)ctx.control.device : null; @@ -293,38 +360,18 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) // only record if we send an event pointerState.OnMove(_currentTime, position, targetDisplay); } - else if(!pointerState.LastPositionValid) + else if (!pointerState.LastPositionValid) pointerState.OnMove(_currentTime, position, targetDisplay); } - private void OnMovePerformed(InputAction.CallbackContext ctx) - { - var direction = NavigationEvent.DetermineMoveDirection(ctx.ReadValue()); - if (direction == NavigationEvent.Direction.None) - return; - // _navigationEventRepeatHelper.Reset(); - - // TODO repeat rate - DispatchFromCallback(Event.From(new NavigationEvent - { - type = NavigationEvent.Type.Move, - direction = direction, - timestamp = _currentTime, - eventSource = EventSource.Unspecified, // TODO - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers - })); - } - private void OnSubmitPerformed(InputAction.CallbackContext ctx) { - // TODO repeat rate DispatchFromCallback(Event.From(new NavigationEvent { type = NavigationEvent.Type.Submit, direction = NavigationEvent.Direction.None, timestamp = _currentTime, - eventSource = EventSource.Unspecified, // TODO + eventSource = GetEventSource(ctx), playerId = kDefaultPlayerId, eventModifiers = _eventModifiers })); @@ -332,13 +379,12 @@ private void OnSubmitPerformed(InputAction.CallbackContext ctx) private void OnCancelPerformed(InputAction.CallbackContext ctx) { - // TODO repeat rate DispatchFromCallback(Event.From(new NavigationEvent { type = NavigationEvent.Type.Cancel, direction = NavigationEvent.Direction.None, timestamp = _currentTime, - eventSource = EventSource.Unspecified, // TODO + eventSource = GetEventSource(ctx), playerId = kDefaultPlayerId, eventModifiers = _eventModifiers })); @@ -390,9 +436,9 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event })); } - private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseLeft); - private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseMiddle); - private void OnRightClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSourceForCallback(ctx), PointerEvent.Button.MouseRight); + private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseLeft); + private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseMiddle); + private void OnRightClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseRight); private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) { @@ -400,7 +446,7 @@ private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) if (scrollDelta.sqrMagnitude < kSmallestReportedMovementSqrDist) return; - var eventSource = GetEventSourceForCallback(ctx); + var eventSource = GetEventSource(ctx); ref var state = ref GetPointerStateForSource(eventSource); var position = Vector2.zero; @@ -416,7 +462,7 @@ private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) position = Mouse.current.position.ReadValue(); targetDisplay = Mouse.current.displayIndex.ReadValue(); } - + // Make it look similar to IMGUI event scroll values. // TODO check how it behaves on macOS scrollDelta.x /= 40.0f; @@ -444,6 +490,27 @@ private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) })); } + private void RegisterNextPreviousAction() + { + _nextPreviousAction = new InputAction(name: "nextPreviousAction"); + // TODO add more default bindings, or make them configurable + _nextPreviousAction.AddBinding("/tab"); + if (_nextPreviousAction != null) + _nextPreviousAction.performed += OnNextPreviousPerformed; + + _nextPreviousAction.Enable(); + } + + private void UnregisterNextPreviousAction() + { + if (_nextPreviousAction != null) + { + _nextPreviousAction.performed -= OnNextPreviousPerformed; + _nextPreviousAction.Disable(); + _nextPreviousAction = null; + } + } + private void RegisterActions(Configuration cfg) { _inputActionAsset = InputActionAsset.FromJson(cfg.InputActionAssetAsJson); @@ -460,9 +527,6 @@ private void RegisterActions(Configuration cfg) if (_pointAction.action != null) _pointAction.action.performed += OnPointerPerformed; - if (_moveAction.action != null) - _moveAction.action.performed += OnMovePerformed; - if (_submitAction.action != null) _submitAction.action.performed += OnSubmitPerformed; @@ -480,20 +544,21 @@ private void RegisterActions(Configuration cfg) if (_scrollWheelAction.action != null) _scrollWheelAction.action.performed += OnScrollWheelPerformed; - - // When adding new one's don't forget to add them to UnregisterActions + + // When adding new one's don't forget to add them to UnregisterActions _inputActionAsset.Enable(); + + // TODO make it configurable as it is not part of default config + // The Next/Previous action is not part of the input actions asset + RegisterNextPreviousAction(); } private void UnregisterActions(Configuration cfg) { if (_pointAction.action != null) _pointAction.action.performed -= OnPointerPerformed; - - if (_moveAction.action != null) - _moveAction.action.performed -= OnMovePerformed; - + if (_submitAction.action != null) _submitAction.action.performed -= OnSubmitPerformed; @@ -511,7 +576,7 @@ private void UnregisterActions(Configuration cfg) if (_scrollWheelAction.action != null) _scrollWheelAction.action.performed -= OnScrollWheelPerformed; - + _pointAction = null; _moveAction = null; _submitAction = null; @@ -522,6 +587,10 @@ private void UnregisterActions(Configuration cfg) _scrollWheelAction = null; _inputActionAsset.Disable(); + + // The Next/Previous action is not part of the input actions asset + UnregisterNextPreviousAction(); + UnityEngine.Object.Destroy(_inputActionAsset); // TODO check if this is ok } @@ -549,7 +618,7 @@ public static Configuration GetDefaultConfiguration() var json = asset.asset.ToJson(); UnityEngine.Object.DestroyImmediate(asset.asset); // TODO just Dispose doesn't work in edit mode // asset.Dispose(); - + return new Configuration { InputActionAssetAsJson = json, From 9ad5c78a95e3446388025d9a2c13d1cebdb20e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o?= Date: Thu, 20 Apr 2023 17:34:34 +0200 Subject: [PATCH 15/31] InputForUI: Add repetition for Next/Previous navigation events (#1670) * Update renaming of Event.CompareType * Add Next/Previous navigation events repetition Currently it doesn't deal with keys other than tab and shift+tab. Discussion needs to happen to allow configuration for this with the Input System. --- .../Plugins/InputForUI/InputSystemProvider.cs | 73 ++++++++++++------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 492c5ec453..202c78b82d 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -90,22 +90,6 @@ public void Initialize() RegisterActions(_cfg); } - private void OnNextPreviousPerformed(InputAction.CallbackContext ctx) - { - if (ctx.control.device is Keyboard) - { - //TODO repeat rate - var keyboard = ctx.control.device as Keyboard; - DispatchFromCallback(Event.From(new NavigationEvent - { - type = NavigationEvent.Type.Move, - direction = keyboard.shiftKey.isPressed ? NavigationEvent.Direction.Previous : NavigationEvent.Direction.Next, - timestamp = _currentTime, - eventSource = EventSource.Keyboard, - })); - } - } - public void Shutdown() { UnregisterActions(_cfg); @@ -143,13 +127,19 @@ public void Update() _seenMouseEvents = false; } + //TODO: Refactor as there is no need for having almost the same implementation in the IM and ISX? private void DirectionNavigation(DiscreteTime currentTime) { - //TODO: Refactor as there is no need for having almost the same implementation in the IM and ISX? var(move, axesButtonWerePressed) = ReadCurrentNavigationMoveVector(); - var direction = NavigationEvent.DetermineMoveDirection(move); + // Checks for next/previous directions if no movement was detected + if (direction == NavigationEvent.Direction.None) + { + direction = ReadNextPreviousDirection(); + axesButtonWerePressed = _nextPreviousAction.WasPressedThisFrame(); + } + if (direction == NavigationEvent.Direction.None) { repeatHelper.Reset(); @@ -163,7 +153,7 @@ private void DirectionNavigation(DiscreteTime currentTime) type = NavigationEvent.Type.Move, direction = direction, timestamp = currentTime, - eventSource = GetEventSource(_moveAction.action.activeControl.device), + eventSource = GetEventSource(GetActiveDeviceFromDirection(direction)), playerId = kDefaultPlayerId, eventModifiers = _eventModifiers })); @@ -171,6 +161,24 @@ private void DirectionNavigation(DiscreteTime currentTime) } } + private InputDevice GetActiveDeviceFromDirection(NavigationEvent.Direction direction) + { + switch (direction) + { + case NavigationEvent.Direction.Left: + case NavigationEvent.Direction.Up: + case NavigationEvent.Direction.Right: + case NavigationEvent.Direction.Down: + return _moveAction.action.activeControl.device; + case NavigationEvent.Direction.Next: + case NavigationEvent.Direction.Previous: + return _nextPreviousAction.activeControl.device; + case NavigationEvent.Direction.None: + default: + return Keyboard.current; + } + } + private (Vector2, bool) ReadCurrentNavigationMoveVector() { var move = _moveAction.action.ReadValue(); @@ -179,9 +187,28 @@ private void DirectionNavigation(DiscreteTime currentTime) return (move, axisWasPressed); } + private NavigationEvent.Direction ReadNextPreviousDirection() + { + if (_nextPreviousAction.IsPressed()) + { + //TODO: For now it only deals with Keyboard, needs to deal with other devices if we can add bindings + // for Gamepad, etc + //TODO: An alternative could be to have an action for next and for previous since shortcut support does + // not work properly + if (_nextPreviousAction.activeControl.device is Keyboard) + { + var keyboard = _nextPreviousAction.activeControl.device as Keyboard; + // Return direction based on whether shift is pressed or not + return keyboard.shiftKey.isPressed ? NavigationEvent.Direction.Previous : NavigationEvent.Direction.Next; + } + } + + return NavigationEvent.Direction.None; + } + private static int SortEvents(Event a, Event b) { - return Event.Compare(a, b); + return Event.CompareType(a, b); } public void OnFocusChanged(bool focus) @@ -492,12 +519,9 @@ private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) private void RegisterNextPreviousAction() { - _nextPreviousAction = new InputAction(name: "nextPreviousAction"); + _nextPreviousAction = new InputAction(name: "nextPreviousAction", type: InputActionType.Button); // TODO add more default bindings, or make them configurable _nextPreviousAction.AddBinding("/tab"); - if (_nextPreviousAction != null) - _nextPreviousAction.performed += OnNextPreviousPerformed; - _nextPreviousAction.Enable(); } @@ -505,7 +529,6 @@ private void UnregisterNextPreviousAction() { if (_nextPreviousAction != null) { - _nextPreviousAction.performed -= OnNextPreviousPerformed; _nextPreviousAction.Disable(); _nextPreviousAction = null; } From 32cbfc8c0e314d6cc52a9b8843593315abdc54bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o?= Date: Thu, 20 Apr 2023 17:40:30 +0200 Subject: [PATCH 16/31] Set seenTouchEvents and seenTouchEvents for missing control paths and events (#1674) --- .../InputSystem/Plugins/InputForUI/InputSystemProvider.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 202c78b82d..e083caaaca 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -340,7 +340,7 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); - if (asTouchControl != null) + if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; else if (asPenDevice != null) _seenPenEvents = true; @@ -436,6 +436,11 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event var asTouchscreenDevice = ctx.control.device is Touchscreen ? (Touchscreen)ctx.control.device : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); + + if (asTouchControl != null || asTouchscreenDevice != null) + _seenTouchEvents = true; + else + _seenMouseEvents = true; var wasPressed = state.ButtonsState.Get(button); var isPressed = ctx.ReadValueAsButton(); From 1ab3c35ddd93bad76005eae3633679193ce95bb4 Mon Sep 17 00:00:00 2001 From: James McGill Date: Thu, 27 Apr 2023 11:57:42 +0200 Subject: [PATCH 17/31] fix compilation errors when opening InputSystem project --- .../Plugins/InputForUI/InputSystemProvider.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index e083caaaca..22d10cffda 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -1,19 +1,17 @@ -using System; using System.Collections.Generic; using Unity.IntegerTime; -using UnityEngine; -using UnityEngine.InputForUI; -using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; -using Event = UnityEngine.InputForUI.Event; -using EventModifiers = UnityEngine.InputForUI.EventModifiers; -using EventProvider = UnityEngine.InputForUI.EventProvider; +using UnityEngine.InputForUI; #if UNITY_EDITOR using UnityEditor; #endif -namespace InputSystem.Plugins.InputForUI +namespace UnityEngine.InputSystem.Plugins.InputForUI { + using Event = UnityEngine.InputForUI.Event; + using EventModifiers = UnityEngine.InputForUI.EventModifiers; + using EventProvider = UnityEngine.InputForUI.EventProvider; + #if UNITY_EDITOR [InitializeOnLoad] #endif From df24be7c4fe23db84a38fbfd5c4ae238156ec4e7 Mon Sep 17 00:00:00 2001 From: James McGill Date: Thu, 27 Apr 2023 14:06:02 +0200 Subject: [PATCH 18/31] fix compilation errors when opening project in older editors --- .../InputSystem/Plugins/InputForUI/InputSystemProvider.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 22d10cffda..452a9cbe4a 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -1,3 +1,4 @@ +#if UNITY_2023_2_OR_NEWER // UnityEngine.InputForUI Module unavailable in earlier releases using System.Collections.Generic; using Unity.IntegerTime; using UnityEngine.InputSystem.Controls; @@ -663,3 +664,4 @@ public static Configuration GetDefaultConfiguration() } } } +#endif // UNITY_2023_2_OR_NEWER From d7dd23956e94b1e2c3cb8e75996a1c0be2848e63 Mon Sep 17 00:00:00 2001 From: James McGill Date: Sat, 29 Apr 2023 14:59:04 +0200 Subject: [PATCH 19/31] Bootstrap InputForUI provider only if enabled in the PlayerSettings (ISX-1386) --- .../Plugins/InputForUI/InputSystemProvider.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 452a9cbe4a..e0f37bc1c1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -51,16 +51,15 @@ internal class InputSystemProvider : IEventProviderImpl static InputSystemProvider() { - // TODO check if input system is enabled before doing this - // enable me to test! + // Only if InputSystem is enabled in the PlayerSettings do we set it as the provider. + // This includes situations where both InputManager and InputSystem are enabled. +#if ENABLE_INPUT_SYSTEM EventProvider.SetInputSystemProvider(new InputSystemProvider()); +#endif } [RuntimeInitializeOnLoadMethod(loadType: RuntimeInitializeLoadType.SubsystemRegistration)] - private static void Bootstrap() - { - // will invoke static class constructor - } + private static void Bootstrap() {} // Empty function. Exists only to invoke the static class constructor in Runtime Players private EventModifiers _eventModifiers => _inputEventPartialProvider._eventModifiers; From e7e81f0bc1423d6e3dbd34dafef903c1998ad7c9 Mon Sep 17 00:00:00 2001 From: James McGill Date: Sat, 29 Apr 2023 15:03:36 +0200 Subject: [PATCH 20/31] Fix null reference errors by not initializing InputForUI in the editor (ISX-1397) --- .../InputSystem/Plugins/InputForUI/InputSystemProvider.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index e0f37bc1c1..130d45ffb5 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -3,9 +3,6 @@ using Unity.IntegerTime; using UnityEngine.InputSystem.Controls; using UnityEngine.InputForUI; -#if UNITY_EDITOR -using UnityEditor; -#endif namespace UnityEngine.InputSystem.Plugins.InputForUI { @@ -13,9 +10,6 @@ namespace UnityEngine.InputSystem.Plugins.InputForUI using EventModifiers = UnityEngine.InputForUI.EventModifiers; using EventProvider = UnityEngine.InputForUI.EventProvider; -#if UNITY_EDITOR - [InitializeOnLoad] -#endif internal class InputSystemProvider : IEventProviderImpl { private InputEventPartialProvider _inputEventPartialProvider; From 1441c5f6b59d9413949277b37fe60d1dfc134982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Freire?= Date: Mon, 8 May 2023 16:42:28 +0200 Subject: [PATCH 21/31] Fix to avoid PointerEvents from Mouse when using Touch --- .../Plugins/InputForUI/InputSystemProvider.cs | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 130d45ffb5..f95711bcd6 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -42,6 +42,7 @@ internal class InputSystemProvider : IEventProviderImpl private const float kSmallestReportedMovementSqrDist = 0.01f; private NavigationEventRepeatHelper repeatHelper = new(); + private bool _doNotResetSeenEventsOnUpdate; static InputSystemProvider() { @@ -106,14 +107,33 @@ public void Update() // this is mostly used to filter out simulated input, e.g. when pen is active it also generates mouse input if (_seenTouchEvents && ev.type == Event.Type.PointerEvent && ev.eventSource == EventSource.Pen) _penState.Reset(); - else if ((_seenTouchEvents || _seenPenEvents) && ev.type == Event.Type.PointerEvent && (ev.eventSource == EventSource.Mouse || ev.eventSource == EventSource.Unspecified)) + else if ((_seenTouchEvents || _seenPenEvents) && + ev.type == Event.Type.PointerEvent && (ev.eventSource == EventSource.Mouse || ev.eventSource == EventSource.Unspecified)) _mouseState.Reset(); else + { + if(ev.eventSource == EventSource.Mouse) + Debug.Log("Mouse event triggered"); EventProvider.Dispatch(ev); + } } + // Sometimes single lower priority events can be received when using Touch or Pen, on a different frame. + // To avoid dispatching them, the seen event flags aren't reset in between calls to OnPointerPerformed. + // Essentially, if we're moving with Touch or Pen, lower priority events aren't dispatch as well. + // Once OnClickPerformed is called, the seen flags are reset + if (!_doNotResetSeenEventsOnUpdate) + { + ResetSeenEvents(); + _doNotResetSeenEventsOnUpdate = false; + } + _events.Clear(); + } + + private void ResetSeenEvents() + { _seenTouchEvents = false; _seenPenEvents = false; _seenMouseEvents = false; @@ -332,6 +352,8 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); + + _doNotResetSeenEventsOnUpdate = true; if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; else if (asPenDevice != null) @@ -428,7 +450,8 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event var asTouchscreenDevice = ctx.control.device is Touchscreen ? (Touchscreen)ctx.control.device : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); - + + _doNotResetSeenEventsOnUpdate = false; if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; else From 3f57bc39a91c81904347b4307090f64f12e2c1ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Freire?= Date: Tue, 9 May 2023 12:00:07 +0200 Subject: [PATCH 22/31] Reverse bool logic of resetSeenEventsOnUpdate --- .../Plugins/InputForUI/InputSystemProvider.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index f95711bcd6..7d6121b862 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -42,7 +42,7 @@ internal class InputSystemProvider : IEventProviderImpl private const float kSmallestReportedMovementSqrDist = 0.01f; private NavigationEventRepeatHelper repeatHelper = new(); - private bool _doNotResetSeenEventsOnUpdate; + private bool _resetSeenEventsOnUpdate; static InputSystemProvider() { @@ -122,10 +122,10 @@ public void Update() // To avoid dispatching them, the seen event flags aren't reset in between calls to OnPointerPerformed. // Essentially, if we're moving with Touch or Pen, lower priority events aren't dispatch as well. // Once OnClickPerformed is called, the seen flags are reset - if (!_doNotResetSeenEventsOnUpdate) + if (_resetSeenEventsOnUpdate) { ResetSeenEvents(); - _doNotResetSeenEventsOnUpdate = false; + _resetSeenEventsOnUpdate = false; } _events.Clear(); @@ -353,7 +353,7 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); - _doNotResetSeenEventsOnUpdate = true; + _resetSeenEventsOnUpdate = false; if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; else if (asPenDevice != null) @@ -451,7 +451,7 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); - _doNotResetSeenEventsOnUpdate = false; + _resetSeenEventsOnUpdate = true; if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; else From 73d6dd1f8e915b83bfa9be80dfa9f1c6fb144fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Freire?= Date: Tue, 9 May 2023 15:22:33 +0200 Subject: [PATCH 23/31] Remove debug logs --- .../InputSystem/Plugins/InputForUI/InputSystemProvider.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 7d6121b862..2fffc6c6b2 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -111,11 +111,7 @@ public void Update() ev.type == Event.Type.PointerEvent && (ev.eventSource == EventSource.Mouse || ev.eventSource == EventSource.Unspecified)) _mouseState.Reset(); else - { - if(ev.eventSource == EventSource.Mouse) - Debug.Log("Mouse event triggered"); EventProvider.Dispatch(ev); - } } // Sometimes single lower priority events can be received when using Touch or Pen, on a different frame. From f29e0a9a4e2b198b68918957eb1816a6afa61ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Freire?= Date: Mon, 15 May 2023 13:59:49 +0200 Subject: [PATCH 24/31] Fix PointerEvents with same pointerIndex for all fingers --- .../Plugins/InputForUI/InputSystemProvider.cs | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 2fffc6c6b2..c1dedd50b2 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -335,6 +335,27 @@ private void DispatchFromCallback(in Event ev) _events.Add(ev); } + private static int FindTouchFingerIndex(Touchscreen touchscreen, InputAction.CallbackContext ctx) + { + var asVector2Control = ctx.control is Vector2Control ? (Vector2Control)ctx.control : null; + var asTouchPressControl = ctx.control is TouchPressControl ? (TouchPressControl)ctx.control : null; + var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; + if (touchscreen == null) + return 0; + + // Finds the index of the matching control type in the Touchscreen device lost of touch controls (touches) + for (var i = 0; i < touchscreen.touches.Count; ++i) + { + if (asVector2Control != null && asVector2Control == touchscreen.touches[i].position) + return i; + if (asTouchPressControl != null && asTouchPressControl == touchscreen.touches[i].press) + return i; + if (asTouchControl != null && asTouchControl == touchscreen.touches[i]) + return i; + } + return 0; + } + private void OnPointerPerformed(InputAction.CallbackContext ctx) { var eventSource = GetEventSource(ctx); @@ -346,9 +367,8 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) var asPenDevice = ctx.control.device is Pen ? (Pen)ctx.control.device : null; var asTouchscreenDevice = ctx.control.device is Touchscreen ? (Touchscreen)ctx.control.device : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; - var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); + var pointerIndex = FindTouchFingerIndex(asTouchscreenDevice, ctx); - _resetSeenEventsOnUpdate = false; if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; @@ -427,26 +447,14 @@ private void OnCancelPerformed(InputAction.CallbackContext ctx) })); } - private int FindPointerIndex(Touchscreen touchscreen, TouchControl touchControl) - { - if (touchscreen == null || touchControl == null) - return 0; - - for (var i = 0; i < touchscreen.touches.Count; ++i) - if (touchscreen.touches[i] == touchControl) - return i; - - return 0; - } - private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) { ref var state = ref GetPointerStateForSource(eventSource); var asTouchscreenDevice = ctx.control.device is Touchscreen ? (Touchscreen)ctx.control.device : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; - var pointerIndex = FindPointerIndex(asTouchscreenDevice, asTouchControl); - + var pointerIndex = FindTouchFingerIndex(asTouchscreenDevice, ctx); + _resetSeenEventsOnUpdate = true; if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; From 04323d7dee661793333ff57ae3ca9cc355a95c2c Mon Sep 17 00:00:00 2001 From: James McGill Date: Tue, 16 May 2023 16:00:52 +0200 Subject: [PATCH 25/31] fix InputForUI not being bootstrapped in IL2CPP builds (ISX-1424) --- .../InputSystem/Plugins/InputForUI/AssemblyInfo.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs index 570168457b..ea35c04c30 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/AssemblyInfo.cs @@ -1,3 +1,5 @@ using System.Runtime.CompilerServices; +using UnityEngine.Scripting; [assembly: InternalsVisibleTo("UnityEngine.InputForUIVisualizer")] +[assembly: AlwaysLinkAssembly] From 21e3fff30e108567bbe4cfb9a0b5f4b031f28b0f Mon Sep 17 00:00:00 2001 From: James McGill Date: Wed, 17 May 2023 17:16:12 +0200 Subject: [PATCH 26/31] fix for deprecated warning --- .../Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs index c5acb6794d..bf492130f5 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs @@ -61,7 +61,7 @@ private void OnKeyDownEventForRename(KeyDownEvent e) return; FocusOnRenameTextField(); - e.PreventDefault(); + e.StopPropagation(); } private void OnMouseDownEventForRename(MouseDownEvent e) @@ -70,7 +70,6 @@ private void OnMouseDownEventForRename(MouseDownEvent e) return; FocusOnRenameTextField(); - e.StopPropagation(); } From a5a723095fc80d10a81ff0a35669fe97acebb7ce Mon Sep 17 00:00:00 2001 From: James McGill Date: Fri, 19 May 2023 13:28:13 +0200 Subject: [PATCH 27/31] fix for unused variable warning --- .../Plugins/InputForUI/InputSystemProvider.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index c1dedd50b2..4a30e0694c 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -31,7 +31,6 @@ internal class InputSystemProvider : IEventProviderImpl List _events = new List(); private PointerState _mouseState; - private bool _seenMouseEvents; private PointerState _penState; private bool _seenPenEvents; @@ -70,7 +69,6 @@ public void Initialize() _events.Clear(); _mouseState.Reset(); - _seenMouseEvents = false; _penState.Reset(); _seenPenEvents = false; @@ -132,7 +130,6 @@ private void ResetSeenEvents() { _seenTouchEvents = false; _seenPenEvents = false; - _seenMouseEvents = false; } //TODO: Refactor as there is no need for having almost the same implementation in the IM and ISX? @@ -343,7 +340,7 @@ private static int FindTouchFingerIndex(Touchscreen touchscreen, InputAction.Cal if (touchscreen == null) return 0; - // Finds the index of the matching control type in the Touchscreen device lost of touch controls (touches) + // Finds the index of the matching control type in the Touchscreen device lost of touch controls (touches) for (var i = 0; i < touchscreen.touches.Count; ++i) { if (asVector2Control != null && asVector2Control == touchscreen.touches[i].position) @@ -374,8 +371,6 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) _seenTouchEvents = true; else if (asPenDevice != null) _seenPenEvents = true; - else - _seenMouseEvents = true; var positionISX = ctx.ReadValue(); var targetDisplay = asPointerDevice != null ? asPointerDevice.displayIndex.ReadValue() : (asTouchscreenDevice != null ? asTouchscreenDevice.displayIndex.ReadValue() : 0); @@ -458,8 +453,6 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event _resetSeenEventsOnUpdate = true; if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; - else - _seenMouseEvents = true; var wasPressed = state.ButtonsState.Get(button); var isPressed = ctx.ReadValueAsButton(); From 9f4e9961cba4610c7777de905e3551f050cf10a8 Mon Sep 17 00:00:00 2001 From: James McGill Date: Fri, 19 May 2023 15:03:43 +0200 Subject: [PATCH 28/31] run formatting tool --- .../InputSystem/Plugins/InputForUI/InputSystemProvider.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 4a30e0694c..f07729b3c5 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -105,7 +105,7 @@ public void Update() // this is mostly used to filter out simulated input, e.g. when pen is active it also generates mouse input if (_seenTouchEvents && ev.type == Event.Type.PointerEvent && ev.eventSource == EventSource.Pen) _penState.Reset(); - else if ((_seenTouchEvents || _seenPenEvents) && + else if ((_seenTouchEvents || _seenPenEvents) && ev.type == Event.Type.PointerEvent && (ev.eventSource == EventSource.Mouse || ev.eventSource == EventSource.Unspecified)) _mouseState.Reset(); else @@ -121,9 +121,8 @@ public void Update() ResetSeenEvents(); _resetSeenEventsOnUpdate = false; } - - _events.Clear(); + _events.Clear(); } private void ResetSeenEvents() @@ -449,7 +448,7 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event var asTouchscreenDevice = ctx.control.device is Touchscreen ? (Touchscreen)ctx.control.device : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; var pointerIndex = FindTouchFingerIndex(asTouchscreenDevice, ctx); - + _resetSeenEventsOnUpdate = true; if (asTouchControl != null || asTouchscreenDevice != null) _seenTouchEvents = true; From 386d16f04f9a6d5f8314e37692c88f9458719f77 Mon Sep 17 00:00:00 2001 From: James McGill Date: Fri, 19 May 2023 16:30:30 +0200 Subject: [PATCH 29/31] modify naming to conform to coding convention --- .../Plugins/InputForUI/InputSystemProvider.cs | 366 +++++++++--------- 1 file changed, 183 insertions(+), 183 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index f07729b3c5..0880fc8ea1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -12,36 +12,36 @@ namespace UnityEngine.InputSystem.Plugins.InputForUI internal class InputSystemProvider : IEventProviderImpl { - private InputEventPartialProvider _inputEventPartialProvider; + InputEventPartialProvider m_InputEventPartialProvider; - private Configuration _cfg; + Configuration m_Cfg; - private InputActionAsset _inputActionAsset; - private InputActionReference _pointAction; - private InputActionReference _moveAction; - private InputActionReference _submitAction; - private InputActionReference _cancelAction; - private InputActionReference _leftClickAction; - private InputActionReference _middleClickAction; - private InputActionReference _rightClickAction; - private InputActionReference _scrollWheelAction; + InputActionAsset m_InputActionAsset; + InputActionReference m_PointAction; + InputActionReference m_MoveAction; + InputActionReference m_SubmitAction; + InputActionReference m_CancelAction; + InputActionReference m_LeftClickAction; + InputActionReference m_MiddleClickAction; + InputActionReference m_RightClickAction; + InputActionReference m_ScrollWheelAction; - InputAction _nextPreviousAction; + InputAction m_NextPreviousAction; - List _events = new List(); + List m_Events = new List(); - private PointerState _mouseState; + PointerState m_MouseState; - private PointerState _penState; - private bool _seenPenEvents; + PointerState m_PenState; + bool m_SeenPenEvents; - private PointerState _touchState; - private bool _seenTouchEvents; + PointerState m_TouchState; + bool m_SeenTouchEvents; - private const float kSmallestReportedMovementSqrDist = 0.01f; + const float k_SmallestReportedMovementSqrDist = 0.01f; - private NavigationEventRepeatHelper repeatHelper = new(); - private bool _resetSeenEventsOnUpdate; + NavigationEventRepeatHelper m_RepeatHelper = new(); + bool m_ResetSeenEventsOnUpdate; static InputSystemProvider() { @@ -53,61 +53,61 @@ static InputSystemProvider() } [RuntimeInitializeOnLoadMethod(loadType: RuntimeInitializeLoadType.SubsystemRegistration)] - private static void Bootstrap() {} // Empty function. Exists only to invoke the static class constructor in Runtime Players + static void Bootstrap() {} // Empty function. Exists only to invoke the static class constructor in Runtime Players - private EventModifiers _eventModifiers => _inputEventPartialProvider._eventModifiers; + EventModifiers m_EventModifiers => m_InputEventPartialProvider._eventModifiers; - private DiscreteTime _currentTime => (DiscreteTime)Time.timeAsRational; + DiscreteTime m_CurrentTime => (DiscreteTime)Time.timeAsRational; - private const uint kDefaultPlayerId = 0u; + const uint k_DefaultPlayerId = 0u; public void Initialize() { - _inputEventPartialProvider ??= new InputEventPartialProvider(); - _inputEventPartialProvider.Initialize(); + m_InputEventPartialProvider ??= new InputEventPartialProvider(); + m_InputEventPartialProvider.Initialize(); - _events.Clear(); + m_Events.Clear(); - _mouseState.Reset(); + m_MouseState.Reset(); - _penState.Reset(); - _seenPenEvents = false; + m_PenState.Reset(); + m_SeenPenEvents = false; - _touchState.Reset(); - _seenTouchEvents = false; + m_TouchState.Reset(); + m_SeenTouchEvents = false; // TODO should UITK somehow override this? - _cfg = Configuration.GetDefaultConfiguration(); - RegisterActions(_cfg); + m_Cfg = Configuration.GetDefaultConfiguration(); + RegisterActions(m_Cfg); } public void Shutdown() { - UnregisterActions(_cfg); + UnregisterActions(m_Cfg); - _inputEventPartialProvider.Shutdown(); - _inputEventPartialProvider = null; + m_InputEventPartialProvider.Shutdown(); + m_InputEventPartialProvider = null; } public void Update() { - _inputEventPartialProvider.Update(); + m_InputEventPartialProvider.Update(); - _events.Sort(SortEvents); + m_Events.Sort(SortEvents); var currentTime = (DiscreteTime)Time.timeAsRational; DirectionNavigation(currentTime); - foreach (var ev in _events) + foreach (var ev in m_Events) { // we need to ignore some pointer events based on priority (touch->pen->mouse) // this is mostly used to filter out simulated input, e.g. when pen is active it also generates mouse input - if (_seenTouchEvents && ev.type == Event.Type.PointerEvent && ev.eventSource == EventSource.Pen) - _penState.Reset(); - else if ((_seenTouchEvents || _seenPenEvents) && + if (m_SeenTouchEvents && ev.type == Event.Type.PointerEvent && ev.eventSource == EventSource.Pen) + m_PenState.Reset(); + else if ((m_SeenTouchEvents || m_SeenPenEvents) && ev.type == Event.Type.PointerEvent && (ev.eventSource == EventSource.Mouse || ev.eventSource == EventSource.Unspecified)) - _mouseState.Reset(); + m_MouseState.Reset(); else EventProvider.Dispatch(ev); } @@ -116,23 +116,23 @@ public void Update() // To avoid dispatching them, the seen event flags aren't reset in between calls to OnPointerPerformed. // Essentially, if we're moving with Touch or Pen, lower priority events aren't dispatch as well. // Once OnClickPerformed is called, the seen flags are reset - if (_resetSeenEventsOnUpdate) + if (m_ResetSeenEventsOnUpdate) { ResetSeenEvents(); - _resetSeenEventsOnUpdate = false; + m_ResetSeenEventsOnUpdate = false; } - _events.Clear(); + m_Events.Clear(); } - private void ResetSeenEvents() + void ResetSeenEvents() { - _seenTouchEvents = false; - _seenPenEvents = false; + m_SeenTouchEvents = false; + m_SeenPenEvents = false; } //TODO: Refactor as there is no need for having almost the same implementation in the IM and ISX? - private void DirectionNavigation(DiscreteTime currentTime) + void DirectionNavigation(DiscreteTime currentTime) { var(move, axesButtonWerePressed) = ReadCurrentNavigationMoveVector(); var direction = NavigationEvent.DetermineMoveDirection(move); @@ -141,16 +141,16 @@ private void DirectionNavigation(DiscreteTime currentTime) if (direction == NavigationEvent.Direction.None) { direction = ReadNextPreviousDirection(); - axesButtonWerePressed = _nextPreviousAction.WasPressedThisFrame(); + axesButtonWerePressed = m_NextPreviousAction.WasPressedThisFrame(); } if (direction == NavigationEvent.Direction.None) { - repeatHelper.Reset(); + m_RepeatHelper.Reset(); } else { - if (repeatHelper.ShouldSendMoveEvent(currentTime, direction, axesButtonWerePressed)) + if (m_RepeatHelper.ShouldSendMoveEvent(currentTime, direction, axesButtonWerePressed)) { EventProvider.Dispatch(Event.From(new NavigationEvent { @@ -158,14 +158,14 @@ private void DirectionNavigation(DiscreteTime currentTime) direction = direction, timestamp = currentTime, eventSource = GetEventSource(GetActiveDeviceFromDirection(direction)), - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers + playerId = k_DefaultPlayerId, + eventModifiers = m_EventModifiers })); } } } - private InputDevice GetActiveDeviceFromDirection(NavigationEvent.Direction direction) + InputDevice GetActiveDeviceFromDirection(NavigationEvent.Direction direction) { switch (direction) { @@ -173,35 +173,35 @@ private InputDevice GetActiveDeviceFromDirection(NavigationEvent.Direction direc case NavigationEvent.Direction.Up: case NavigationEvent.Direction.Right: case NavigationEvent.Direction.Down: - return _moveAction.action.activeControl.device; + return m_MoveAction.action.activeControl.device; case NavigationEvent.Direction.Next: case NavigationEvent.Direction.Previous: - return _nextPreviousAction.activeControl.device; + return m_NextPreviousAction.activeControl.device; case NavigationEvent.Direction.None: default: return Keyboard.current; } } - private (Vector2, bool) ReadCurrentNavigationMoveVector() + (Vector2, bool) ReadCurrentNavigationMoveVector() { - var move = _moveAction.action.ReadValue(); + var move = m_MoveAction.action.ReadValue(); // Check if the action was "pressed" this frame to deal with repeating events - var axisWasPressed = _moveAction.action.WasPressedThisFrame(); + var axisWasPressed = m_MoveAction.action.WasPressedThisFrame(); return (move, axisWasPressed); } - private NavigationEvent.Direction ReadNextPreviousDirection() + NavigationEvent.Direction ReadNextPreviousDirection() { - if (_nextPreviousAction.IsPressed()) + if (m_NextPreviousAction.IsPressed()) { //TODO: For now it only deals with Keyboard, needs to deal with other devices if we can add bindings // for Gamepad, etc //TODO: An alternative could be to have an action for next and for previous since shortcut support does // not work properly - if (_nextPreviousAction.activeControl.device is Keyboard) + if (m_NextPreviousAction.activeControl.device is Keyboard) { - var keyboard = _nextPreviousAction.activeControl.device as Keyboard; + var keyboard = m_NextPreviousAction.activeControl.device as Keyboard; // Return direction based on whether shift is pressed or not return keyboard.shiftKey.isPressed ? NavigationEvent.Direction.Previous : NavigationEvent.Direction.Next; } @@ -210,39 +210,39 @@ private NavigationEvent.Direction ReadNextPreviousDirection() return NavigationEvent.Direction.None; } - private static int SortEvents(Event a, Event b) + static int SortEvents(Event a, Event b) { return Event.CompareType(a, b); } public void OnFocusChanged(bool focus) { - _inputEventPartialProvider.OnFocusChanged(focus); + m_InputEventPartialProvider.OnFocusChanged(focus); } public bool RequestCurrentState(Event.Type type) { - if (_inputEventPartialProvider.RequestCurrentState(type)) + if (m_InputEventPartialProvider.RequestCurrentState(type)) return true; switch (type) { case Event.Type.PointerEvent: { - if (_touchState.LastPositionValid) - EventProvider.Dispatch(Event.From(ToPointerStateEvent(_currentTime, _touchState, EventSource.Touch))); - if (_penState.LastPositionValid) - EventProvider.Dispatch(Event.From(ToPointerStateEvent(_currentTime, _penState, EventSource.Pen))); - if (_mouseState.LastPositionValid) - EventProvider.Dispatch(Event.From(ToPointerStateEvent(_currentTime, _mouseState, EventSource.Mouse))); + if (m_TouchState.LastPositionValid) + EventProvider.Dispatch(Event.From(ToPointerStateEvent(m_CurrentTime, m_TouchState, EventSource.Touch))); + if (m_PenState.LastPositionValid) + EventProvider.Dispatch(Event.From(ToPointerStateEvent(m_CurrentTime, m_PenState, EventSource.Pen))); + if (m_MouseState.LastPositionValid) + EventProvider.Dispatch(Event.From(ToPointerStateEvent(m_CurrentTime, m_MouseState, EventSource.Mouse))); else { // TODO maybe it's reasonable to poll and dispatch mouse state here anyway? } - return _touchState.LastPositionValid || - _penState.LastPositionValid || - _mouseState.LastPositionValid; + return m_TouchState.LastPositionValid || + m_PenState.LastPositionValid || + m_MouseState.LastPositionValid; } // TODO case Event.Type.IMECompositionEvent: @@ -256,7 +256,7 @@ public bool RequestCurrentState(Event.Type type) public uint playerCount => 1; // TODO // copied from UIElementsRuntimeUtility.cs - private static Vector2 ScreenBottomLeftToPanelPosition(Vector2 position, int targetDisplay) + static Vector2 ScreenBottomLeftToPanelPosition(Vector2 position, int targetDisplay) { // Flip positions Y axis between input and UITK var screenHeight = Screen.height; @@ -266,7 +266,7 @@ private static Vector2 ScreenBottomLeftToPanelPosition(Vector2 position, int tar return position; } - private PointerEvent ToPointerStateEvent(DiscreteTime currentTime, in PointerState state, EventSource eventSource) + PointerEvent ToPointerStateEvent(DiscreteTime currentTime, in PointerState state, EventSource eventSource) { return new PointerEvent { @@ -286,18 +286,18 @@ private PointerEvent ToPointerStateEvent(DiscreteTime currentTime, in PointerSta clickCount = 0, timestamp = currentTime, eventSource = eventSource, - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers + playerId = k_DefaultPlayerId, + eventModifiers = m_EventModifiers }; } - private EventSource GetEventSource(InputAction.CallbackContext ctx) + EventSource GetEventSource(InputAction.CallbackContext ctx) { var device = ctx.control.device; return GetEventSource(device); } - private EventSource GetEventSource(InputDevice device) + EventSource GetEventSource(InputDevice device) { if (device is Touchscreen) return EventSource.Touch; @@ -313,25 +313,25 @@ private EventSource GetEventSource(InputDevice device) return EventSource.Unspecified; } - private ref PointerState GetPointerStateForSource(EventSource eventSource) + ref PointerState GetPointerStateForSource(EventSource eventSource) { switch (eventSource) { case EventSource.Touch: - return ref _touchState; + return ref m_TouchState; case EventSource.Pen: - return ref _penState; + return ref m_PenState; default: - return ref _mouseState; + return ref m_MouseState; } } - private void DispatchFromCallback(in Event ev) + void DispatchFromCallback(in Event ev) { - _events.Add(ev); + m_Events.Add(ev); } - private static int FindTouchFingerIndex(Touchscreen touchscreen, InputAction.CallbackContext ctx) + static int FindTouchFingerIndex(Touchscreen touchscreen, InputAction.CallbackContext ctx) { var asVector2Control = ctx.control is Vector2Control ? (Vector2Control)ctx.control : null; var asTouchPressControl = ctx.control is TouchPressControl ? (TouchPressControl)ctx.control : null; @@ -352,7 +352,7 @@ private static int FindTouchFingerIndex(Touchscreen touchscreen, InputAction.Cal return 0; } - private void OnPointerPerformed(InputAction.CallbackContext ctx) + void OnPointerPerformed(InputAction.CallbackContext ctx) { var eventSource = GetEventSource(ctx); ref var pointerState = ref GetPointerStateForSource(eventSource); @@ -365,11 +365,11 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; var pointerIndex = FindTouchFingerIndex(asTouchscreenDevice, ctx); - _resetSeenEventsOnUpdate = false; + m_ResetSeenEventsOnUpdate = false; if (asTouchControl != null || asTouchscreenDevice != null) - _seenTouchEvents = true; + m_SeenTouchEvents = true; else if (asPenDevice != null) - _seenPenEvents = true; + m_SeenPenEvents = true; var positionISX = ctx.ReadValue(); var targetDisplay = asPointerDevice != null ? asPointerDevice.displayIndex.ReadValue() : (asTouchscreenDevice != null ? asTouchscreenDevice.displayIndex.ReadValue() : 0); @@ -385,7 +385,7 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) ? asPenDevice.eraser.isPressed : false; // TODO any way to detect that pen is inverted but not touching? - if (delta.sqrMagnitude >= kSmallestReportedMovementSqrDist) + if (delta.sqrMagnitude >= k_SmallestReportedMovementSqrDist) { DispatchFromCallback(Event.From(new PointerEvent { @@ -402,46 +402,46 @@ private void OnPointerPerformed(InputAction.CallbackContext ctx) button = 0, buttonsState = pointerState.ButtonsState, clickCount = 0, - timestamp = _currentTime, + timestamp = m_CurrentTime, eventSource = eventSource, - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers + playerId = k_DefaultPlayerId, + eventModifiers = m_EventModifiers })); // only record if we send an event - pointerState.OnMove(_currentTime, position, targetDisplay); + pointerState.OnMove(m_CurrentTime, position, targetDisplay); } else if (!pointerState.LastPositionValid) - pointerState.OnMove(_currentTime, position, targetDisplay); + pointerState.OnMove(m_CurrentTime, position, targetDisplay); } - private void OnSubmitPerformed(InputAction.CallbackContext ctx) + void OnSubmitPerformed(InputAction.CallbackContext ctx) { DispatchFromCallback(Event.From(new NavigationEvent { type = NavigationEvent.Type.Submit, direction = NavigationEvent.Direction.None, - timestamp = _currentTime, + timestamp = m_CurrentTime, eventSource = GetEventSource(ctx), - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers + playerId = k_DefaultPlayerId, + eventModifiers = m_EventModifiers })); } - private void OnCancelPerformed(InputAction.CallbackContext ctx) + void OnCancelPerformed(InputAction.CallbackContext ctx) { DispatchFromCallback(Event.From(new NavigationEvent { type = NavigationEvent.Type.Cancel, direction = NavigationEvent.Direction.None, - timestamp = _currentTime, + timestamp = m_CurrentTime, eventSource = GetEventSource(ctx), - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers + playerId = k_DefaultPlayerId, + eventModifiers = m_EventModifiers })); } - private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) + void OnClickPerformed(InputAction.CallbackContext ctx, EventSource eventSource, PointerEvent.Button button) { ref var state = ref GetPointerStateForSource(eventSource); @@ -449,13 +449,13 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; var pointerIndex = FindTouchFingerIndex(asTouchscreenDevice, ctx); - _resetSeenEventsOnUpdate = true; + m_ResetSeenEventsOnUpdate = true; if (asTouchControl != null || asTouchscreenDevice != null) - _seenTouchEvents = true; + m_SeenTouchEvents = true; var wasPressed = state.ButtonsState.Get(button); var isPressed = ctx.ReadValueAsButton(); - state.OnButtonChange(_currentTime, button, wasPressed, isPressed); + state.OnButtonChange(m_CurrentTime, button, wasPressed, isPressed); DispatchFromCallback(Event.From(new PointerEvent { @@ -472,21 +472,21 @@ private void OnClickPerformed(InputAction.CallbackContext ctx, EventSource event button = button, buttonsState = state.ButtonsState, clickCount = state.ClickCount, - timestamp = _currentTime, + timestamp = m_CurrentTime, eventSource = eventSource, - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers + playerId = k_DefaultPlayerId, + eventModifiers = m_EventModifiers })); } - private void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseLeft); - private void OnMiddleClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseMiddle); - private void OnRightClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseRight); + void OnLeftClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseLeft); + void OnMiddleClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseMiddle); + void OnRightClickPerformed(InputAction.CallbackContext ctx) => OnClickPerformed(ctx, GetEventSource(ctx), PointerEvent.Button.MouseRight); - private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) + void OnScrollWheelPerformed(InputAction.CallbackContext ctx) { var scrollDelta = ctx.ReadValue(); - if (scrollDelta.sqrMagnitude < kSmallestReportedMovementSqrDist) + if (scrollDelta.sqrMagnitude < k_SmallestReportedMovementSqrDist) return; var eventSource = GetEventSource(ctx); @@ -526,111 +526,111 @@ private void OnScrollWheelPerformed(InputAction.CallbackContext ctx) button = 0, buttonsState = state.ButtonsState, clickCount = 0, - timestamp = _currentTime, + timestamp = m_CurrentTime, eventSource = EventSource.Mouse, - playerId = kDefaultPlayerId, - eventModifiers = _eventModifiers + playerId = k_DefaultPlayerId, + eventModifiers = m_EventModifiers })); } - private void RegisterNextPreviousAction() + void RegisterNextPreviousAction() { - _nextPreviousAction = new InputAction(name: "nextPreviousAction", type: InputActionType.Button); + m_NextPreviousAction = new InputAction(name: "nextPreviousAction", type: InputActionType.Button); // TODO add more default bindings, or make them configurable - _nextPreviousAction.AddBinding("/tab"); - _nextPreviousAction.Enable(); + m_NextPreviousAction.AddBinding("/tab"); + m_NextPreviousAction.Enable(); } - private void UnregisterNextPreviousAction() + void UnregisterNextPreviousAction() { - if (_nextPreviousAction != null) + if (m_NextPreviousAction != null) { - _nextPreviousAction.Disable(); - _nextPreviousAction = null; + m_NextPreviousAction.Disable(); + m_NextPreviousAction = null; } } - private void RegisterActions(Configuration cfg) + void RegisterActions(Configuration cfg) { - _inputActionAsset = InputActionAsset.FromJson(cfg.InputActionAssetAsJson); + m_InputActionAsset = InputActionAsset.FromJson(cfg.InputActionAssetAsJson); - _pointAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.PointAction)); - _moveAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.MoveAction)); - _submitAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.SubmitAction)); - _cancelAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.CancelAction)); - _leftClickAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.LeftClickAction)); - _middleClickAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.MiddleClickAction)); - _rightClickAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.RightClickAction)); - _scrollWheelAction = InputActionReference.Create(_inputActionAsset.FindAction(_cfg.ScrollWheelAction)); + m_PointAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.PointAction)); + m_MoveAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.MoveAction)); + m_SubmitAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.SubmitAction)); + m_CancelAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.CancelAction)); + m_LeftClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.LeftClickAction)); + m_MiddleClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.MiddleClickAction)); + m_RightClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.RightClickAction)); + m_ScrollWheelAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.ScrollWheelAction)); - if (_pointAction.action != null) - _pointAction.action.performed += OnPointerPerformed; + if (m_PointAction.action != null) + m_PointAction.action.performed += OnPointerPerformed; - if (_submitAction.action != null) - _submitAction.action.performed += OnSubmitPerformed; + if (m_SubmitAction.action != null) + m_SubmitAction.action.performed += OnSubmitPerformed; - if (_cancelAction.action != null) - _cancelAction.action.performed += OnCancelPerformed; + if (m_CancelAction.action != null) + m_CancelAction.action.performed += OnCancelPerformed; - if (_leftClickAction.action != null) - _leftClickAction.action.performed += OnLeftClickPerformed; + if (m_LeftClickAction.action != null) + m_LeftClickAction.action.performed += OnLeftClickPerformed; - if (_middleClickAction.action != null) - _middleClickAction.action.performed += OnMiddleClickPerformed; + if (m_MiddleClickAction.action != null) + m_MiddleClickAction.action.performed += OnMiddleClickPerformed; - if (_rightClickAction.action != null) - _rightClickAction.action.performed += OnRightClickPerformed; + if (m_RightClickAction.action != null) + m_RightClickAction.action.performed += OnRightClickPerformed; - if (_scrollWheelAction.action != null) - _scrollWheelAction.action.performed += OnScrollWheelPerformed; + if (m_ScrollWheelAction.action != null) + m_ScrollWheelAction.action.performed += OnScrollWheelPerformed; // When adding new one's don't forget to add them to UnregisterActions - _inputActionAsset.Enable(); + m_InputActionAsset.Enable(); // TODO make it configurable as it is not part of default config // The Next/Previous action is not part of the input actions asset RegisterNextPreviousAction(); } - private void UnregisterActions(Configuration cfg) + void UnregisterActions(Configuration cfg) { - if (_pointAction.action != null) - _pointAction.action.performed -= OnPointerPerformed; + if (m_PointAction.action != null) + m_PointAction.action.performed -= OnPointerPerformed; - if (_submitAction.action != null) - _submitAction.action.performed -= OnSubmitPerformed; + if (m_SubmitAction.action != null) + m_SubmitAction.action.performed -= OnSubmitPerformed; - if (_cancelAction.action != null) - _cancelAction.action.performed -= OnCancelPerformed; + if (m_CancelAction.action != null) + m_CancelAction.action.performed -= OnCancelPerformed; - if (_leftClickAction.action != null) - _leftClickAction.action.performed -= OnLeftClickPerformed; + if (m_LeftClickAction.action != null) + m_LeftClickAction.action.performed -= OnLeftClickPerformed; - if (_middleClickAction.action != null) - _middleClickAction.action.performed -= OnMiddleClickPerformed; + if (m_MiddleClickAction.action != null) + m_MiddleClickAction.action.performed -= OnMiddleClickPerformed; - if (_rightClickAction.action != null) - _rightClickAction.action.performed -= OnRightClickPerformed; + if (m_RightClickAction.action != null) + m_RightClickAction.action.performed -= OnRightClickPerformed; - if (_scrollWheelAction.action != null) - _scrollWheelAction.action.performed -= OnScrollWheelPerformed; + if (m_ScrollWheelAction.action != null) + m_ScrollWheelAction.action.performed -= OnScrollWheelPerformed; - _pointAction = null; - _moveAction = null; - _submitAction = null; - _cancelAction = null; - _leftClickAction = null; - _middleClickAction = null; - _rightClickAction = null; - _scrollWheelAction = null; + m_PointAction = null; + m_MoveAction = null; + m_SubmitAction = null; + m_CancelAction = null; + m_LeftClickAction = null; + m_MiddleClickAction = null; + m_RightClickAction = null; + m_ScrollWheelAction = null; - _inputActionAsset.Disable(); + m_InputActionAsset.Disable(); // The Next/Previous action is not part of the input actions asset UnregisterNextPreviousAction(); - UnityEngine.Object.Destroy(_inputActionAsset); // TODO check if this is ok + UnityEngine.Object.Destroy(m_InputActionAsset); // TODO check if this is ok } public struct Configuration From e6c532baf784dd4379cd892f932c88e2882ebb4c Mon Sep 17 00:00:00 2001 From: James McGill Date: Mon, 22 May 2023 18:39:48 +0200 Subject: [PATCH 30/31] fix for running tests in standalone builds --- .../InputSystem/Plugins/InputForUI/InputSystemProvider.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index 0880fc8ea1..a2486eb22e 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -91,6 +91,14 @@ public void Shutdown() public void Update() { +#if UNITY_EDITOR + // Ensure we are in a good (initialized) state before running updates. + // This could be in a bad state for a duration while the build pipeline is running + // when building tests to run in the Standalone Player. + if (m_InputActionAsset == null) + return; +#endif + m_InputEventPartialProvider.Update(); m_Events.Sort(SortEvents); From 0ff50f6c963b4ee216d9a5b7f9fc2c33cfa257e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Freire?= Date: Tue, 23 May 2023 11:19:24 +0200 Subject: [PATCH 31/31] Remove commented code and add missing comment --- .../Plugins/InputForUI/InputSystemProvider.cs | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs index a2486eb22e..e385373951 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs @@ -101,6 +101,10 @@ public void Update() m_InputEventPartialProvider.Update(); + // Sort events added by input actions callbacks, based on type. + // This is necessary to ensure that events are dispatched in the correct order. + // If all events are of the PointerEvents type, sorting is based on reverse order of the EventSource enum. + // Touch -> Pen -> Mouse. m_Events.Sort(SortEvents); var currentTime = (DiscreteTime)Time.timeAsRational; @@ -109,8 +113,8 @@ public void Update() foreach (var ev in m_Events) { - // we need to ignore some pointer events based on priority (touch->pen->mouse) - // this is mostly used to filter out simulated input, e.g. when pen is active it also generates mouse input + // We need to ignore some pointer events based on priority (Touch->Pen->Mouse) + // This is mostly used to filter out simulated input, e.g. when pen is active it also generates mouse input if (m_SeenTouchEvents && ev.type == Event.Type.PointerEvent && ev.eventSource == EventSource.Pen) m_PenState.Reset(); else if ((m_SeenTouchEvents || m_SeenPenEvents) && @@ -254,8 +258,6 @@ public bool RequestCurrentState(Event.Type type) } // TODO case Event.Type.IMECompositionEvent: - //EventProvider.Dispatch(Event.From(ToIMECompositionEvent(currentTime, _compositionString))); - //return true; default: return false; } @@ -341,11 +343,12 @@ void DispatchFromCallback(in Event ev) static int FindTouchFingerIndex(Touchscreen touchscreen, InputAction.CallbackContext ctx) { + if (touchscreen == null) + return 0; + var asVector2Control = ctx.control is Vector2Control ? (Vector2Control)ctx.control : null; var asTouchPressControl = ctx.control is TouchPressControl ? (TouchPressControl)ctx.control : null; var asTouchControl = ctx.control is TouchControl ? (TouchControl)ctx.control : null; - if (touchscreen == null) - return 0; // Finds the index of the matching control type in the Touchscreen device lost of touch controls (touches) for (var i = 0; i < touchscreen.touches.Count; ++i) @@ -652,11 +655,6 @@ public struct Configuration public string MiddleClickAction; public string RightClickAction; public string ScrollWheelAction; - //public string TrackedDevicePositionAction; - //public string TrackedDeviceOrientationAction; - - // public float InputActionsPerSecond; - // public float RepeatDelay; public static Configuration GetDefaultConfiguration() { @@ -664,7 +662,6 @@ public static Configuration GetDefaultConfiguration() var asset = new DefaultInputActions(); var json = asset.asset.ToJson(); UnityEngine.Object.DestroyImmediate(asset.asset); // TODO just Dispose doesn't work in edit mode - // asset.Dispose(); return new Configuration { @@ -677,8 +674,6 @@ public static Configuration GetDefaultConfiguration() MiddleClickAction = "UI/MiddleClick", RightClickAction = "UI/RightClick", ScrollWheelAction = "UI/ScrollWheel", - // InputActionsPerSecond = 10, - // RepeatDelay = 0.5f, }; } }