Homepage Demos Overview Downloads Tutorials Reference
Credits

EventRouter.cc

Go to the documentation of this file.
00001 #include "EventRouter.h"
00002 #include "Shared/Profiler.h"
00003 #include <algorithm>
00004 
00005 EventRouter * erouter=NULL;
00006 
00007 EventRouter::EventRouter()
00008   : timers(), events(), doSendBufferLock(false), lastBufClear(0), buffertime(0), trappers(), listeners()
00009 {}
00010 
00011 //! @todo handle recursive calls
00012 void EventRouter::processTimers() {
00013   //    cout << "processTimers..." << flush;
00014   unsigned int curtime=get_time();
00015   if(curtime-lastBufClear>=buffertime || buffertime==1)
00016     processEventBuffer();
00017 
00018   TimerEntry curTimer(curtime);
00019   timer_it_t last_it=upper_bound(timers.begin(),timers.end(),&curTimer,TimerEntryPtrCmp());
00020   std::vector<TimerEntry*> process(timers.begin(),last_it); //copy these out for safe keeping
00021   for(timer_it_t it=process.begin(); it!=process.end(); it++) //increment the timers we're processing
00022     if((*it)->repeat)
00023       (*it)->next+=(*it)->delay;
00024     else
00025       (*it)->next=(unsigned int)-1;
00026   sort(timers.begin(),last_it,TimerEntryPtrCmp()); //re-sort the timers we're processing (at the beginning of timers)
00027   inplace_merge(timers.begin(),last_it,timers.end(),TimerEntryPtrCmp()); //now do a merge of the sorted processed stuff and the rest of the list (which is still sorted)
00028   //  if(process.size()>0) chkTimers();
00029   for(timer_it_t it=process.begin(); it!=process.end(); it++) // process the timers we say we're going to, can no longer assume anything about the state of the world
00030     (*it)->el->processEvent(EventBase(EventBase::timerEGID,(*it)->sid,EventBase::statusETID,(*it)->next));
00031   //  if(process.size()>0) chkTimers();
00032   static const TimerEntry deadTimer((unsigned int)-1); // matches all the dead ones as set in the incrementation phase
00033   last_it=lower_bound(timers.begin(),timers.end(),&deadTimer,TimerEntryPtrCmp()); //find the beginning of all the non-repeating timers we're clearing
00034   for(timer_it_t it=last_it; it!=timers.end(); it++) // delete all of them
00035     delete *it;
00036   timers.erase(last_it,timers.end()); //and then remove them from the timer list
00037   //  if(process.size()>0) chkTimers();
00038   //    cout << "done" << endl;
00039 }
00040 
00041 /*! timers are unique by EventListener and source ID - can't have two timers for the same el and sid
00042  *  a delay of 0 with repeating will cause an event to be sent at every opportunity, use very sparingly
00043  *  a delay of -1U will call removeTimer() if it already exists, otherwise is ignored
00044  *  @param el the EventListener to send the timer event to
00045  *  @param sid the source ID to use on that event (if you need to send more info, send a pointer to a struct of your devising, typecasted as int)
00046  *  @param delay the delay between the first (and future) calls
00047  *  @param repeat set to true if you want to keep receiving this event, otherwise it will only send once */
00048 void EventRouter::addTimer(EventListener* el, unsigned int sid, unsigned int delay, bool repeat) {
00049   if(delay==-1U) {
00050     removeTimer(el,sid);
00051     return;
00052   }
00053   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00054     if((*it)->el==el && (*it)->sid==sid) {
00055       (*it)->Set(delay,repeat);
00056       // now put that timer back into the correct place in the ordering (think before touching this! ;)
00057       if(it!=timers.begin() && (*it)->next<(*(it-1))->next)
00058         rotate(upper_bound(timers.begin(),it,*it,TimerEntryPtrCmp()),it,it+1);
00059       else if(it+1!=timers.end() && (*it)->next>(*(it+1))->next)
00060         rotate(it,it+1,lower_bound(it+1,timers.end(),*it,TimerEntryPtrCmp()));
00061       return;
00062     }
00063   //didn't find a pre-existing one
00064   TimerEntry * add=new TimerEntry(el,sid,delay,repeat);
00065   timers.insert(lower_bound(timers.begin(),timers.end(),add,TimerEntryPtrCmp()),add);
00066   //  chkTimers();
00067 }
00068 
00069 void EventRouter::addListener(EventListener* el, const EventBase& e) {
00070   if(e.getGeneratorID()==EventBase::timerEGID)
00071     addTimer(el,e.getSourceID(),e.getDuration());
00072   else
00073     listeners.addMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID());
00074 }
00075 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid) {
00076   listeners.addMapping(el,egid); 
00077 }
00078 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00079   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00080     listeners.addMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00081 }
00082 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00083   listeners.addMapping(el,egid,sid,etid);
00084 }
00085 
00086 void EventRouter::removeListener(EventListener* el, const EventBase& e) {
00087   if(e.getGeneratorID()==EventBase::timerEGID)
00088     removeTimer(el,e.getSourceID());
00089   else {
00090     listeners.removeMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID());
00091     listeners.clean();
00092   }
00093 }
00094 
00095 void EventRouter::removeTimer(EventListener* el) {
00096   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00097     if((*it)->el==el) {
00098       delete *it;
00099       *it=NULL;
00100     }
00101   timers.erase(remove(timers.begin(),timers.end(),(const TimerEntry*)NULL),timers.end());
00102 }
00103 
00104 void EventRouter::removeTimer(EventListener* el, unsigned int sid) {
00105   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00106     if((*it)->el==el && (*it)->sid==sid) {
00107       delete *it;
00108       timers.erase(it);
00109       return;
00110     }
00111 }
00112 
00113 void EventRouter::removeAllTimers() {
00114   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00115     delete *it;
00116   timers.erase(timers.begin(),timers.end());
00117 }
00118 
00119 void EventRouter::processEventBuffer() { //clears buffered events
00120   if(events.size()>0)
00121     doSendBuffer();
00122 }
00123 void EventRouter::doSendBuffer() {
00124   if(doSendBufferLock) {
00125     std::cout << "*** WARNING recursive call to doSendBuffer()" << std::endl;
00126     return;
00127   }
00128   doSendBufferLock=true;
00129   unsigned int start=get_time();
00130   //  doSendEvent(EventBase(EventBase::eventRouterEGID,0,EventBase::activateETID,0));
00131   //important to use indexes instead of iterators in case the event listeners decide to post more events during processing
00132   for(unsigned int i=0; i<events.size(); i++) {
00133     doSendEvent(*events[i]);
00134     delete events[i];
00135   }
00136   events.erase(events.begin(),events.end());
00137   doSendBufferLock=false;
00138   lastBufClear=start;
00139   //  doSendEvent(EventBase(EventBase::eventRouterEGID,0,EventBase::deactivateETID,get_time()-start));
00140 }
00141 
00142 void EventRouter::processEvent(const EventBase& e) {
00143   // want to make sure we don't send events out of order...
00144   if(events.size()>0)
00145     doSendBuffer();
00146   doSendEvent(e);
00147 }
00148 void EventRouter::doSendEvent(const EventBase& e) {
00149   //  cout << "doSendEvent("<<e.getName()<<")..." << flush;
00150   std::vector<EventTrapper*> t;
00151   trappers.getMapping(e,t);
00152   for(std::vector<EventTrapper*>::iterator it=t.begin(); it!=t.end(); it++)
00153     if(trappers.verifyMapping(*it,e))
00154       if((*it)->trapEvent(e))
00155         return;
00156   std::vector<EventListener*> l;
00157   listeners.getMapping(e,l);
00158   for(std::vector<EventListener*>::iterator it=l.begin(); it!=l.end(); it++)
00159     if(listeners.verifyMapping(*it,e))
00160       (*it)->processEvent(e);
00161   //  cout << "done." << flush;
00162 }
00163 
00164 EventRouter::EventMapper::EventMapper() {
00165   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00166     for(unsigned int et=0; et<EventBase::numETIDs; et++)
00167       filteredevents[eg][et]=NULL;
00168 }
00169 
00170 void EventRouter::EventMapper::addMapping(void* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00171   if(filteredevents[egid][etid]==NULL) //if this is the first subscriber to this EGID and ETID
00172     filteredevents[egid][etid]=new SIDtoListenerVectorMap_t(); 
00173   SIDtoListenerVectorMap_t::iterator it=filteredevents[egid][etid]->find(sid); // now find subscribers to the source id as well
00174   std::vector<void*>* elv=NULL;
00175   if(it==filteredevents[egid][etid]->end()) { // if this is the first subscriber to the source ID
00176     std::pair<const unsigned int,std::vector<void*> > p(sid,std::vector<void*>());
00177     //    p.first=sid; //p.second is a vector, only needs to be constructed
00178     filteredevents[egid][etid]->insert(p);
00179     elv=&(*filteredevents[egid][etid]->find(sid)).second;
00180   } else {
00181     elv=&(*it).second;
00182   }
00183   elv->push_back(el); // now that everything's set up, we can add the listener
00184 }
00185 
00186 void EventRouter::EventMapper::removeMapping(void* el, EventBase::EventGeneratorID_t egid) {
00187   // remove listener from allevents
00188   allevents[egid].erase(remove(allevents[egid].begin(),allevents[egid].end(),el),allevents[egid].end());
00189   
00190   // now remove listener from all of the filtered events
00191   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00192     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00193     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00194       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00195       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) {// go through each sourceID, delete EL
00196         std::vector<void*> * v=&(*mapit).second;
00197         v->erase(remove(v->begin(),v->end(),el),v->end());
00198       }
00199     }
00200   }
00201 }
00202 
00203 void EventRouter::EventMapper::removeMapping(void* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00204   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00205   if(mapping!=NULL) { // if there are subscribers to this egid/etid
00206     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00207     if(mapit!=mapping->end()) {
00208       std::vector<void*> * v=&(*mapit).second;
00209       v->erase(remove(v->begin(),v->end(),el),v->end());
00210     }
00211   }
00212 }
00213 
00214 void EventRouter::EventMapper::clean() {
00215   // first, remove any empty sid vectors from all the mappings
00216   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00217     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00218       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00219       if(mapping!=NULL) { // if there are subscribers to this egid/etid
00220         SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00221         bool done=false;
00222         while(!done) {
00223           done=true;
00224           for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) { // go through each sourceID vector
00225             if((*mapit).second.size()==0) {
00226               mapping->erase(mapit);
00227               done=false;
00228               break;
00229             }
00230           }
00231         }
00232       }
00233     }
00234   }
00235   // now remove any empty mappings
00236   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00237     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00238       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00239       if(mapping!=NULL) { // if there are subscribers to this egid/etid
00240         if(mapping->size()==0) {
00241           delete mapping;
00242           filteredevents[eg][et]=NULL;
00243         }
00244       }
00245     }
00246   }
00247 }
00248 
00249 void EventRouter::EventMapper::clear() {
00250   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00251     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00252       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00253       if(mapping!=NULL) { // don't beat a dead horse!
00254         mapping->erase(mapping->begin(),mapping->end());
00255         delete mapping;
00256         filteredevents[eg][et]=NULL;
00257       }
00258     }
00259   }
00260 }
00261 
00262 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid) {
00263   if(allevents[egid].size()>0)
00264     return true;
00265   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00266     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00267     if(mapping!=NULL) {
00268       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00269       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00270         if((*mapit).second.size()>0)
00271           return true;
00272     }
00273   }
00274   return false;
00275 }
00276 
00277 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, unsigned int sid) {
00278   if(allevents[egid].size()>0)
00279     return true;
00280   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00281     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00282     if(mapping!=NULL) {
00283       SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00284       if(mapit!=mapping->end() && (*mapit).second.size()>0)
00285         return true;
00286     }
00287   }
00288   return false;
00289 }
00290 
00291 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00292   if(allevents[egid].size()>0)
00293     return true;
00294   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00295   if(mapping!=NULL) {
00296     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00297     if(mapit!=mapping->end())
00298       return ((*mapit).second.size()>0);
00299   }
00300   return false;
00301 }
00302 
00303 template<class T>
00304 void EventRouter::EventMapper::getMapping(const EventBase& e, std::vector<T*>& ls) {
00305   // first get all the filtered subscribers (tricky!)
00306   std::vector<void*>* elv=NULL;
00307   SIDtoListenerVectorMap_t* sidtovm=filteredevents[e.getGeneratorID()][e.getTypeID()];
00308   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00309     SIDtoListenerVectorMap_t::iterator mapit=sidtovm->find(e.getSourceID()); // find listening for this source id
00310     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00311       elv=&(*mapit).second; // now go through them all
00312       for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00313         ls.push_back(static_cast<T*>(*elit));
00314     }
00315   }
00316   // now get the 'all events' subscribers
00317   elv=&allevents[e.getGeneratorID()];
00318   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00319     ls.push_back(static_cast<T*>(*elit));
00320 }
00321 
00322 bool EventRouter::EventMapper::verifyMapping(void * listener, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00323   // first get all the filtered subscribers (tricky!)
00324   std::vector<void*>* elv=NULL;
00325   SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][etid];
00326   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00327     SIDtoListenerVectorMap_t::iterator mapit=sidtovm->find(sid); // find listening for this source id
00328     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00329       elv=&(*mapit).second; // now go through them all
00330       for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00331         if(*elit==listener)
00332           return true;
00333     }
00334   }
00335   // now get the 'all events' subscribers
00336   elv=&allevents[egid];
00337   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00338     if(*elit==listener)
00339       return true;
00340 
00341   // if we haven't found it, doesn't exist:
00342   return false;
00343 }
00344 
00345 
00346 /*! @file
00347  * @brief Implements EventRouter class, for distribution and trapping of events to listeners
00348  * @author ejt (Creator)
00349  *
00350  * $Author: ejt $
00351  * $Name: tekkotsu-2_1 $
00352  * $Revision: 1.10 $
00353  * $State: Rel $
00354  * $Date: 2003/10/03 03:41:01 $
00355  */
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 // Use hasListeners(*) it's faster, i doubt anyone would really care how many... (but just in case...)
00364 /*
00365 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid) {
00366   unsigned int ans=allevents[egid].size();
00367   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00368     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00369     if(mapping!=NULL) {
00370       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00371       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00372         ans+=(*mapit).second.size();
00373     }
00374   }
00375   return ans;
00376 }
00377 
00378 bool EventRouter::numListeners(EventBase::EventGeneratorID_t egid, unsigned int sid) {
00379   unsigned int ans=allevents[egid].size();
00380   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00381     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00382     if(mapping!=NULL) {
00383       SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00384       if(mapit!=mapping->end())
00385         ans+=(*mapit).second.size();
00386     }
00387   }
00388   return false;
00389 }
00390 
00391 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00392   unsigned int ans=allevents[egid].size();
00393   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00394   if(mapping!=NULL) {
00395     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00396     if(mapit!=mapping->end())
00397       ans+=(*mapit).second.size();
00398   }
00399   return ans;
00400 }
00401 */

Tekkotsu v2.1
Generated Tue Mar 16 23:19:13 2004 by Doxygen 1.3.5