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