os_event_queue.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * Copyright (c) 2012-2014 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #pragma once
  6. #include <cstring>
  7. #include "types.h"
  8. #include "mouse.h"
  9. #include "keyboard.h"
  10. #include "atomic_int.h"
  11. namespace crown
  12. {
  13. struct OsMetricsEvent
  14. {
  15. uint16_t x;
  16. uint16_t y;
  17. uint16_t width;
  18. uint16_t height;
  19. };
  20. struct OsExitEvent
  21. {
  22. int32_t code;
  23. };
  24. /// Represents an event fired by mouse.
  25. struct OsMouseEvent
  26. {
  27. enum Enum
  28. {
  29. BUTTON,
  30. WHEEL,
  31. MOVE
  32. };
  33. OsMouseEvent::Enum type;
  34. MouseButton::Enum button;
  35. uint16_t x;
  36. uint16_t y;
  37. bool pressed;
  38. float wheel;
  39. };
  40. /// Represents an event fired by keyboard.
  41. struct OsKeyboardEvent
  42. {
  43. KeyboardButton::Enum button;
  44. uint32_t modifier;
  45. bool pressed;
  46. };
  47. /// Represents an event fired by touch screen.
  48. struct OsTouchEvent
  49. {
  50. enum Enum
  51. {
  52. POINTER,
  53. MOVE
  54. };
  55. OsTouchEvent::Enum type;
  56. uint8_t pointer_id;
  57. uint16_t x;
  58. uint16_t y;
  59. bool pressed;
  60. };
  61. /// Represents an event fired by accelerometer.
  62. struct OsAccelerometerEvent
  63. {
  64. float x;
  65. float y;
  66. float z;
  67. };
  68. struct OsEvent
  69. {
  70. /// Represents an event fired by the OS
  71. enum Enum
  72. {
  73. NONE = 0,
  74. KEYBOARD = 1,
  75. MOUSE = 2,
  76. TOUCH = 3,
  77. ACCELEROMETER = 4,
  78. METRICS,
  79. PAUSE,
  80. RESUME,
  81. // Exit from program
  82. EXIT
  83. };
  84. OsEvent::Enum type;
  85. union
  86. {
  87. OsMetricsEvent metrics;
  88. OsExitEvent exit;
  89. OsMouseEvent mouse;
  90. OsKeyboardEvent keyboard;
  91. OsTouchEvent touch;
  92. OsAccelerometerEvent accelerometer;
  93. };
  94. };
  95. #define MAX_OS_EVENTS 64
  96. /// Single Producer Single Consumer event queue.
  97. /// Used only to pass events from os thread to main thread.
  98. struct OsEventQueue
  99. {
  100. OsEventQueue()
  101. : _tail(0)
  102. , _head(0)
  103. {
  104. }
  105. void push_mouse_event(uint16_t x, uint16_t y)
  106. {
  107. OsEvent ev;
  108. ev.type = OsEvent::MOUSE;
  109. ev.mouse.type = OsMouseEvent::MOVE;
  110. ev.mouse.x = x;
  111. ev.mouse.y = y;
  112. push_event(ev);
  113. }
  114. void push_mouse_event(uint16_t x, uint16_t y, MouseButton::Enum b, bool pressed)
  115. {
  116. OsEvent ev;
  117. ev.type = OsEvent::MOUSE;
  118. ev.mouse.type = OsMouseEvent::BUTTON;
  119. ev.mouse.x = x;
  120. ev.mouse.y = y;
  121. ev.mouse.button = b;
  122. ev.mouse.pressed = pressed;
  123. push_event(ev);
  124. }
  125. void push_mouse_event(uint16_t x, uint16_t y, float wheel)
  126. {
  127. OsEvent ev;
  128. ev.type = OsEvent::MOUSE;
  129. ev.mouse.type = OsMouseEvent::WHEEL;
  130. ev.mouse.x = x;
  131. ev.mouse.y = y;
  132. ev.mouse.wheel = wheel;
  133. push_event(ev);
  134. }
  135. void push_keyboard_event(uint32_t modifier, KeyboardButton::Enum b, bool pressed)
  136. {
  137. OsEvent ev;
  138. ev.type = OsEvent::KEYBOARD;
  139. ev.keyboard.button = b;
  140. ev.keyboard.modifier = modifier;
  141. ev.keyboard.pressed = pressed;
  142. push_event(ev);
  143. }
  144. void push_touch_event(uint16_t x, uint16_t y, uint8_t pointer_id)
  145. {
  146. OsEvent ev;
  147. ev.type = OsEvent::TOUCH;
  148. ev.touch.type = OsTouchEvent::MOVE;
  149. ev.touch.x = x;
  150. ev.touch.y = y;
  151. ev.touch.pointer_id = pointer_id;
  152. push_event(ev);
  153. }
  154. void push_touch_event(uint16_t x, uint16_t y, uint8_t pointer_id, bool pressed)
  155. {
  156. OsEvent ev;
  157. ev.type = OsEvent::TOUCH;
  158. ev.touch.type = OsTouchEvent::POINTER;
  159. ev.touch.x = x;
  160. ev.touch.y = y;
  161. ev.touch.pointer_id = pointer_id;
  162. ev.touch.pressed = pressed;
  163. push_event(ev);
  164. }
  165. void push_exit_event(int32_t code)
  166. {
  167. OsEvent ev;
  168. ev.type = OsEvent::EXIT;
  169. ev.exit.code = code;
  170. push_event(ev);
  171. }
  172. void push_pause_event()
  173. {
  174. OsEvent ev;
  175. ev.type = OsEvent::PAUSE;
  176. push_event(ev);
  177. }
  178. void push_resume_event()
  179. {
  180. OsEvent ev;
  181. ev.type = OsEvent::RESUME;
  182. push_event(ev);
  183. }
  184. void push_metrics_event(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
  185. {
  186. OsEvent ev;
  187. ev.type = OsEvent::METRICS;
  188. ev.metrics.x = x;
  189. ev.metrics.y = y;
  190. ev.metrics.width = width;
  191. ev.metrics.height = height;
  192. push_event(ev);
  193. }
  194. void push_none_event()
  195. {
  196. OsEvent ev;
  197. ev.type = OsEvent::NONE;
  198. push_event(ev);
  199. }
  200. bool push_event(const OsEvent& ev)
  201. {
  202. int cur_tail = _tail.load();
  203. int next_tail = increment(cur_tail);
  204. if(next_tail != _head.load())
  205. {
  206. _queue[cur_tail] = ev;
  207. _tail.store(next_tail);
  208. return true;
  209. }
  210. return false;
  211. }
  212. bool pop_event(OsEvent& ev)
  213. {
  214. const int cur_head = _head.load();
  215. if(cur_head == _tail.load()) return false;
  216. ev = _queue[cur_head];
  217. _head.store(increment(cur_head));
  218. return true;
  219. }
  220. int increment(int idx) const
  221. {
  222. return (idx + 1) % MAX_OS_EVENTS;
  223. }
  224. private:
  225. OsEvent _queue[MAX_OS_EVENTS];
  226. AtomicInt _tail;
  227. AtomicInt _head;
  228. };
  229. } // namespace crown