| using Unity.Collections; |
| using Unity.Collections.LowLevel.Unsafe; |
|
|
| namespace UnityEngine.InputSystem.LowLevel |
| { |
| |
| |
| |
| |
| |
| |
| |
| internal unsafe struct InputEventStream |
| { |
| public bool isOpen => m_IsOpen; |
|
|
| public int remainingEventCount => m_RemainingNativeEventCount + m_RemainingAppendEventCount; |
|
|
| |
| |
| |
| public int numEventsRetainedInBuffer => m_NumEventsRetainedInBuffer; |
|
|
| public InputEvent* currentEventPtr => m_RemainingNativeEventCount > 0 |
| ? m_CurrentNativeEventReadPtr |
| : (m_RemainingAppendEventCount > 0 ? m_CurrentAppendEventReadPtr : null); |
|
|
| public uint numBytesRetainedInBuffer => |
| (uint)((byte*)m_CurrentNativeEventWritePtr - |
| (byte*)NativeArrayUnsafeUtility |
| .GetUnsafeBufferPointerWithoutChecks(m_NativeBuffer.data)); |
|
|
| public InputEventStream(ref InputEventBuffer eventBuffer, int maxAppendedEvents) |
| { |
| m_CurrentNativeEventWritePtr = m_CurrentNativeEventReadPtr = |
| (InputEvent*)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(eventBuffer.data); |
|
|
| m_NativeBuffer = eventBuffer; |
| m_RemainingNativeEventCount = m_NativeBuffer.eventCount; |
| m_NumEventsRetainedInBuffer = 0; |
|
|
| m_CurrentAppendEventReadPtr = m_CurrentAppendEventWritePtr = default; |
| m_AppendBuffer = default; |
| m_RemainingAppendEventCount = 0; |
| m_MaxAppendedEvents = maxAppendedEvents; |
|
|
| m_IsOpen = true; |
| } |
|
|
| public void Close(ref InputEventBuffer eventBuffer) |
| { |
| |
| if (m_NumEventsRetainedInBuffer > 0) |
| { |
| var bufferPtr = NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(m_NativeBuffer.data); |
| Debug.Assert((byte*)m_CurrentNativeEventWritePtr > (byte*)bufferPtr); |
| var newBufferSize = (byte*)m_CurrentNativeEventWritePtr - (byte*)bufferPtr; |
| m_NativeBuffer = new InputEventBuffer((InputEvent*)bufferPtr, m_NumEventsRetainedInBuffer, (int)newBufferSize, |
| (int)m_NativeBuffer.capacityInBytes); |
| } |
| else |
| { |
| m_NativeBuffer.Reset(); |
| } |
|
|
| if (m_AppendBuffer.data.IsCreated) |
| m_AppendBuffer.Dispose(); |
|
|
| eventBuffer = m_NativeBuffer; |
| m_IsOpen = false; |
| } |
|
|
| public void CleanUpAfterException() |
| { |
| if (!isOpen) |
| return; |
|
|
| m_NativeBuffer.Reset(); |
|
|
| if (m_AppendBuffer.data.IsCreated) |
| m_AppendBuffer.Dispose(); |
|
|
| m_IsOpen = false; |
| } |
|
|
| public void Write(InputEvent* eventPtr) |
| { |
| if (m_AppendBuffer.eventCount >= m_MaxAppendedEvents) |
| { |
| Debug.LogError($"Maximum number of queued events exceeded. Set the '{nameof(InputSettings.maxQueuedEventsPerUpdate)}' " + |
| $"setting to a higher value if you need to queue more events than this. " + |
| $"Current limit is '{m_MaxAppendedEvents}'."); |
| return; |
| } |
|
|
| var wasAlreadyCreated = m_AppendBuffer.data.IsCreated; |
| var oldBufferPtr = (byte*)m_AppendBuffer.bufferPtr.data; |
|
|
| m_AppendBuffer.AppendEvent(eventPtr, allocator: Allocator.Temp); |
|
|
| if (!wasAlreadyCreated) |
| { |
| m_CurrentAppendEventWritePtr = m_CurrentAppendEventReadPtr = |
| (InputEvent*)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(m_AppendBuffer.data); |
| } |
| else |
| { |
| |
| |
| var newBufferPtr = (byte*)m_AppendBuffer.bufferPtr.data; |
| if (oldBufferPtr != newBufferPtr) |
| { |
| var currentWriteOffset = (byte*)m_CurrentAppendEventWritePtr - oldBufferPtr; |
| var currentReadOffset = (byte*)m_CurrentAppendEventReadPtr - oldBufferPtr; |
| m_CurrentAppendEventWritePtr = (InputEvent*)(newBufferPtr + currentWriteOffset); |
| m_CurrentAppendEventReadPtr = (InputEvent*)(newBufferPtr + currentReadOffset); |
| } |
| } |
|
|
| m_RemainingAppendEventCount++; |
| } |
|
|
| public InputEvent* Advance(bool leaveEventInBuffer) |
| { |
| if (m_RemainingNativeEventCount > 0) |
| { |
| m_NativeBuffer.AdvanceToNextEvent(ref m_CurrentNativeEventReadPtr, ref m_CurrentNativeEventWritePtr, |
| ref m_NumEventsRetainedInBuffer, ref m_RemainingNativeEventCount, leaveEventInBuffer); |
| } |
| else if (m_RemainingAppendEventCount > 0) |
| { |
| var numEventRetained = 0; |
| m_AppendBuffer.AdvanceToNextEvent(ref m_CurrentAppendEventReadPtr, ref m_CurrentAppendEventWritePtr, |
| ref numEventRetained, ref m_RemainingAppendEventCount, false); |
| } |
|
|
| return currentEventPtr; |
| } |
|
|
| |
| |
| |
| public InputEvent* Peek() |
| { |
| |
| if (m_RemainingNativeEventCount > 1) |
| return InputEvent.GetNextInMemory(m_CurrentNativeEventReadPtr); |
|
|
| |
| |
| if (m_RemainingNativeEventCount == 1) |
| return m_RemainingAppendEventCount > 0 ? m_CurrentAppendEventReadPtr : null; |
|
|
| |
| if (m_RemainingAppendEventCount > 1) |
| return InputEvent.GetNextInMemory(m_CurrentAppendEventReadPtr); |
|
|
| |
| return null; |
| } |
|
|
| private InputEventBuffer m_NativeBuffer; |
| private InputEvent* m_CurrentNativeEventReadPtr; |
| private InputEvent* m_CurrentNativeEventWritePtr; |
| private int m_RemainingNativeEventCount; |
| private readonly int m_MaxAppendedEvents; |
|
|
| |
| private InputEventBuffer m_AppendBuffer; |
| private InputEvent* m_CurrentAppendEventReadPtr; |
| private InputEvent* m_CurrentAppendEventWritePtr; |
| private int m_RemainingAppendEventCount; |
|
|
| |
| |
| |
| |
| private int m_NumEventsRetainedInBuffer; |
| private bool m_IsOpen; |
| } |
| } |
|
|