A game about forced loneliness, made by TACStudios
1using System.Runtime.InteropServices; 2using UnityEngine.InputSystem.Utilities; 3using Unity.Collections; 4using Unity.Collections.LowLevel.Unsafe; 5 6namespace UnityEngine.InputSystem.LowLevel 7{ 8 ////REVIEW: why is this passing the command by pointer instead of by ref? 9 /// <summary> 10 /// Delegate used by <see cref="InputSystem.onDeviceCommand"/>. 11 /// </summary> 12 public unsafe delegate long? InputDeviceCommandDelegate(InputDevice device, InputDeviceCommand* command); 13 14 /// <summary> 15 /// Delegate for executing <see cref="InputDeviceCommand"/>s inside <see cref="InputSystem.onFindLayoutForDevice"/>. 16 /// </summary> 17 /// <param name="command">Command to execute.</param> 18 /// <seealso cref="InputSystem.onFindLayoutForDevice"/> 19 /// <seealso cref="Layouts.InputDeviceFindControlLayoutDelegate"/> 20 public delegate long InputDeviceExecuteCommandDelegate(ref InputDeviceCommand command); 21 22 /// <summary> 23 /// Data header for a command send to an <see cref="InputDevice"/>. 24 /// </summary> 25 /// <remarks> 26 /// Commands are essentially synchronously processed events send directly 27 /// to a specific device. Their primary use is to expose device-specific 28 /// functions without having to extend the C# API used to communicate 29 /// between input code and backend device implementations (which may sit 30 /// in native code). 31 /// 32 /// Like input events, device commands use <see cref="FourCC"/> codes 33 /// to indicate their type. 34 /// </remarks> 35 [StructLayout(LayoutKind.Explicit, Size = kBaseCommandSize)] 36 public struct InputDeviceCommand : IInputDeviceCommandInfo 37 { 38 ////TODO: Remove kBaseCommandSize 39 internal const int kBaseCommandSize = 8; 40 public const int BaseCommandSize = 8; 41 42 /// <summary> 43 /// Generic failure code for <see cref="InputDevice.ExecuteCommand{TCommand}"/> calls. 44 /// </summary> 45 /// <remarks> 46 /// Any negative return value for an <see cref="InputDevice.ExecuteCommand{TCommand}"/> call should be considered failure. 47 /// </remarks> 48 public const long GenericFailure = -1; 49 50 public const long GenericSuccess = 1; 51 52 [FieldOffset(0)] public FourCC type; 53 [FieldOffset(4)] public int sizeInBytes; 54 55 public int payloadSizeInBytes => sizeInBytes - kBaseCommandSize; 56 57 public unsafe void* payloadPtr 58 { 59 get 60 { 61 fixed(void* thisPtr = &this) 62 { 63 return ((byte*)thisPtr) + kBaseCommandSize; 64 } 65 } 66 } 67 68 public InputDeviceCommand(FourCC type, int sizeInBytes = kBaseCommandSize) 69 { 70 this.type = type; 71 this.sizeInBytes = sizeInBytes; 72 } 73 74 public static unsafe NativeArray<byte> AllocateNative(FourCC type, int payloadSize) 75 { 76 var sizeInBytes = payloadSize + kBaseCommandSize; 77 var buffer = new NativeArray<byte>(sizeInBytes, Allocator.Temp); 78 79 var commandPtr = (InputDeviceCommand*)NativeArrayUnsafeUtility.GetUnsafePtr(buffer); 80 commandPtr->type = type; 81 commandPtr->sizeInBytes = sizeInBytes; 82 83 return buffer; 84 } 85 86 public FourCC typeStatic 87 { 88 get { return new FourCC(); } 89 } 90 } 91}