00001 // Filename: eventHandler.cxx 00002 // Created by: drose (08Feb99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "eventHandler.h" 00020 #include "eventQueue.h" 00021 #include "config_event.h" 00022 00023 TypeHandle EventHandler::_type_handle; 00024 00025 //////////////////////////////////////////////////////////////////// 00026 // Function: EventHandler::Constructor 00027 // Access: Public 00028 // Description: 00029 //////////////////////////////////////////////////////////////////// 00030 EventHandler:: 00031 EventHandler(EventQueue *queue) : _queue(*queue) { 00032 } 00033 00034 //////////////////////////////////////////////////////////////////// 00035 // Function: EventHandler::process_events 00036 // Access: Public 00037 // Description: The main processing loop of the EventHandler. This 00038 // function must be called periodically to service 00039 // events. Walks through each pending event and calls 00040 // its assigned hooks. 00041 //////////////////////////////////////////////////////////////////// 00042 void EventHandler:: 00043 process_events() { 00044 while (!_queue.is_queue_empty()) { 00045 dispatch_event(_queue.dequeue_event()); 00046 } 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: EventHandler::dispatch_event 00051 // Access: Public, Virtual 00052 // Description: Calls the hooks assigned to the indicated single 00053 // event. 00054 //////////////////////////////////////////////////////////////////// 00055 void EventHandler:: 00056 dispatch_event(const CPT_Event &event) { 00057 // Is the event name defined in the hook table? It will be if 00058 // anyone has ever assigned a hook to this particular event name. 00059 Hooks::const_iterator hi; 00060 hi = _hooks.find(event->get_name()); 00061 00062 if (hi != _hooks.end()) { 00063 // Yes, it is! Now walk through all the functions assigned to 00064 // that event name. 00065 Functions copy_functions = (*hi).second; 00066 00067 Functions::const_iterator fi; 00068 for (fi = copy_functions.begin(); fi != copy_functions.end(); ++fi) { 00069 if (event_cat.is_spam()) 00070 event_cat->spam() << "calling callback 0x" << (void*)(*fi) 00071 << " for event '" << event->get_name() << "'" 00072 << endl; 00073 (*fi)(event); 00074 } 00075 } 00076 00077 // now for callback hooks 00078 CallbackHooks::const_iterator cbhi; 00079 cbhi = _cbhooks.find(event->get_name()); 00080 00081 if (cbhi != _cbhooks.end()) { 00082 // found one 00083 CallbackFunctions copy_functions = (*cbhi).second; 00084 00085 CallbackFunctions::const_iterator cbfi; 00086 for (cbfi = copy_functions.begin(); cbfi != copy_functions.end(); ++cbfi) { 00087 ((*cbfi).first)(event, (*cbfi).second); 00088 } 00089 } 00090 } 00091 00092 00093 //////////////////////////////////////////////////////////////////// 00094 // Function: EventHandler::write 00095 // Access: Public 00096 // Description: 00097 //////////////////////////////////////////////////////////////////// 00098 void EventHandler:: 00099 write(ostream &out) const { 00100 Hooks::const_iterator hi; 00101 hi = _hooks.begin(); 00102 00103 CallbackHooks::const_iterator cbhi; 00104 cbhi = _cbhooks.begin(); 00105 00106 while (hi != _hooks.end() && cbhi != _cbhooks.end()) { 00107 if ((*hi).first < (*cbhi).first) { 00108 write_hook(out, *hi); 00109 ++hi; 00110 00111 } else if ((*cbhi).first < (*hi).first) { 00112 write_cbhook(out, *cbhi); 00113 ++cbhi; 00114 00115 } else { 00116 write_hook(out, *hi); 00117 write_cbhook(out, *cbhi); 00118 ++hi; 00119 ++cbhi; 00120 } 00121 } 00122 00123 while (hi != _hooks.end()) { 00124 write_hook(out, *hi); 00125 ++hi; 00126 } 00127 00128 while (cbhi != _cbhooks.end()) { 00129 write_cbhook(out, *cbhi); 00130 ++cbhi; 00131 } 00132 } 00133 00134 00135 00136 //////////////////////////////////////////////////////////////////// 00137 // Function: EventHandler::add_hook 00138 // Access: Public 00139 // Description: Adds the indicated function to the list of those that 00140 // will be called when the named event is thrown. 00141 // Returns true if the function was successfully added, 00142 // false if it was already defined on the indicated 00143 // event name. 00144 //////////////////////////////////////////////////////////////////// 00145 bool EventHandler:: 00146 add_hook(const string &event_name, EventFunction *function) { 00147 if (event_cat.is_debug()) 00148 event_cat.debug() << "adding hook for event '" << event_name 00149 << "' with function 0x" << (void*)function << endl; 00150 return _hooks[event_name].insert(function).second; 00151 } 00152 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Function: EventHandler::add_hook 00156 // Access: Public 00157 // Description: Adds the indicated function to the list of those that 00158 // will be called when the named event is thrown. 00159 // Returns true if the function was successfully added, 00160 // false if it was already defined on the indicated 00161 // event name. This version records an untyped pointer 00162 // to user callback data. 00163 //////////////////////////////////////////////////////////////////// 00164 bool EventHandler:: 00165 add_hook(const string &event_name, EventCallbackFunction *function, 00166 void *data) { 00167 return _cbhooks[event_name].insert(CallbackFunction(function, data)).second; 00168 } 00169 00170 00171 //////////////////////////////////////////////////////////////////// 00172 // Function: EventHandler::remove_hook 00173 // Access: Public 00174 // Description: Removes the indicated function from the named event 00175 // hook. Returns true if the hook was removed, false if 00176 // it wasn't there in the first place. 00177 //////////////////////////////////////////////////////////////////// 00178 bool EventHandler:: 00179 remove_hook(const string &event_name, EventFunction *function) { 00180 return _hooks[event_name].erase(function) != 0; 00181 } 00182 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // Function: EventHandler::remove_hook 00186 // Access: Public 00187 // Description: Removes the indicated function from the named event 00188 // hook. Returns true if the hook was removed, false if 00189 // it wasn't there in the first place. This version 00190 // takes an untyped pointer to user callback data. 00191 //////////////////////////////////////////////////////////////////// 00192 bool EventHandler:: 00193 remove_hook(const string &event_name, EventCallbackFunction *function, 00194 void *data) { 00195 return _cbhooks[event_name].erase(CallbackFunction(function, data)) != 0; 00196 } 00197 00198 00199 //////////////////////////////////////////////////////////////////// 00200 // Function: EventHandler::remove_all_hooks 00201 // Access: Public 00202 // Description: Removes all hooks assigned to all events. 00203 //////////////////////////////////////////////////////////////////// 00204 void EventHandler:: 00205 remove_all_hooks() { 00206 _hooks.clear(); 00207 _cbhooks.clear(); 00208 } 00209 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: EventHandler::write_hook 00213 // Access: Private 00214 // Description: 00215 //////////////////////////////////////////////////////////////////// 00216 void EventHandler:: 00217 write_hook(ostream &out, const EventHandler::Hooks::value_type &hook) const { 00218 if (!hook.second.empty()) { 00219 out << hook.first << " has " << hook.second.size() << " functions.\n"; 00220 } 00221 } 00222 00223 //////////////////////////////////////////////////////////////////// 00224 // Function: EventHandler::write_cbhook 00225 // Access: Private 00226 // Description: 00227 //////////////////////////////////////////////////////////////////// 00228 void EventHandler:: 00229 write_cbhook(ostream &out, const EventHandler::CallbackHooks::value_type &hook) const { 00230 if (!hook.second.empty()) { 00231 out << hook.first << " has " << hook.second.size() << " callback functions.\n"; 00232 } 00233 }