IInputRuntime.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. using System;
  2. using Unity.Collections.LowLevel.Unsafe;
  3. using UnityEngine.InputSystem.Layouts;
  4. #if UNITY_EDITOR
  5. using UnityEditor;
  6. #endif
  7. ////TODO: add API to send events in bulk rather than one by one
  8. namespace UnityEngine.InputSystem.LowLevel
  9. {
  10. internal delegate void InputUpdateDelegate(InputUpdateType updateType, ref InputEventBuffer eventBuffer);
  11. /// <summary>
  12. /// Input functions that have to be performed by the underlying input runtime.
  13. /// </summary>
  14. /// <remarks>
  15. /// The runtime owns the input event queue, reports device discoveries, and runs
  16. /// periodic updates that flushes out events from the queue. Updates can also be manually
  17. /// triggered by calling <see cref="Update"/>.
  18. /// </remarks>
  19. internal unsafe interface IInputRuntime
  20. {
  21. /// <summary>
  22. /// Allocate a new unique device ID.
  23. /// </summary>
  24. /// <returns>A numeric device ID that is not <see cref="InputDevice.InvalidDeviceId"/>.</returns>
  25. /// <remarks>
  26. /// Device IDs are managed by the runtime. This method allows creating devices that
  27. /// can use the same ID system but are not known to the underlying runtime.
  28. /// </remarks>
  29. int AllocateDeviceId();
  30. /// <summary>
  31. /// Manually trigger an update.
  32. /// </summary>
  33. /// <param name="type">Type of update to run. If this is a combination of updates, each flag
  34. /// that is set in the mask will run a separate update.</param>
  35. /// <remarks>
  36. /// Updates will flush out events and trigger <see cref="onBeforeUpdate"/> and <see cref="onUpdate"/>.
  37. /// Also, newly discovered devices will be reported by an update is run.
  38. /// </remarks>
  39. void Update(InputUpdateType type);
  40. /// <summary>
  41. /// Queue an input event.
  42. /// </summary>
  43. /// <remarks>
  44. /// This method has to be thread-safe.
  45. /// </remarks>
  46. /// <param name="ptr">Pointer to the event data. Uses the <see cref="InputEvent"/> format.</param>
  47. /// <remarks>
  48. /// Events are copied into an internal buffer. Thus the memory referenced by this method does
  49. /// not have to persist until the event is processed.
  50. /// </remarks>
  51. void QueueEvent(InputEvent* ptr);
  52. //NOTE: This method takes an IntPtr instead of a generic ref type parameter (like InputDevice.ExecuteCommand)
  53. // to avoid issues with AOT where generic interface methods can lead to problems. Il2cpp can handle it here
  54. // just fine but Mono will run into issues.
  55. /// <summary>
  56. /// Perform an I/O transaction directly against a specific device.
  57. /// </summary>
  58. /// <remarks>
  59. /// This function is used to set up device-specific communication controls between
  60. /// a device and the user of a device. The interface does not dictate a set of supported
  61. /// IOCTL control codes.
  62. /// </remarks>
  63. /// <param name="deviceId">Device to send the command to.</param>
  64. /// <param name="commandPtr">Pointer to the command buffer.</param>
  65. /// <returns>Negative value on failure, >=0 on success. Meaning of return values depends on the
  66. /// command sent to the device.</returns>
  67. long DeviceCommand(int deviceId, InputDeviceCommand* commandPtr);
  68. /// <summary>
  69. /// Set delegate to be called on input updates.
  70. /// </summary>
  71. InputUpdateDelegate onUpdate { get; set; }
  72. /// <summary>
  73. /// Set delegate to be called right before <see cref="onUpdate"/>.
  74. /// </summary>
  75. /// <remarks>
  76. /// This delegate is meant to allow events to be queued that should be processed right
  77. /// in the upcoming update.
  78. /// </remarks>
  79. Action<InputUpdateType> onBeforeUpdate { get; set; }
  80. Func<InputUpdateType, bool> onShouldRunUpdate { get; set; }
  81. /// <summary>
  82. /// Set delegate to be called when a new device is discovered.
  83. /// </summary>
  84. /// <remarks>
  85. /// The runtime should delay reporting of already present devices until the delegate
  86. /// has been put in place and then call the delegate for every device already in the system.
  87. ///
  88. /// First parameter is the ID assigned to the device, second parameter is a description
  89. /// in JSON format of the device (see <see cref="InputDeviceDescription.FromJson"/>).
  90. /// </remarks>
  91. Action<int, string> onDeviceDiscovered { get; set; }
  92. /// <summary>
  93. /// Set delegate to call when the application changes focus.
  94. /// </summary>
  95. /// <seealso cref="Application.onFocusChanged"/>
  96. Action<bool> onPlayerFocusChanged { get; set; }
  97. /// <summary>
  98. /// Set delegate to invoke when system is shutting down.
  99. /// </summary>
  100. Action onShutdown { get; set; }
  101. /// <summary>
  102. /// Set the background polling frequency for devices that have to be polled.
  103. /// </summary>
  104. /// <remarks>
  105. /// The frequency is in Hz. A value of 60 means that polled devices get sampled
  106. /// 60 times a second.
  107. /// </remarks>
  108. float pollingFrequency { get; set; }
  109. /// <summary>
  110. /// The current time on the same timeline that input events are delivered on.
  111. /// </summary>
  112. /// <remarks>
  113. /// This is used to timestamp events that are not explicitly supplied with timestamps.
  114. ///
  115. /// Time in the input system progresses linearly and in real-time and relates to when Unity was started.
  116. /// In the editor, this always corresponds to <see cref="EditorApplication.timeSinceStartup"/>.
  117. ///
  118. /// Input time, however, is offset in relation to <see cref="Time.realtimeSinceStartup"/>. This is because
  119. /// in the player, <see cref="Time.realtimeSinceStartup"/> is reset to 0 upon loading the first scene and
  120. /// in the editor, <see cref="Time.realtimeSinceStartup"/> is reset to 0 whenever the editor enters play
  121. /// mode. As the resetting runs counter to the need of linearly progressing time for input, the input
  122. /// system will not reset time along with <see cref="Time.realtimeSinceStartup"/>.
  123. /// </remarks>
  124. double currentTime { get; }
  125. /// <summary>
  126. /// The current time on the same timeline that input events are delivered on, for the current FixedUpdate.
  127. /// </summary>
  128. /// <remarks>
  129. /// This should be used inside FixedUpdate calls instead of currentTime, as FixedUpdates are simulated at times
  130. /// not matching the real time the simulation corresponds to.
  131. /// </remarks>
  132. double currentTimeForFixedUpdate { get; }
  133. /// <summary>
  134. /// The value of <c>Time.unscaledTime</c>.
  135. /// </summary>
  136. float unscaledGameTime { get; }
  137. /// <summary>
  138. /// The time offset that <see cref="currentTime"/> currently has to <see cref="Time.realtimeSinceStartup"/>.
  139. /// </summary>
  140. double currentTimeOffsetToRealtimeSinceStartup { get; }
  141. bool runInBackground { get; }
  142. ScreenOrientation screenOrientation { get; }
  143. // If analytics are enabled, the runtime receives analytics events from the input manager.
  144. // See InputAnalytics.
  145. #if UNITY_ANALYTICS || UNITY_EDITOR
  146. void RegisterAnalyticsEvent(string name, int maxPerHour, int maxPropertiesPerEvent);
  147. void SendAnalyticsEvent(string name, object data);
  148. #endif
  149. bool isInBatchMode { get; }
  150. #if UNITY_EDITOR
  151. Action<PlayModeStateChange> onPlayModeChanged { get; set; }
  152. Action onProjectChange { get; set; }
  153. bool isInPlayMode { get; }
  154. bool isPaused { get; }
  155. #endif
  156. }
  157. internal static class InputRuntime
  158. {
  159. public static IInputRuntime s_Instance;
  160. public static double s_CurrentTimeOffsetToRealtimeSinceStartup;
  161. }
  162. internal static class InputRuntimeExtensions
  163. {
  164. public static unsafe long DeviceCommand<TCommand>(this IInputRuntime runtime, int deviceId, ref TCommand command)
  165. where TCommand : struct, IInputDeviceCommandInfo
  166. {
  167. if (runtime == null)
  168. throw new ArgumentNullException(nameof(runtime));
  169. return runtime.DeviceCommand(deviceId, (InputDeviceCommand*)UnsafeUtility.AddressOf(ref command));
  170. }
  171. }
  172. }