暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

DeltaStateEvent.cs 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using Unity.Collections;
  4. using Unity.Collections.LowLevel.Unsafe;
  5. using UnityEngine.InputSystem.Utilities;
  6. namespace UnityEngine.InputSystem.LowLevel
  7. {
  8. /// <summary>
  9. /// Partial state update for an input device.
  10. /// </summary>
  11. /// <remarks>
  12. /// Avoids having to send a full state memory snapshot when only a small
  13. /// part of the state has changed.
  14. /// </remarks>
  15. [StructLayout(LayoutKind.Explicit, Pack = 1, Size = InputEvent.kBaseEventSize + 9)]
  16. public unsafe struct DeltaStateEvent : IInputEventTypeInfo
  17. {
  18. public const int Type = 0x444C5441; // 'DLTA'
  19. [FieldOffset(0)]
  20. public InputEvent baseEvent;
  21. [FieldOffset(InputEvent.kBaseEventSize)]
  22. public FourCC stateFormat;
  23. [FieldOffset(InputEvent.kBaseEventSize + 4)]
  24. public uint stateOffset;
  25. [FieldOffset(InputEvent.kBaseEventSize + 8)]
  26. internal fixed byte stateData[1]; // Variable-sized.
  27. public uint deltaStateSizeInBytes => baseEvent.sizeInBytes - (InputEvent.kBaseEventSize + 8);
  28. public void* deltaState
  29. {
  30. get
  31. {
  32. fixed(byte* data = stateData)
  33. {
  34. return data;
  35. }
  36. }
  37. }
  38. public FourCC typeStatic => Type;
  39. public InputEventPtr ToEventPtr()
  40. {
  41. fixed(DeltaStateEvent * ptr = &this)
  42. {
  43. return new InputEventPtr((InputEvent*)ptr);
  44. }
  45. }
  46. public static DeltaStateEvent* From(InputEventPtr ptr)
  47. {
  48. if (!ptr.valid)
  49. throw new ArgumentNullException(nameof(ptr));
  50. if (!ptr.IsA<DeltaStateEvent>())
  51. throw new InvalidCastException($"Cannot cast event with type '{ptr.type}' into DeltaStateEvent");
  52. return FromUnchecked(ptr);
  53. }
  54. internal static DeltaStateEvent* FromUnchecked(InputEventPtr ptr)
  55. {
  56. return (DeltaStateEvent*)ptr.data;
  57. }
  58. public static NativeArray<byte> From(InputControl control, out InputEventPtr eventPtr, Allocator allocator = Allocator.Temp)
  59. {
  60. if (control == null)
  61. throw new ArgumentNullException(nameof(control));
  62. var device = control.device;
  63. if (!device.added)
  64. throw new ArgumentException($"Device for control '{control}' has not been added to system",
  65. nameof(control));
  66. ref var deviceStateBlock = ref device.m_StateBlock;
  67. ref var controlStateBlock = ref control.m_StateBlock;
  68. var stateFormat = deviceStateBlock.format; // The event is sent against the *device* so that's the state format we use.
  69. var stateSize = 0u;
  70. if (controlStateBlock.bitOffset != 0)
  71. stateSize = (controlStateBlock.bitOffset + controlStateBlock.sizeInBits + 7) / 8;
  72. else
  73. stateSize = controlStateBlock.alignedSizeInBytes;
  74. var stateOffset = controlStateBlock.byteOffset;
  75. var statePtr = (byte*)control.currentStatePtr + (int)stateOffset;
  76. var eventSize = InputEvent.kBaseEventSize + sizeof(int) * 2 + stateSize;
  77. var buffer = new NativeArray<byte>((int)eventSize.AlignToMultipleOf(4), allocator);
  78. var stateEventPtr = (DeltaStateEvent*)buffer.GetUnsafePtr();
  79. stateEventPtr->baseEvent = new InputEvent(Type, (int)eventSize, device.deviceId, InputRuntime.s_Instance.currentTime);
  80. stateEventPtr->stateFormat = stateFormat;
  81. stateEventPtr->stateOffset = controlStateBlock.byteOffset - deviceStateBlock.byteOffset; // Make offset relative to device.
  82. UnsafeUtility.MemCpy(stateEventPtr->deltaState, statePtr, stateSize);
  83. eventPtr = stateEventPtr->ToEventPtr();
  84. return buffer;
  85. }
  86. }
  87. }