BsInput.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "BsModule.h"
  6. #include "BsOSInputHandler.h"
  7. #include "BsRawInputHandler.h"
  8. #include "BsInputFwd.h"
  9. namespace bs
  10. {
  11. /** @addtogroup Input
  12. * @{
  13. */
  14. /**
  15. * Primary module used for dealing with input. Allows you to receieve and query raw or OS input for
  16. * mouse/keyboard/gamepad.
  17. *
  18. * All inputs are received through an input handler, which can be overriden to provide custom input functionality.
  19. */
  20. class BS_CORE_EXPORT Input : public Module<Input>
  21. {
  22. /** Possible button states. */
  23. enum class ButtonState
  24. {
  25. Off, /**< Button is not being pressed. */
  26. On, /**< Button is being pressed. */
  27. ToggledOn, /**< Button has been pressed this frame. */
  28. ToggledOff, /**< Button has been released this frame. */
  29. ToggledOnOff, /**< Button has been pressed and released this frame. */
  30. };
  31. /** Contains axis and device data per device. */
  32. struct DeviceData
  33. {
  34. DeviceData();
  35. Vector<RawAxisState> axes;
  36. ButtonState keyStates[BC_Count];
  37. };
  38. /** Different types of possible input event callbacks. */
  39. enum class EventType
  40. {
  41. ButtonUp, ButtonDown, PointerMoved, PointerUp, PointerDown, PointerDoubleClick, TextInput, Command
  42. };
  43. /** Stores information about a queued input event that is to be triggered later. */
  44. struct QueuedEvent
  45. {
  46. QueuedEvent(EventType type, UINT32 idx)
  47. :type(type), idx(idx)
  48. { }
  49. EventType type;
  50. UINT32 idx;
  51. };
  52. public:
  53. Input();
  54. ~Input();
  55. /**
  56. * Returns value of the specified input axis. Normally in range [-1.0, 1.0] but can be outside the range for
  57. * devices with unbound axes (for example mouse).
  58. *
  59. * @param[in] type Type of axis to query. Usually a type from InputAxis but can be a custom value.
  60. * @param[in] deviceIdx Index of the device in case more than one is hooked up (0 - primary).
  61. */
  62. float getAxisValue(UINT32 type, UINT32 deviceIdx = 0) const;
  63. /**
  64. * Query if the provided button is currently being held (this frame or previous frames).
  65. *
  66. * @param[in] keyCode Code of the button to query.
  67. * @param[in] deviceIdx Device to query the button on (0 - primary).
  68. */
  69. bool isButtonHeld(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
  70. /**
  71. * Query if the provided button is currently being released (only true for one frame).
  72. *
  73. * @param[in] keyCode Code of the button to query.
  74. * @param[in] deviceIdx Device to query the button on (0 - primary).
  75. */
  76. bool isButtonUp(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
  77. /**
  78. * Query if the provided button is currently being pressed (only true for one frame).
  79. *
  80. * @param[in] keyCode Code of the button to query.
  81. * @param[in] deviceIdx Device to query the button on (0 - primary).
  82. */
  83. bool isButtonDown(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
  84. /** Returns position of the pointer (for example mouse cursor) relative to the screen. */
  85. Vector2I getPointerPosition() const;
  86. /** Returns difference between pointer position between current and last frame. */
  87. Vector2I getPointerDelta() const { return mPointerDelta; }
  88. /**
  89. * Query if the provided pointer button is currently being held (this frame or previous frames).
  90. *
  91. * @param[in] pointerButton Code of the button to query.
  92. */
  93. bool isPointerButtonHeld(PointerEventButton pointerButton) const;
  94. /**
  95. * Query if the provided pointer button is currently being released (only true for one frame).
  96. *
  97. * @param[in] pointerButton Code of the button to query.
  98. */
  99. bool isPointerButtonUp(PointerEventButton pointerButton) const;
  100. /**
  101. * Query if the provided pointer button is currently being pressed (only true for one frame).
  102. *
  103. * @param[in] pointerButton Code of the button to query.
  104. */
  105. bool isPointerButtonDown(PointerEventButton pointerButton) const;
  106. /** Query has the left pointer button has been double-clicked this frame. */
  107. bool isPointerDoubleClicked() const;
  108. /** Enables or disables mouse smoothing. Smoothing makes the changes to mouse axes more gradual. */
  109. void setMouseSmoothing(bool enabled);
  110. /** Triggered whenever a button is first pressed. */
  111. Event<void(const ButtonEvent&)> onButtonDown;
  112. /** Triggered whenever a button is first released. */
  113. Event<void(const ButtonEvent&)> onButtonUp;
  114. /** Triggered whenever user inputs a text character. */
  115. Event<void(const TextInputEvent&)> onCharInput;
  116. /** Triggers when some pointing device (mouse cursor, touch) moves. */
  117. Event<void(const PointerEvent&)> onPointerMoved;
  118. /** Triggers when some pointing device (mouse cursor, touch) button is pressed. */
  119. Event<void(const PointerEvent&)> onPointerPressed;
  120. /** Triggers when some pointing device (mouse cursor, touch) button is released. */
  121. Event<void(const PointerEvent&)> onPointerReleased;
  122. /** Triggers when some pointing device (mouse cursor, touch) button is double clicked. */
  123. Event<void(const PointerEvent&)> onPointerDoubleClick;
  124. // TODO Low priority: Remove this, I can emulate it using virtual input
  125. /** Triggers on special input commands. */
  126. Event<void(InputCommandType)> onInputCommand;
  127. public: // ***** INTERNAL ******
  128. /** @name Internal
  129. * @{
  130. */
  131. /** Registers a new input handler. Replaces any previous input handler. */
  132. void _registerRawInputHandler(SPtr<RawInputHandler> inputHandler);
  133. /**
  134. * Called every frame. Detects button state changes and prepares callback events to trigger via a call to
  135. * _triggerCallbacks().
  136. */
  137. void _update();
  138. /** Triggers any queued input event callbacks. */
  139. void _triggerCallbacks();
  140. /** @} */
  141. private:
  142. /** Triggered by input handler when a button is pressed. */
  143. void buttonDown(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
  144. /** Triggered by input handler when a button is released. */
  145. void buttonUp(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
  146. /** Triggered by input handler when a single character is input. */
  147. void charInput(UINT32 chr);
  148. /** Triggered by input handler when a mouse/joystick axis is moved. */
  149. void axisMoved(UINT32 deviceIdx, const RawAxisState& state, UINT32 axis);
  150. /** Cursor movement as OS reports it. Used for screen cursor position. */
  151. void cursorMoved(const PointerEvent& event);
  152. /** Cursor button presses as OS reports it. */
  153. void cursorPressed(const PointerEvent& event);
  154. /** Cursor button releases as OS reports it. */
  155. void cursorReleased(const PointerEvent& event);
  156. /** Cursor button releases as OS reports it. */
  157. void cursorDoubleClick(const PointerEvent& event);
  158. /** Input commands as OS reports them. */
  159. void inputCommandEntered(InputCommandType commandType);
  160. /** Called when window in focus changes, as reported by the OS. */
  161. void inputWindowChanged(RenderWindow& win);
  162. private:
  163. SPtr<RawInputHandler> mRawInputHandler;
  164. SPtr<OSInputHandler> mOSInputHandler;
  165. Vector<DeviceData> mDevices;
  166. Vector2I mPointerPosition;
  167. Vector2I mPointerDelta;
  168. ButtonState mPointerButtonStates[3];
  169. bool mPointerDoubleClicked;
  170. bool mLastPositionSet;
  171. Vector<QueuedEvent> mQueuedEvents;
  172. Vector<TextInputEvent> mTextInputEvents;
  173. Vector<InputCommandType> mCommandEvents;
  174. Vector<PointerEvent> mPointerDoubleClickEvents;
  175. Vector<PointerEvent> mPointerReleasedEvents;
  176. Vector<PointerEvent> mPointerPressedEvents;
  177. Vector<PointerEvent> mPointerMovedEvents;
  178. Vector<ButtonEvent> mButtonDownEvents;
  179. Vector<ButtonEvent> mButtonUpEvents;
  180. /************************************************************************/
  181. /* STATICS */
  182. /************************************************************************/
  183. static const int HISTORY_BUFFER_SIZE; // Size of buffer used for input smoothing
  184. static const float WEIGHT_MODIFIER;
  185. };
  186. /** Provides global access to Input. */
  187. BS_CORE_EXPORT Input& gInput();
  188. /** @} */
  189. }