eventHandler.cxx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. // Filename: eventHandler.cxx
  2. // Created by: drose (08Feb99)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. #include "eventHandler.h"
  15. #include "eventQueue.h"
  16. #include "config_event.h"
  17. TypeHandle EventHandler::_type_handle;
  18. EventHandler *EventHandler::_global_event_handler = NULL;
  19. ////////////////////////////////////////////////////////////////////
  20. // Function: EventHandler::Constructor
  21. // Access: Public
  22. // Description:
  23. ////////////////////////////////////////////////////////////////////
  24. EventHandler::
  25. EventHandler(EventQueue *ev_queue) : _queue(*ev_queue) {
  26. }
  27. ////////////////////////////////////////////////////////////////////
  28. // Function: EventHandler::process_events
  29. // Access: Public
  30. // Description: The main processing loop of the EventHandler. This
  31. // function must be called periodically to service
  32. // events. Walks through each pending event and calls
  33. // its assigned hooks.
  34. ////////////////////////////////////////////////////////////////////
  35. void EventHandler::
  36. process_events() {
  37. while (!_queue.is_queue_empty()) {
  38. dispatch_event(_queue.dequeue_event());
  39. }
  40. }
  41. ////////////////////////////////////////////////////////////////////
  42. // Function: EventHandler::dispatch_event
  43. // Access: Public, Virtual
  44. // Description: Calls the hooks assigned to the indicated single
  45. // event.
  46. ////////////////////////////////////////////////////////////////////
  47. void EventHandler::
  48. dispatch_event(const Event *event) {
  49. nassertv(event != (Event *)NULL);
  50. // Is the event name defined in the hook table? It will be if
  51. // anyone has ever assigned a hook to this particular event name.
  52. Hooks::const_iterator hi;
  53. hi = _hooks.find(event->get_name());
  54. if (hi != _hooks.end()) {
  55. // Yes, it is! Now walk through all the functions assigned to
  56. // that event name.
  57. Functions copy_functions = (*hi).second;
  58. Functions::const_iterator fi;
  59. for (fi = copy_functions.begin(); fi != copy_functions.end(); ++fi) {
  60. if (event_cat.is_spam()) {
  61. event_cat->spam()
  62. << "calling callback 0x" << (void*)(*fi)
  63. << " for event '" << event->get_name() << "'"
  64. << endl;
  65. }
  66. (*fi)(event);
  67. }
  68. }
  69. // now for callback hooks
  70. CallbackHooks::const_iterator chi;
  71. chi = _cbhooks.find(event->get_name());
  72. if (chi != _cbhooks.end()) {
  73. // found one
  74. CallbackFunctions copy_functions = (*chi).second;
  75. CallbackFunctions::const_iterator cfi;
  76. for (cfi = copy_functions.begin(); cfi != copy_functions.end(); ++cfi) {
  77. ((*cfi).first)(event, (*cfi).second);
  78. }
  79. }
  80. }
  81. ////////////////////////////////////////////////////////////////////
  82. // Function: EventHandler::write
  83. // Access: Public
  84. // Description:
  85. ////////////////////////////////////////////////////////////////////
  86. void EventHandler::
  87. write(ostream &out) const {
  88. Hooks::const_iterator hi;
  89. hi = _hooks.begin();
  90. CallbackHooks::const_iterator chi;
  91. chi = _cbhooks.begin();
  92. while (hi != _hooks.end() && chi != _cbhooks.end()) {
  93. if ((*hi).first < (*chi).first) {
  94. write_hook(out, *hi);
  95. ++hi;
  96. } else if ((*chi).first < (*hi).first) {
  97. write_cbhook(out, *chi);
  98. ++chi;
  99. } else {
  100. write_hook(out, *hi);
  101. write_cbhook(out, *chi);
  102. ++hi;
  103. ++chi;
  104. }
  105. }
  106. while (hi != _hooks.end()) {
  107. write_hook(out, *hi);
  108. ++hi;
  109. }
  110. while (chi != _cbhooks.end()) {
  111. write_cbhook(out, *chi);
  112. ++chi;
  113. }
  114. }
  115. ////////////////////////////////////////////////////////////////////
  116. // Function: EventHandler::add_hook
  117. // Access: Public
  118. // Description: Adds the indicated function to the list of those that
  119. // will be called when the named event is thrown.
  120. // Returns true if the function was successfully added,
  121. // false if it was already defined on the indicated
  122. // event name.
  123. ////////////////////////////////////////////////////////////////////
  124. bool EventHandler::
  125. add_hook(const string &event_name, EventFunction *function) {
  126. if (event_cat.is_debug()) {
  127. event_cat.debug()
  128. << "adding hook for event '" << event_name
  129. << "' with function 0x" << (void*)function << endl;
  130. }
  131. assert(!event_name.empty());
  132. assert(function);
  133. return _hooks[event_name].insert(function).second;
  134. }
  135. ////////////////////////////////////////////////////////////////////
  136. // Function: EventHandler::add_hook
  137. // Access: Public
  138. // Description: Adds the indicated function to the list of those that
  139. // will be called when the named event is thrown.
  140. // Returns true if the function was successfully added,
  141. // false if it was already defined on the indicated
  142. // event name. This version records an untyped pointer
  143. // to user callback data.
  144. ////////////////////////////////////////////////////////////////////
  145. bool EventHandler::
  146. add_hook(const string &event_name, EventCallbackFunction *function,
  147. void *data) {
  148. assert(!event_name.empty());
  149. assert(function);
  150. return _cbhooks[event_name].insert(CallbackFunction(function, data)).second;
  151. }
  152. ////////////////////////////////////////////////////////////////////
  153. // Function: EventHandler::has_hook
  154. // Access: Public
  155. // Description: Returns true if there is any hook added on the
  156. // indicated event name, false otherwise.
  157. ////////////////////////////////////////////////////////////////////
  158. bool EventHandler::
  159. has_hook(const string &event_name) const {
  160. assert(!event_name.empty());
  161. Hooks::const_iterator hi;
  162. hi = _hooks.find(event_name);
  163. if (hi != _hooks.end()) {
  164. if (!(*hi).second.empty()) {
  165. return true;
  166. }
  167. }
  168. CallbackHooks::const_iterator chi;
  169. chi = _cbhooks.find(event_name);
  170. if (chi != _cbhooks.end()) {
  171. if (!(*chi).second.empty()) {
  172. return true;
  173. }
  174. }
  175. return false;
  176. }
  177. ////////////////////////////////////////////////////////////////////
  178. // Function: EventHandler::remove_hook
  179. // Access: Public
  180. // Description: Removes the indicated function from the named event
  181. // hook. Returns true if the hook was removed, false if
  182. // it wasn't there in the first place.
  183. ////////////////////////////////////////////////////////////////////
  184. bool EventHandler::
  185. remove_hook(const string &event_name, EventFunction *function) {
  186. assert(!event_name.empty());
  187. assert(function);
  188. return _hooks[event_name].erase(function) != 0;
  189. }
  190. ////////////////////////////////////////////////////////////////////
  191. // Function: EventHandler::remove_hook
  192. // Access: Public
  193. // Description: Removes the indicated function from the named event
  194. // hook. Returns true if the hook was removed, false if
  195. // it wasn't there in the first place. This version
  196. // takes an untyped pointer to user callback data.
  197. ////////////////////////////////////////////////////////////////////
  198. bool EventHandler::
  199. remove_hook(const string &event_name, EventCallbackFunction *function,
  200. void *data) {
  201. assert(!event_name.empty());
  202. assert(function);
  203. return _cbhooks[event_name].erase(CallbackFunction(function, data)) != 0;
  204. }
  205. ////////////////////////////////////////////////////////////////////
  206. // Function: EventHandler::remove_hooks
  207. // Access: Public
  208. // Description: Removes all functions from the named event hook.
  209. // Returns true if any functions were removed, false if
  210. // there were no functions added to the hook.
  211. ////////////////////////////////////////////////////////////////////
  212. bool EventHandler::
  213. remove_hooks(const string &event_name) {
  214. assert(!event_name.empty());
  215. bool any_removed = false;
  216. Hooks::iterator hi = _hooks.find(event_name);
  217. if (hi != _hooks.end()) {
  218. if (!(*hi).second.empty()) {
  219. any_removed = true;
  220. }
  221. _hooks.erase(hi);
  222. }
  223. CallbackHooks::iterator chi = _cbhooks.find(event_name);
  224. if (chi != _cbhooks.end()) {
  225. if (!(*chi).second.empty()) {
  226. any_removed = true;
  227. }
  228. _cbhooks.erase(chi);
  229. }
  230. return any_removed;
  231. }
  232. ////////////////////////////////////////////////////////////////////
  233. // Function: EventHandler::remove_hooks_with
  234. // Access: Public
  235. // Description: Removes all CallbackFunction hooks that have the
  236. // indicated pointer as the associated data pointer.
  237. ////////////////////////////////////////////////////////////////////
  238. bool EventHandler::
  239. remove_hooks_with(void *data) {
  240. bool any_removed = false;
  241. CallbackHooks::iterator chi;
  242. for (chi = _cbhooks.begin(); chi != _cbhooks.end(); ++chi) {
  243. CallbackFunctions &funcs = (*chi).second;
  244. CallbackFunctions::iterator cfi;
  245. CallbackFunctions new_funcs;
  246. for (cfi = funcs.begin(); cfi != funcs.end(); ++cfi) {
  247. if ((*cfi).second == data) {
  248. any_removed = true;
  249. } else {
  250. new_funcs.insert(*cfi);
  251. }
  252. }
  253. funcs.swap(new_funcs);
  254. }
  255. return any_removed;
  256. }
  257. ////////////////////////////////////////////////////////////////////
  258. // Function: EventHandler::remove_all_hooks
  259. // Access: Public
  260. // Description: Removes all hooks assigned to all events.
  261. ////////////////////////////////////////////////////////////////////
  262. void EventHandler::
  263. remove_all_hooks() {
  264. _hooks.clear();
  265. _cbhooks.clear();
  266. }
  267. ////////////////////////////////////////////////////////////////////
  268. // Function: EventHandler::make_global_event_handler
  269. // Access: Protected, Static
  270. // Description:
  271. ////////////////////////////////////////////////////////////////////
  272. void EventHandler::
  273. make_global_event_handler() {
  274. _global_event_handler = new EventHandler(EventQueue::get_global_event_queue());
  275. }
  276. ////////////////////////////////////////////////////////////////////
  277. // Function: EventHandler::write_hook
  278. // Access: Private
  279. // Description:
  280. ////////////////////////////////////////////////////////////////////
  281. void EventHandler::
  282. write_hook(ostream &out, const EventHandler::Hooks::value_type &hook) const {
  283. if (!hook.second.empty()) {
  284. out << hook.first << " has " << hook.second.size() << " functions.\n";
  285. }
  286. }
  287. ////////////////////////////////////////////////////////////////////
  288. // Function: EventHandler::write_cbhook
  289. // Access: Private
  290. // Description:
  291. ////////////////////////////////////////////////////////////////////
  292. void EventHandler::
  293. write_cbhook(ostream &out, const EventHandler::CallbackHooks::value_type &hook) const {
  294. if (!hook.second.empty()) {
  295. out << hook.first << " has " << hook.second.size() << " callback functions.\n";
  296. }
  297. }