using System; using Unity.Collections.LowLevel.Unsafe; using UnityEngine.InputSystem.Layouts; #if UNITY_EDITOR using UnityEditor; #endif ////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); /// /// Input functions that have to be performed by the underlying input runtime. /// /// /// 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 . /// internal unsafe interface IInputRuntime { /// /// Allocate a new unique device ID. /// /// A numeric device ID that is not . /// /// 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. /// int AllocateDeviceId(); /// /// Manually trigger an update. /// /// 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. /// /// Updates will flush out events and trigger and . /// Also, newly discovered devices will be reported by an update is run. /// void Update(InputUpdateType type); /// /// Queue an input event. /// /// /// This method has to be thread-safe. /// /// Pointer to the event data. Uses the format. /// /// Events are copied into an internal buffer. Thus the memory referenced by this method does /// not have to persist until the event is processed. /// 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. /// /// Perform an I/O transaction directly against a specific device. /// /// /// 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. /// /// Device to send the command to. /// Pointer to the command buffer. /// Negative value on failure, >=0 on success. Meaning of return values depends on the /// command sent to the device. long DeviceCommand(int deviceId, InputDeviceCommand* commandPtr); /// /// Set delegate to be called on input updates. /// InputUpdateDelegate onUpdate { get; set; } /// /// Set delegate to be called right before . /// /// /// This delegate is meant to allow events to be queued that should be processed right /// in the upcoming update. /// Action onBeforeUpdate { get; set; } Func onShouldRunUpdate { get; set; } #if UNITY_EDITOR /// /// Set delegate to be called during player loop initialization callbacks. /// Action onPlayerLoopInitialization { get; set; } #endif /// /// Set delegate to be called when a new device is discovered. /// /// /// 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 ). /// Action onDeviceDiscovered { get; set; } /// /// Set delegate to call when the application changes focus. /// /// Action onPlayerFocusChanged { get; set; } /// // Is true when the player or game view has focus. /// /// bool isPlayerFocused { get; } /// /// Set delegate to invoke when system is shutting down. /// Action onShutdown { get; set; } /// /// Set the background polling frequency for devices that have to be polled. /// /// /// The frequency is in Hz. A value of 60 means that polled devices get sampled /// 60 times a second. /// float pollingFrequency { get; set; } /// /// The current time on the same timeline that input events are delivered on. /// /// /// 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 . /// /// Input time, however, is offset in relation to . This is because /// in the player, is reset to 0 upon loading the first scene and /// in the editor, 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 . /// double currentTime { get; } /// /// The current time on the same timeline that input events are delivered on, for the current FixedUpdate. /// /// /// 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. /// double currentTimeForFixedUpdate { get; } /// /// The value of Time.unscaledTime. /// float unscaledGameTime { get; } /// /// The time offset that currently has to . /// double currentTimeOffsetToRealtimeSinceStartup { get; } bool runInBackground { get; set; } Vector2 screenSize { get; } ScreenOrientation screenOrientation { get; } // If analytics are enabled, the runtime receives analytics events from the input manager. // See InputAnalytics. #if UNITY_ANALYTICS || UNITY_EDITOR void RegisterAnalyticsEvent(string name, int maxPerHour, int maxPropertiesPerEvent); void SendAnalyticsEvent(string name, object data); #endif bool isInBatchMode { get; } #if UNITY_EDITOR Action onPlayModeChanged { get; set; } Action onProjectChange { get; set; } bool isInPlayMode { get; } bool isPaused { get; } bool isEditorActive { get; } // Functionality related to the Unity Remote. Func onUnityRemoteMessage { set; } void SetUnityRemoteGyroEnabled(bool value); void SetUnityRemoteGyroUpdateInterval(float interval); #endif } internal static class InputRuntime { public static IInputRuntime s_Instance; public static double s_CurrentTimeOffsetToRealtimeSinceStartup; } internal static class InputRuntimeExtensions { public static unsafe long DeviceCommand(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)); } } }