123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- using System;
- using System.Diagnostics;
- using UnityEngine.InputSystem.LowLevel;
- #if UNITY_EDITOR
- using UnityEditor;
- #endif
-
- ////REVIEW: this *really* should be renamed to TouchPolling or something like that
-
- ////REVIEW: Should this auto-enable itself when the API is used? Problem with this is that it means the first touch inputs will get missed
- //// as by the time the API is polled, we're already into the first frame.
-
- ////TODO: gesture support
- ////TODO: high-frequency touch support
-
- ////REVIEW: have TouchTap, TouchSwipe, etc. wrapper MonoBehaviours like LeanTouch?
-
- ////TODO: as soon as we can break the API, remove the EnhancedTouchSupport class altogether and rename UnityEngine.InputSystem.EnhancedTouch to TouchPolling
-
- ////FIXME: does not survive domain reloads
-
- namespace UnityEngine.InputSystem.EnhancedTouch
- {
- /// <summary>
- /// API to control enhanced touch facilities like <see cref="Touch"/> that are not
- /// enabled by default.
- /// </summary>
- /// <remarks>
- /// Enhanced touch support provides automatic finger tracking and touch history recording.
- /// It is an API designed for polling, i.e. for querying touch state directly in methods
- /// such as <c>MonoBehaviour.Update</c>. Enhanced touch support cannot be used in combination
- /// with <see cref="InputAction"/>s though both can be used side-by-side.
- ///
- /// <example>
- /// <code>
- /// public class MyBehavior : MonoBehaviour
- /// {
- /// protected void OnEnable()
- /// {
- /// EnhancedTouchSupport.Enable();
- /// }
- ///
- /// protected void OnDisable()
- /// {
- /// EnhancedTouchSupport.Disable();
- /// }
- ///
- /// protected void Update()
- /// {
- /// var activeTouches = Touch.activeTouches;
- /// for (var i = 0; i < activeTouches.Count; ++i)
- /// Debug.Log("Active touch: " + activeTouches[i]);
- /// }
- /// }
- /// </code>
- /// </example>
- /// </remarks>
- /// <seealso cref="Touch"/>
- /// <seealso cref="Finger"/>
- public static class EnhancedTouchSupport
- {
- /// <summary>
- /// Whether enhanced touch support is currently enabled.
- /// </summary>
- /// <value>True if EnhancedTouch support has been enabled.</value>
- public static bool enabled => s_Enabled > 0;
-
- private static int s_Enabled;
- private static InputSettings.UpdateMode s_UpdateMode;
-
- /// <summary>
- /// Enable enhanced touch support.
- /// </summary>
- /// <remarks>
- /// Calling this method is necessary to enable the functionality provided
- /// by <see cref="Touch"/> and <see cref="Finger"/>. These APIs add extra
- /// processing to touches and are thus disabled by default.
- ///
- /// Calls to <c>Enable</c> and <see cref="Disable"/> balance each other out.
- /// If <c>Enable</c> is called repeatedly, it will take as many calls to
- /// <see cref="Disable"/> to disable the system again.
- /// </remarks>
- public static void Enable()
- {
- ++s_Enabled;
- if (s_Enabled > 1)
- return;
-
- InputSystem.onDeviceChange += OnDeviceChange;
- InputSystem.onBeforeUpdate += Touch.BeginUpdate;
- InputSystem.onSettingsChange += OnSettingsChange;
-
- #if UNITY_EDITOR
- AssemblyReloadEvents.beforeAssemblyReload += OnBeforeDomainReload;
- #endif
-
- SetUpState();
- }
-
- /// <summary>
- /// Disable enhanced touch support.
- /// </summary>
- /// <remarks>
- /// This method only undoes a single call to <see cref="Enable"/>.
- /// </remarks>
- public static void Disable()
- {
- if (!enabled)
- return;
- --s_Enabled;
- if (s_Enabled > 0)
- return;
-
- InputSystem.onDeviceChange -= OnDeviceChange;
- InputSystem.onBeforeUpdate -= Touch.BeginUpdate;
- InputSystem.onSettingsChange -= OnSettingsChange;
-
- #if UNITY_EDITOR
- AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeDomainReload;
- #endif
-
- TearDownState();
- }
-
- internal static void Reset()
- {
- Touch.s_GlobalState.touchscreens = default;
- Touch.s_GlobalState.playerState.Destroy();
- Touch.s_GlobalState.playerState = default;
- #if UNITY_EDITOR
- Touch.s_GlobalState.editorState.Destroy();
- Touch.s_GlobalState.editorState = default;
- #endif
- s_Enabled = 0;
- }
-
- private static void SetUpState()
- {
- Touch.s_GlobalState.playerState.updateMask = InputUpdateType.Dynamic | InputUpdateType.Manual | InputUpdateType.Fixed;
- #if UNITY_EDITOR
- Touch.s_GlobalState.editorState.updateMask = InputUpdateType.Editor;
- #endif
-
- s_UpdateMode = InputSystem.settings.updateMode;
-
- foreach (var device in InputSystem.devices)
- OnDeviceChange(device, InputDeviceChange.Added);
- }
-
- internal static void TearDownState()
- {
- foreach (var device in InputSystem.devices)
- OnDeviceChange(device, InputDeviceChange.Removed);
-
- Touch.s_GlobalState.playerState.Destroy();
- #if UNITY_EDITOR
- Touch.s_GlobalState.editorState.Destroy();
- #endif
-
- Touch.s_GlobalState.playerState = default;
- #if UNITY_EDITOR
- Touch.s_GlobalState.editorState = default;
- #endif
- }
-
- private static void OnDeviceChange(InputDevice device, InputDeviceChange change)
- {
- switch (change)
- {
- case InputDeviceChange.Added:
- {
- if (device is Touchscreen touchscreen)
- Touch.AddTouchscreen(touchscreen);
- break;
- }
-
- case InputDeviceChange.Removed:
- {
- if (device is Touchscreen touchscreen)
- Touch.RemoveTouchscreen(touchscreen);
- break;
- }
- }
- }
-
- private static void OnSettingsChange()
- {
- var currentUpdateMode = InputSystem.settings.updateMode;
- if (s_UpdateMode == currentUpdateMode)
- return;
- TearDownState();
- SetUpState();
- }
-
- #if UNITY_EDITOR
- private static void OnBeforeDomainReload()
- {
- // We need to release NativeArrays we're holding before losing track of them during domain reloads.
- Touch.s_GlobalState.playerState.Destroy();
- Touch.s_GlobalState.editorState.Destroy();
- }
-
- #endif
-
- [Conditional("DEVELOPMENT_BUILD")]
- [Conditional("UNITY_EDITOR")]
- internal static void CheckEnabled()
- {
- if (!enabled)
- throw new InvalidOperationException("EnhancedTouch API is not enabled; call EnhancedTouchSupport.Enable()");
- }
- }
- }
|