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}