Input.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Math.h>
  7. #include <AnKi/Util/Singleton.h>
  8. #include <AnKi/Util/Array.h>
  9. #include <AnKi/Util/String.h>
  10. #include <AnKi/Util/Enum.h>
  11. #include <AnKi/Window/KeyCode.h>
  12. namespace anki {
  13. enum class InputEvent : U8
  14. {
  15. kWindowFocusLost,
  16. kWindowFocusGained,
  17. kWindowClosed,
  18. kCount
  19. };
  20. enum class MouseCursor : U8
  21. {
  22. kArrow,
  23. kTextInput, // When hovering over InputText, etc.
  24. kResizeAll,
  25. kResizeNS, // When hovering over a horizontal border
  26. kResizeEW, // When hovering over a vertical border or a column
  27. kResizeNESW, // When hovering over the bottom-left corner of a window
  28. kResizeNWSE, // When hovering over the bottom-right corner of a window
  29. kHand,
  30. kWait, // When waiting for something to process/load.
  31. kProgress, // When waiting for something to process/load, but application is still interactive.
  32. kNotAllowed,
  33. kCount,
  34. kFirst = 0
  35. };
  36. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(MouseCursor)
  37. // Handle the input and other events
  38. // @note All positions are in NDC space
  39. class Input : public MakeSingletonPtr<Input>
  40. {
  41. template<typename>
  42. friend class MakeSingletonPtr;
  43. public:
  44. Error init();
  45. // Shows the current key state
  46. // 0: Key resting
  47. // 1: Ley pressed once
  48. // >1: Kept pressed 'n' times continuously
  49. // <0: Key up
  50. I32 getKey(KeyCode i) const
  51. {
  52. return m_keys[i];
  53. }
  54. // See getKey()
  55. I32 getMouseButton(MouseButton i) const
  56. {
  57. return m_mouseBtns[i];
  58. }
  59. const Vec2& getMousePositionNdc() const
  60. {
  61. return m_mousePosNdc;
  62. }
  63. const Vec2& getMousePreviousPositionNdc() const
  64. {
  65. return m_prevMousePosNdc;
  66. }
  67. Vec2 getMouseMoveDeltaNdc() const
  68. {
  69. return m_mousePosNdc - m_prevMousePosNdc;
  70. }
  71. // Move the mouse cursor to a position inside the window. Useful for locking the cursor into a fixed location (eg in the center of the screen)
  72. void moveMouseNdc(const Vec2& posNdc);
  73. // Lock mouse to (0, 0)
  74. void lockMouseWindowCenter(Bool lock)
  75. {
  76. m_lockCurs = lock;
  77. }
  78. // Hide the mouse cursor
  79. void hideCursor(Bool hide);
  80. void setMouseCursor(MouseCursor cursor);
  81. // See getKey()
  82. I32 getTouchPointer(TouchPointer p) const
  83. {
  84. return m_touchPointers[p];
  85. }
  86. Vec2 getTouchPointerNdcPosition(TouchPointer p) const
  87. {
  88. return m_touchPointerPosNdc[p];
  89. }
  90. Bool hasTouchDevice() const;
  91. // Populate the key and button with the new state
  92. Error handleEvents();
  93. // Add a new event
  94. // It's thread-safe
  95. void addEvent(InputEvent eventId)
  96. {
  97. m_events[eventId].fetchAdd(1);
  98. }
  99. // Get the times an event was triggered and resets the counter
  100. // It's thread-safe
  101. U32 getEvent(InputEvent eventId) const
  102. {
  103. return m_events[eventId].exchange(0);
  104. }
  105. // Get some easy to digest input from the keyboard.
  106. CString getTextInput() const
  107. {
  108. return &m_textInput[0];
  109. }
  110. protected:
  111. Array<I32, U(KeyCode::kCount)> m_keys;
  112. Array<I32, U(MouseButton::kCount)> m_mouseBtns;
  113. Vec2 m_mousePosNdc;
  114. Vec2 m_prevMousePosNdc;
  115. Array<I32, U(TouchPointer::kCount)> m_touchPointers;
  116. Array<Vec2, U(TouchPointer::kCount)> m_touchPointerPosNdc;
  117. mutable Array<Atomic<U32>, U(InputEvent::kCount)> m_events;
  118. // The keybord input as ascii.
  119. static constexpr U32 kMaxTexInput = 256;
  120. Array<Char, kMaxTexInput> m_textInput;
  121. Bool m_lockCurs = false;
  122. Input()
  123. {
  124. reset();
  125. }
  126. void reset()
  127. {
  128. zeroMemory(m_keys);
  129. zeroMemory(m_mouseBtns);
  130. m_mousePosNdc = m_prevMousePosNdc = Vec2(-1.0f);
  131. zeroMemory(m_events);
  132. zeroMemory(m_textInput);
  133. zeroMemory(m_touchPointers);
  134. zeroMemory(m_touchPointerPosNdc);
  135. }
  136. };
  137. template<>
  138. template<>
  139. Input& MakeSingletonPtr<Input>::allocateSingleton<>();
  140. template<>
  141. void MakeSingletonPtr<Input>::freeSingleton();
  142. } // end namespace anki