Homepage Demos Overview Downloads Tutorials Reference
Credits
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Search

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((*it)->trapEvent(e))
00154       return;
00155   std::vector<EventListener*> l;
00156   listeners.getMapping(e,l);
00157   for(std::vector<EventListener*>::iterator it=l.begin(); it!=l.end(); it++)
00158     (*it)->processEvent(e);
00159   //  cout << "done." << flush;
00160 }
00161 
00162 EventRouter::EventMapper::EventMapper() {
00163   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00164     for(unsigned int et=0; et<EventBase::numETIDs; et++)
00165       filteredevents[eg][et]=NULL;
00166 }
00167 
00168 void EventRouter::EventMapper::addMapping(void* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00169   if(filteredevents[egid][etid]==NULL) //if this is the first subscriber to this EGID and ETID
00170     filteredevents[egid][etid]=new SIDtoListenerVectorMap_t(); 
00171   SIDtoListenerVectorMap_t::iterator it=filteredevents[egid][etid]->find(sid); // now find subscribers to the source id as well
00172   std::vector<void*>* elv=NULL;
00173   if(it==filteredevents[egid][etid]->end()) { // if this is the first subscriber to the source ID
00174     std::pair<const unsigned int,std::vector<void*> > p(sid,std::vector<void*>());
00175     //    p.first=sid; //p.second is a vector, only needs to be constructed
00176     filteredevents[egid][etid]->insert(p);
00177     elv=&(*filteredevents[egid][etid]->find(sid)).second;
00178   } else {
00179     elv=&(*it).second;
00180   }
00181   elv->push_back(el); // now that everything's set up, we can add the listener
00182 }
00183 
00184 void EventRouter::EventMapper::removeMapping(void* el, EventBase::EventGeneratorID_t egid) {
00185   // remove listener from allevents
00186   allevents[egid].erase(remove(allevents[egid].begin(),allevents[egid].end(),el),allevents[egid].end());
00187   
00188   // now remove listener from all of the filtered events
00189   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00190     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00191     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00192       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00193       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) {// go through each sourceID, delete EL
00194         std::vector<void*> * v=&(*mapit).second;
00195         v->erase(remove(v->begin(),v->end(),el),v->end());
00196       }
00197     }
00198   }
00199 }
00200 
00201 void EventRouter::EventMapper::removeMapping(void* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00202   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00203   if(mapping!=NULL) { // if there are subscribers to this egid/etid
00204     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00205     if(mapit!=mapping->end()) {
00206       std::vector<void*> * v=&(*mapit).second;
00207       v->erase(remove(v->begin(),v->end(),el),v->end());
00208     }
00209   }
00210 }
00211 
00212 void EventRouter::EventMapper::clean() {
00213   // first, remove any empty sid vectors from all the mappings
00214   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00215     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00216       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00217       if(mapping!=NULL) { // if there are subscribers to this egid/etid
00218         SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00219         bool done=false;
00220         while(!done) {
00221           done=true;
00222           for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) { // go through each sourceID vector
00223             if((*mapit).second.size()==0) {
00224               mapping->erase(mapit);
00225               done=false;
00226               break;
00227             }
00228           }
00229         }
00230       }
00231     }
00232   }
00233   // now remove any empty mappings
00234   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00235     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00236       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00237       if(mapping!=NULL) { // if there are subscribers to this egid/etid
00238         if(mapping->size()==0) {
00239           delete mapping;
00240           filteredevents[eg][et]=NULL;
00241         }
00242       }
00243     }
00244   }
00245 }
00246 
00247 void EventRouter::EventMapper::clear() {
00248   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00249     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00250       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00251       if(mapping!=NULL) { // don't beat a dead horse!
00252         mapping->erase(mapping->begin(),mapping->end());
00253         delete mapping;
00254         filteredevents[eg][et]=NULL;
00255       }
00256     }
00257   }
00258 }
00259 
00260 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid) {
00261   if(allevents[egid].size()>0)
00262     return true;
00263   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00264     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00265     if(mapping!=NULL) {
00266       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00267       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00268         if((*mapit).second.size()>0)
00269           return true;
00270     }
00271   }
00272   return false;
00273 }
00274 
00275 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, unsigned int sid) {
00276   if(allevents[egid].size()>0)
00277     return true;
00278   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00279     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00280     if(mapping!=NULL) {
00281       SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00282       if(mapit!=mapping->end() && (*mapit).second.size()>0)
00283         return true;
00284     }
00285   }
00286   return false;
00287 }
00288 
00289 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00290   if(allevents[egid].size()>0)
00291     return true;
00292   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00293   if(mapping!=NULL) {
00294     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00295     if(mapit!=mapping->end())
00296       return ((*mapit).second.size()>0);
00297   }
00298   return false;
00299 }
00300 
00301 template<class T>
00302 void EventRouter::EventMapper::getMapping(const EventBase& e, std::vector<T*>& ls) {
00303   // first get all the filtered subscribers (tricky!)
00304   std::vector<void*>* elv=NULL;
00305   SIDtoListenerVectorMap_t* sidtovm=filteredevents[e.getGeneratorID()][e.getTypeID()];
00306   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00307     SIDtoListenerVectorMap_t::iterator mapit=sidtovm->find(e.getSourceID()); // find listening for this source id
00308     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00309       elv=&(*mapit).second; // now go through them all
00310       for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00311         ls.push_back(static_cast<T*>(*elit));
00312     }
00313   }
00314   // now get the 'all events' subscribers
00315   elv=&allevents[e.getGeneratorID()];
00316   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00317     ls.push_back(static_cast<T*>(*elit));
00318 }
00319 
00320 /*! @file
00321  * @brief Implements EventRouter class, for distribution and trapping of events to listeners
00322  * @author ejt (Creator)
00323  *
00324  * $Author: ejt $
00325  * $Name: tekkotsu-1_4_1 $
00326  * $Revision: 1.8 $
00327  * $State: Exp $
00328  * $Date: 2003/06/09 08:05:13 $
00329  */
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 // Use hasListeners(*) it's faster, i doubt anyone would really care how many... (but just in case...)
00338 /*
00339 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid) {
00340   unsigned int ans=allevents[egid].size();
00341   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00342     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00343     if(mapping!=NULL) {
00344       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00345       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00346         ans+=(*mapit).second.size();
00347     }
00348   }
00349   return ans;
00350 }
00351 
00352 bool EventRouter::numListeners(EventBase::EventGeneratorID_t egid, unsigned int sid) {
00353   unsigned int ans=allevents[egid].size();
00354   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00355     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00356     if(mapping!=NULL) {
00357       SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00358       if(mapit!=mapping->end())
00359         ans+=(*mapit).second.size();
00360     }
00361   }
00362   return false;
00363 }
00364 
00365 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00366   unsigned int ans=allevents[egid].size();
00367   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00368   if(mapping!=NULL) {
00369     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00370     if(mapit!=mapping->end())
00371       ans+=(*mapit).second.size();
00372   }
00373   return ans;
00374 }
00375 */

Tekkotsu v1.4
Generated Sat Jul 19 00:06:30 2003 by Doxygen 1.3.2