IInputStateCallbackReceiver.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // In retrospect, allowing Touchscreen to do what it does the way it does it was a mistake. It came out of thinking that
  2. // we need Touchscreen to have a large pool of TouchStates from which to dynamically allocate -- as this was what the old
  3. // input system does. This made it unfeasible/unwise to put the burden of touch allocation on platform backends and thus
  4. // led to the current setup where backends are sending TouchState events which Touchscreen dynamically incorporates.
  5. //
  6. // This shouldn't have happened.
  7. //
  8. // Ultimately, this led to IInputStateCallbackReceiver in its current form. While quite flexible in what it allows you to
  9. // do, it introduces a lot of additional complication and deviation from an otherwise very simple model based on trivially
  10. // understood chunks of input state.
  11. namespace UnityEngine.InputSystem.LowLevel
  12. {
  13. /// <summary>
  14. /// Interface for devices that implement their own state update handling.
  15. /// </summary>
  16. /// <remarks>
  17. /// The input system has built-in logic to automatically handle the state buffers that store input values for devices. This
  18. /// means that if an input event containing input state is processed, its data will be copied automatically into the state
  19. /// memory for the device.
  20. ///
  21. /// However, some devices need to apply custom logic whenever new input is received. An example of this is <see cref="Pointer.delta"/>
  22. /// which needs to accumulate deltas as they are received within a frame and then reset the delta at the beginning of a new frame.
  23. ///
  24. /// Also, devices like <see cref="Touchscreen"/> extensively customize event handling in order to implement features such as
  25. /// tap detection and primary touch handling. This is what allows the device to receive state events in <see cref="TouchState"/>
  26. /// format even though that is not the format of the device itself (which is mainly a composite of several TouchStates).
  27. ///
  28. /// This interface allows to bypass the built-in logic and instead intercept and manually handle state updates.
  29. /// </remarks>
  30. /// <seealso cref="InputDevice"/>
  31. /// <seealso cref="Pointer"/>
  32. /// <seealso cref="Touchscreen"/>
  33. public interface IInputStateCallbackReceiver
  34. {
  35. /// <summary>
  36. /// A new input update begins. This means that the current state of the device is being carried over into the next
  37. /// frame.
  38. /// </summary>
  39. /// <remarks>
  40. /// This is called without the front and back buffer for the device having been flipped. You can use <see cref="InputState.Change"/>
  41. /// to write values into the device's state (e.g. to reset a given control to its default state) which will implicitly perform
  42. /// the buffer flip.
  43. /// </remarks>
  44. void OnNextUpdate();
  45. /// <summary>
  46. /// A new state event has been received and is being processed.
  47. /// </summary>
  48. /// <param name="eventPtr">The state event. This will be either a <see cref="StateEvent"/> or a <see cref="DeltaStateEvent"/>.</param>
  49. /// <remarks>
  50. /// Use <see cref="InputState.Change"/> to write state updates into the device state buffers. While nothing will prevent a device
  51. /// from writing directly into the memory buffers retrieved with <see cref="InputControl.currentStatePtr"/>, doing so will bypass
  52. /// the buffer flipping logic as well as change detection from change monitors (<see cref="IInputStateChangeMonitor"/>; this will
  53. /// cause <see cref="InputAction"/> to not work with the device) and thus lead to incorrect behavior.
  54. /// </remarks>
  55. /// <seealso cref="StateEvent"/>
  56. /// <seealso cref="DeltaStateEvent"/>
  57. void OnStateEvent(InputEventPtr eventPtr);
  58. /// <summary>
  59. /// Compute an offset that correlates <paramref name="control"/> with the state in <paramref name="eventPtr"/>.
  60. /// </summary>
  61. /// <param name="control">Control the state of which we want to access within <paramref name="eventPtr"/>.</param>
  62. /// <param name="eventPtr">An input event. Must be a <see cref="StateEvent"/> or <see cref="DeltaStateEvent"/></param>
  63. /// <param name="offset"></param>
  64. /// <returns>False if the correlation failed or true if <paramref name="offset"/> has been set and should be used
  65. /// as the offset for the state of <paramref name="control"/>.</returns>
  66. /// <remarks>
  67. /// This method will only be called if the given state event has a state format different than that of the device. In that case,
  68. /// the memory of the input state captured in the given state event cannot be trivially correlated with the control.
  69. ///
  70. /// The input system calls the method to know which offset (if any) in the device's state block to consider the state
  71. /// in <paramref name="eventPtr"/> relative to when accessing the state for <paramref name="control"/> as found in
  72. /// the event.
  73. ///
  74. /// An example of when this is called is for touch events. These are normally sent in <see cref="TouchState"/> format
  75. /// which, however, is not the state format of <see cref="Touchscreen"/> (which uses a composite of several TouchStates).
  76. /// When trying to access the state in <paramref name="eventPtr"/> to, for example, read out the touch position,
  77. /// </remarks>
  78. /// <seealso cref="InputControlExtensions.GetStatePtrFromStateEvent"/>
  79. bool GetStateOffsetForEvent(InputControl control, InputEventPtr eventPtr, ref uint offset);
  80. }
  81. }