Panda3D
|
00001 // Filename: eventHandler.cxx 00002 // Created by: drose (08Feb99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 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 // Function: EventHandler::Constructor 00026 // Access: Public 00027 // Description: 00028 //////////////////////////////////////////////////////////////////// 00029 EventHandler:: 00030 EventHandler(EventQueue *ev_queue) : _queue(*ev_queue) { 00031 } 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: EventHandler::process_events 00035 // Access: Public 00036 // Description: The main processing loop of the EventHandler. This 00037 // function must be called periodically to service 00038 // events. Walks through each pending event and calls 00039 // its assigned hooks. 00040 //////////////////////////////////////////////////////////////////// 00041 void EventHandler:: 00042 process_events() { 00043 while (!_queue.is_queue_empty()) { 00044 dispatch_event(_queue.dequeue_event()); 00045 } 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: EventHandler::dispatch_event 00050 // Access: Public, Virtual 00051 // Description: Calls the hooks assigned to the indicated single 00052 // event. 00053 //////////////////////////////////////////////////////////////////// 00054 void EventHandler:: 00055 dispatch_event(const Event *event) { 00056 nassertv(event != (Event *)NULL); 00057 00058 // Is the event name defined in the hook table? It will be if 00059 // anyone has ever assigned a hook to this particular event name. 00060 Hooks::const_iterator hi; 00061 hi = _hooks.find(event->get_name()); 00062 00063 if (hi != _hooks.end()) { 00064 // Yes, it is! Now walk through all the functions assigned to 00065 // that event name. 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 // now for callback hooks 00081 CallbackHooks::const_iterator chi; 00082 chi = _cbhooks.find(event->get_name()); 00083 00084 if (chi != _cbhooks.end()) { 00085 // found one 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 // Function: EventHandler::write 00098 // Access: Public 00099 // Description: 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 // Function: EventHandler::add_hook 00139 // Access: Public 00140 // Description: Adds the indicated function to the list of those that 00141 // will be called when the named event is thrown. 00142 // Returns true if the function was successfully added, 00143 // false if it was already defined on the indicated 00144 // event name. 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 // Function: EventHandler::add_hook 00161 // Access: Public 00162 // Description: Adds the indicated function to the list of those that 00163 // will be called when the named event is thrown. 00164 // Returns true if the function was successfully added, 00165 // false if it was already defined on the indicated 00166 // event name. This version records an untyped pointer 00167 // to user callback data. 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 // Function: EventHandler::has_hook 00179 // Access: Public 00180 // Description: Returns true if there is any hook added on the 00181 // indicated event name, false otherwise. 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 // Function: EventHandler::remove_hook 00208 // Access: Public 00209 // Description: Removes the indicated function from the named event 00210 // hook. Returns true if the hook was removed, false if 00211 // it wasn't there in the first place. 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 // Function: EventHandler::remove_hook 00223 // Access: Public 00224 // Description: Removes the indicated function from the named event 00225 // hook. Returns true if the hook was removed, false if 00226 // it wasn't there in the first place. This version 00227 // takes an untyped pointer to user callback data. 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 // Function: EventHandler::remove_hooks 00239 // Access: Public 00240 // Description: Removes all functions from the named event hook. 00241 // Returns true if any functions were removed, false if 00242 // there were no functions added to the hook. 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 // Function: EventHandler::remove_hooks_with 00270 // Access: Public 00271 // Description: Removes all CallbackFunction hooks that have the 00272 // indicated pointer as the associated data pointer. 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 // Function: EventHandler::remove_all_hooks 00300 // Access: Public 00301 // Description: Removes all hooks assigned to all events. 00302 //////////////////////////////////////////////////////////////////// 00303 void EventHandler:: 00304 remove_all_hooks() { 00305 _hooks.clear(); 00306 _cbhooks.clear(); 00307 } 00308 00309 //////////////////////////////////////////////////////////////////// 00310 // Function: EventHandler::make_global_event_handler 00311 // Access: Protected, Static 00312 // Description: 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 // Function: EventHandler::write_hook 00322 // Access: Private 00323 // Description: 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 // Function: EventHandler::write_cbhook 00334 // Access: Private 00335 // Description: 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 }