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(); }
}
}
}