using System.Runtime.InteropServices; using UnityEngine.InputSystem.Utilities; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; namespace UnityEngine.InputSystem.LowLevel { ////REVIEW: why is this passing the command by pointer instead of by ref? /// /// Delegate used by . /// public unsafe delegate long? InputDeviceCommandDelegate(InputDevice device, InputDeviceCommand* command); /// /// Delegate for executing s inside . /// /// Command to execute. /// /// public delegate long InputDeviceExecuteCommandDelegate(ref InputDeviceCommand command); /// /// Data header for a command send to an . /// /// /// Commands are essentially synchronously processed events send directly /// to a specific device. Their primary use is to expose device-specific /// functions without having to extend the C# API used to communicate /// between input code and backend device implementations (which may sit /// in native code). /// /// Like input events, device commands use codes /// to indicate their type. /// [StructLayout(LayoutKind.Explicit, Size = kBaseCommandSize)] public struct InputDeviceCommand : IInputDeviceCommandInfo { ////TODO: Remove kBaseCommandSize internal const int kBaseCommandSize = 8; public const int BaseCommandSize = 8; /// /// Generic failure code for calls. /// /// /// Any negative return value for an call should be considered failure. /// public const long GenericFailure = -1; public const long GenericSuccess = 1; [FieldOffset(0)] public FourCC type; [FieldOffset(4)] public int sizeInBytes; public int payloadSizeInBytes => sizeInBytes - kBaseCommandSize; public unsafe void* payloadPtr { get { fixed(void* thisPtr = &this) { return ((byte*)thisPtr) + kBaseCommandSize; } } } public InputDeviceCommand(FourCC type, int sizeInBytes = kBaseCommandSize) { this.type = type; this.sizeInBytes = sizeInBytes; } public static unsafe NativeArray AllocateNative(FourCC type, int payloadSize) { var sizeInBytes = payloadSize + kBaseCommandSize; var buffer = new NativeArray(sizeInBytes, Allocator.Temp); var commandPtr = (InputDeviceCommand*)NativeArrayUnsafeUtility.GetUnsafePtr(buffer); commandPtr->type = type; commandPtr->sizeInBytes = sizeInBytes; return buffer; } public FourCC typeStatic { get { return new FourCC(); } } } }