00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "eventHandler.h"
00016 #include "eventQueue.h"
00017 #include "config_event.h"
00018
00019 TypeHandle EventHandler::_type_handle;
00020
00021 EventHandler *EventHandler::_global_event_handler = 0;
00022
00023
00024
00025
00026
00027
00028
00029 EventHandler::
00030 EventHandler(EventQueue *ev_queue) : _queue(*ev_queue) {
00031 }
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 void EventHandler::
00042 process_events() {
00043 while (!_queue.is_queue_empty()) {
00044 dispatch_event(_queue.dequeue_event());
00045 }
00046 }
00047
00048
00049
00050
00051
00052
00053
00054 void EventHandler::
00055 dispatch_event(const Event *event) {
00056 nassertv(event != (Event *)NULL);
00057
00058
00059
00060 Hooks::const_iterator hi;
00061 hi = _hooks.find(event->get_name());
00062
00063 if (hi != _hooks.end()) {
00064
00065
00066 Functions copy_functions = (*hi).second;
00067
00068 Functions::const_iterator fi;
00069 for (fi = copy_functions.begin(); fi != copy_functions.end(); ++fi) {
00070 if (event_cat.is_spam()) {
00071 event_cat->spam()
00072 << "calling callback 0x" << (void*)(*fi)
00073 << " for event '" << event->get_name() << "'"
00074 << endl;
00075 }
00076 (*fi)(event);
00077 }
00078 }
00079
00080
00081 CallbackHooks::const_iterator chi;
00082 chi = _cbhooks.find(event->get_name());
00083
00084 if (chi != _cbhooks.end()) {
00085
00086 CallbackFunctions copy_functions = (*chi).second;
00087
00088 CallbackFunctions::const_iterator cfi;
00089 for (cfi = copy_functions.begin(); cfi != copy_functions.end(); ++cfi) {
00090 ((*cfi).first)(event, (*cfi).second);
00091 }
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100
00101 void EventHandler::
00102 write(ostream &out) const {
00103 Hooks::const_iterator hi;
00104 hi = _hooks.begin();
00105
00106 CallbackHooks::const_iterator chi;
00107 chi = _cbhooks.begin();
00108
00109 while (hi != _hooks.end() && chi != _cbhooks.end()) {
00110 if ((*hi).first < (*chi).first) {
00111 write_hook(out, *hi);
00112 ++hi;
00113 } else if ((*chi).first < (*hi).first) {
00114 write_cbhook(out, *chi);
00115 ++chi;
00116 } else {
00117 write_hook(out, *hi);
00118 write_cbhook(out, *chi);
00119 ++hi;
00120 ++chi;
00121 }
00122 }
00123
00124 while (hi != _hooks.end()) {
00125 write_hook(out, *hi);
00126 ++hi;
00127 }
00128
00129 while (chi != _cbhooks.end()) {
00130 write_cbhook(out, *chi);
00131 ++chi;
00132 }
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 bool EventHandler::
00147 add_hook(const string &event_name, EventFunction *function) {
00148 if (event_cat.is_debug()) {
00149 event_cat.debug()
00150 << "adding hook for event '" << event_name
00151 << "' with function 0x" << (void*)function << endl;
00152 }
00153 assert(!event_name.empty());
00154 assert(function);
00155 return _hooks[event_name].insert(function).second;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 bool EventHandler::
00170 add_hook(const string &event_name, EventCallbackFunction *function,
00171 void *data) {
00172 assert(!event_name.empty());
00173 assert(function);
00174 return _cbhooks[event_name].insert(CallbackFunction(function, data)).second;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183 bool EventHandler::
00184 has_hook(const string &event_name) const {
00185 assert(!event_name.empty());
00186 Hooks::const_iterator hi;
00187 hi = _hooks.find(event_name);
00188 if (hi != _hooks.end()) {
00189 if (!(*hi).second.empty()) {
00190 return true;
00191 }
00192 }
00193
00194 CallbackHooks::const_iterator chi;
00195 chi = _cbhooks.find(event_name);
00196 if (chi != _cbhooks.end()) {
00197 if (!(*chi).second.empty()) {
00198 return true;
00199 }
00200 }
00201
00202 return false;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 bool EventHandler::
00214 remove_hook(const string &event_name, EventFunction *function) {
00215 assert(!event_name.empty());
00216 assert(function);
00217 return _hooks[event_name].erase(function) != 0;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 bool EventHandler::
00230 remove_hook(const string &event_name, EventCallbackFunction *function,
00231 void *data) {
00232 assert(!event_name.empty());
00233 assert(function);
00234 return _cbhooks[event_name].erase(CallbackFunction(function, data)) != 0;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244 bool EventHandler::
00245 remove_hooks(const string &event_name) {
00246 assert(!event_name.empty());
00247 bool any_removed = false;
00248
00249 Hooks::iterator hi = _hooks.find(event_name);
00250 if (hi != _hooks.end()) {
00251 if (!(*hi).second.empty()) {
00252 any_removed = true;
00253 }
00254 _hooks.erase(hi);
00255 }
00256
00257 CallbackHooks::iterator chi = _cbhooks.find(event_name);
00258 if (chi != _cbhooks.end()) {
00259 if (!(*chi).second.empty()) {
00260 any_removed = true;
00261 }
00262 _cbhooks.erase(chi);
00263 }
00264
00265 return any_removed;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 bool EventHandler::
00275 remove_hooks_with(void *data) {
00276 bool any_removed = false;
00277
00278 CallbackHooks::iterator chi;
00279 for (chi = _cbhooks.begin(); chi != _cbhooks.end(); ++chi) {
00280 CallbackFunctions &funcs = (*chi).second;
00281 CallbackFunctions::iterator cfi;
00282
00283 CallbackFunctions new_funcs;
00284 for (cfi = funcs.begin(); cfi != funcs.end(); ++cfi) {
00285 if ((*cfi).second == data) {
00286 any_removed = true;
00287 } else {
00288 new_funcs.insert(*cfi);
00289 }
00290 }
00291 funcs.swap(new_funcs);
00292 }
00293
00294 return any_removed;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303 void EventHandler::
00304 remove_all_hooks() {
00305 _hooks.clear();
00306 _cbhooks.clear();
00307 }
00308
00309
00310
00311
00312
00313
00314 void EventHandler::
00315 make_global_event_handler() {
00316 _global_event_handler = new EventHandler(EventQueue::get_global_event_queue());
00317 }
00318
00319
00320
00321
00322
00323
00324
00325 void EventHandler::
00326 write_hook(ostream &out, const EventHandler::Hooks::value_type &hook) const {
00327 if (!hook.second.empty()) {
00328 out << hook.first << " has " << hook.second.size() << " functions.\n";
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337 void EventHandler::
00338 write_cbhook(ostream &out, const EventHandler::CallbackHooks::value_type &hook) const {
00339 if (!hook.second.empty()) {
00340 out << hook.first << " has " << hook.second.size() << " callback functions.\n";
00341 }
00342 }