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