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\n
00042  *  a delay of 0 with repeating will cause an event to be sent at every opportunity, use sparingly\n
00043  *  a delay of -1U will call removeTimer() if it already exists, otherwise is ignored\n
00044  *
00045  *  To add a timer, you can also call addListener() with EventBase::timerEGID and the sid
00046  *  and delay (in the EventBase::duration field) - this method will simply cause this
00047  *  function to be called internally.
00048  *
00049  *  @param el the EventListener to send the timer event to
00050  *  @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)
00051  *  @param delay the delay between the first (and future) calls
00052  *  @param repeat set to true if you want to keep receiving this event, otherwise it will only send once */
00053 void EventRouter::addTimer(EventListener* el, unsigned int sid, unsigned int delay, bool repeat) {
00054   if(delay==-1U) {
00055     removeTimer(el,sid);
00056     return;
00057   }
00058   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00059     if((*it)->el==el && (*it)->sid==sid) {
00060       (*it)->Set(delay,repeat);
00061       // now put that timer back into the correct place in the ordering (think before touching this! ;)
00062       if(it!=timers.begin() && (*it)->next<(*(it-1))->next)
00063         rotate(upper_bound(timers.begin(),it,*it,TimerEntryPtrCmp()),it,it+1);
00064       else if(it+1!=timers.end() && (*it)->next>(*(it+1))->next)
00065         rotate(it,it+1,lower_bound(it+1,timers.end(),*it,TimerEntryPtrCmp()));
00066       return;
00067     }
00068   //didn't find a pre-existing one
00069   TimerEntry * add=new TimerEntry(el,sid,delay,repeat);
00070   timers.insert(lower_bound(timers.begin(),timers.end(),add,TimerEntryPtrCmp()),add);
00071   //  chkTimers();
00072 }
00073 
00074 void EventRouter::removeTimer(EventListener* el) {
00075   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00076     if((*it)->el==el) {
00077       delete *it;
00078       *it=NULL;
00079     }
00080   timers.erase(remove(timers.begin(),timers.end(),(const TimerEntry*)NULL),timers.end());
00081 }
00082 
00083 void EventRouter::removeTimer(EventListener* el, unsigned int sid) {
00084   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00085     if((*it)->el==el && (*it)->sid==sid) {
00086       delete *it;
00087       timers.erase(it);
00088       return;
00089     }
00090 }
00091 
00092 void EventRouter::removeAllTimers() {
00093   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00094     delete *it;
00095   timers.erase(timers.begin(),timers.end());
00096 }
00097 
00098 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid) {
00099   if(egid==EventBase::timerEGID)
00100     printf("WARNING: The use of addListener with timerEGID is deprecated,\n"
00101                  "         please see http://bugs.tekkotsu.org/show_bug.cgi?id=89\n");
00102   bool hadListener=hasListeners(egid);
00103   listeners.addMapping(el,egid); 
00104   if(!hadListener)
00105     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00106   else
00107     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00108 }
00109 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00110   if(egid==EventBase::timerEGID)
00111     printf("WARNING: The use of addListener with timerEGID is deprecated,\n"
00112                  "         please see http://bugs.tekkotsu.org/show_bug.cgi?id=89\n");
00113   bool hadListener=hasListeners(egid);
00114   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00115     listeners.addMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00116   if(!hadListener)
00117     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00118   else
00119     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00120 }
00121 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00122   if(egid==EventBase::timerEGID)
00123     printf("WARNING: The use of addListener with timerEGID is deprecated,\n"
00124                  "         please see http://bugs.tekkotsu.org/show_bug.cgi?id=89\n");
00125   bool hadListener=hasListeners(egid);
00126   listeners.addMapping(el,egid,sid,etid);
00127   if(!hadListener)
00128     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00129   else
00130     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00131 }
00132 void EventRouter::addListener(EventListener* el, const EventBase& e) {
00133   if(e.getGeneratorID()==EventBase::timerEGID) {
00134     printf("WARNING: The use of addListener with timerEGID is deprecated,\n"
00135                  "         please see http://bugs.tekkotsu.org/show_bug.cgi?id=89\n");
00136     addTimer(el,e.getSourceID(),e.getDuration());
00137   } else {
00138     bool hadListener=hasListeners(e.getGeneratorID());
00139     listeners.addMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID());
00140     if(!hadListener)
00141       postEvent(new EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::activateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00142     else
00143       postEvent(new EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00144   }
00145 }
00146 
00147 void EventRouter::removeListener(EventListener* el) {
00148   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00149     removeListener(el,(EventBase::EventGeneratorID_t)eg);
00150 }
00151 void EventRouter::removeListener(EventListener* el, EventBase::EventGeneratorID_t egid) {
00152   if(egid==EventBase::timerEGID)
00153     removeTimer(el);
00154   else {
00155     if(!listeners.removeMapping(el,egid))
00156       return; //nothing was removed, don't want to clean up or throw an event
00157     listeners.clean(egid);
00158     if(!hasListeners(egid))
00159       postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00160     else
00161       postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00162   }
00163 }
00164 void EventRouter::removeListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00165   if(egid==EventBase::timerEGID)
00166     removeTimer(el,sid);
00167   else {
00168     unsigned int removed=0;
00169     for(unsigned int et=0; et<EventBase::numETIDs; et++)
00170       removed+=listeners.removeMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00171     if(!removed)
00172       return; //nothing was removed, don't want to clean up or throw an event
00173     listeners.clean(egid);
00174     if(!hasListeners(egid))
00175       postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00176     else
00177       postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00178   }
00179 }
00180 void EventRouter::removeListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00181   if(egid==EventBase::timerEGID) {
00182     if(etid==EventBase::statusETID)
00183       removeTimer(el,sid);
00184   } else {
00185     if(!listeners.removeMapping(el,egid,sid,etid))
00186       return; //nothing was removed, don't want to clean up or throw an event
00187     listeners.clean(egid);
00188     if(!hasListeners(egid))
00189       postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00190     else
00191       postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00192   }
00193 }
00194 void EventRouter::removeListener(EventListener* el, const EventBase& e) {
00195   if(e.getGeneratorID()==EventBase::timerEGID)
00196     removeTimer(el,e.getSourceID());
00197   else {
00198     if(!listeners.removeMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID()))
00199       return; //nothing was removed, don't want to clean up or throw an event
00200     listeners.clean(e.getGeneratorID());
00201     if(!hasListeners(e.getGeneratorID()))
00202       postEvent(new EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::deactivateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],0));
00203     else
00204       postEvent(new EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00205   }
00206 }
00207 
00208 void EventRouter::forgetListener(EventListener* el) {
00209   removeListener(el);
00210 }
00211 
00212 void EventRouter::addTrapper(EventTrapper* el, const EventBase& e) {
00213   bool hadListener=hasListeners(e.getGeneratorID());
00214   trappers.addMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID());
00215   if(!hadListener)
00216     postEvent(new EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::activateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00217   else
00218     postEvent(new EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00219 }
00220 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00221 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid) {
00222   bool hadListener=hasListeners(egid);
00223   trappers.addMapping(el,egid);
00224   if(!hadListener)
00225     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00226   else
00227     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00228 }
00229 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00230 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00231   bool hadListener=hasListeners(egid);
00232   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00233     trappers.addMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00234   if(!hadListener)
00235     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00236   else
00237     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00238 }
00239 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00240 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00241   bool hadListener=hasListeners(egid);
00242   trappers.addMapping(el,egid,sid,etid);
00243   if(!hadListener)
00244     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00245   else
00246     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00247 }
00248 
00249 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00250 void EventRouter::addTrapper(EventTrapper* el) {
00251   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00252     addTrapper(el,(EventBase::EventGeneratorID_t)eg);
00253 }
00254 
00255 
00256 void EventRouter::removeTrapper(EventTrapper* el, const EventBase& e) {
00257   if(!trappers.removeMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID()))
00258     return; //nothing was removed, don't want to clean up or throw an event
00259   trappers.clean(e.getGeneratorID());
00260   if(!hasListeners(e.getGeneratorID()))
00261     postEvent(new EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::deactivateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],0));
00262   else
00263     postEvent(new EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00264 }
00265 void EventRouter::removeTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid) {
00266   if(!trappers.removeMapping(el,egid))
00267     return; //nothing was removed, don't want to clean up or throw an event
00268   trappers.clean(egid);
00269   if(!hasListeners(egid))
00270     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00271   else
00272     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00273 }
00274 void EventRouter::removeTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00275   int removed=0;
00276   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00277     removed+=trappers.removeMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00278   if(!removed)
00279     return; //nothing was removed, don't want to clean up or throw an event
00280   trappers.clean(egid);
00281   if(!hasListeners(egid))
00282     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00283   else
00284     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00285 }
00286 void EventRouter::removeTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00287   if(!trappers.removeMapping(el,egid,sid,etid))
00288     return; //nothing was removed, don't want to clean up or throw an event
00289   trappers.clean(egid);
00290   if(!hasListeners(egid))
00291     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00292   else
00293     postEvent(new EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00294 }
00295 
00296 void EventRouter::removeTrapper(EventTrapper* el) {
00297   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00298     removeTrapper(el,(EventBase::EventGeneratorID_t)eg);
00299 }
00300 
00301 void EventRouter::processEventBuffer() { //clears buffered events
00302   if(events.size()>0)
00303     doSendBuffer();
00304 }
00305 void EventRouter::doSendBuffer() {
00306   if(doSendBufferLock) {
00307     std::cout << "*** WARNING recursive call to doSendBuffer()" << std::endl;
00308     return;
00309   }
00310   doSendBufferLock=true;
00311   unsigned int start=get_time();
00312   //  doSendEvent(EventBase(EventBase::eventRouterEGID,0,EventBase::activateETID,0));
00313   //important to use indexes instead of iterators in case the event listeners decide to post more events during processing
00314   for(unsigned int i=0; i<events.size(); i++) {
00315     doSendEvent(*events[i]);
00316     delete events[i];
00317   }
00318   events.erase(events.begin(),events.end());
00319   doSendBufferLock=false;
00320   lastBufClear=start;
00321   //  doSendEvent(EventBase(EventBase::eventRouterEGID,0,EventBase::deactivateETID,get_time()-start));
00322 }
00323 
00324 void EventRouter::processEvent(const EventBase& e) {
00325   // want to make sure we don't send events out of order...
00326   if(events.size()>0)
00327     doSendBuffer();
00328   doSendEvent(e);
00329 }
00330 void EventRouter::doSendEvent(const EventBase& e) {
00331   //  cout << "doSendEvent("<<e.getName()<<")..." << flush;
00332   std::vector<EventTrapper*> t;
00333   trappers.getMapping(e,t);
00334   for(std::vector<EventTrapper*>::iterator it=t.begin(); it!=t.end(); it++)
00335     if(trappers.verifyMapping(*it,e))
00336       if((*it)->trapEvent(e))
00337         return;
00338   std::vector<EventListener*> l;
00339   listeners.getMapping(e,l);
00340   for(std::vector<EventListener*>::iterator it=l.begin(); it!=l.end(); it++)
00341     if(listeners.verifyMapping(*it,e))
00342       (*it)->processEvent(e);
00343   //  cout << "done." << flush;
00344 }
00345 
00346 EventRouter::EventMapper::EventMapper() {
00347   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00348     for(unsigned int et=0; et<EventBase::numETIDs; et++)
00349       filteredevents[eg][et]=NULL;
00350 }
00351 
00352 void EventRouter::EventMapper::addMapping(void* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00353   if(filteredevents[egid][etid]==NULL) //if this is the first subscriber to this EGID and ETID
00354     filteredevents[egid][etid]=new SIDtoListenerVectorMap_t(); 
00355   SIDtoListenerVectorMap_t::iterator it=filteredevents[egid][etid]->find(sid); // now find subscribers to the source id as well
00356   std::vector<void*>* elv=NULL;
00357   if(it==filteredevents[egid][etid]->end()) { // if this is the first subscriber to the source ID
00358     std::pair<const unsigned int,std::vector<void*> > p(sid,std::vector<void*>());
00359     //    p.first=sid; //p.second is a vector, only needs to be constructed
00360     filteredevents[egid][etid]->insert(p);
00361     elv=&(*filteredevents[egid][etid]->find(sid)).second;
00362   } else {
00363     elv=&(*it).second;
00364   }
00365   elv->push_back(el); // now that everything's set up, we can add the listener
00366 }
00367 
00368 bool EventRouter::EventMapper::removeMapping(void* el, EventBase::EventGeneratorID_t egid) {
00369   // remove listener from allevents
00370   unsigned int numlist=allevents[egid].size();
00371   allevents[egid].erase(remove(allevents[egid].begin(),allevents[egid].end(),el),allevents[egid].end());
00372   bool hadListener=allevents[egid].size()!=numlist;
00373   
00374   // now remove listener from all of the filtered events
00375   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00376     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00377     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00378       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00379       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) {// go through each sourceID, delete EL
00380         std::vector<void*> * v=&(*mapit).second;
00381         std::vector<void*>::iterator last=remove(v->begin(),v->end(),el);
00382         if(last!=v->end()) {
00383           hadListener=true;
00384           v->erase(last,v->end());
00385         }
00386       }
00387     }
00388   }
00389   return hadListener;
00390 }
00391 
00392 bool EventRouter::EventMapper::removeMapping(void* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00393   bool hadListener=false;
00394   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00395   if(mapping!=NULL) { // if there are subscribers to this egid/etid
00396     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00397     if(mapit!=mapping->end()) {
00398       std::vector<void*> * v=&(*mapit).second;
00399       std::vector<void*>::iterator last=remove(v->begin(),v->end(),el);
00400       if(last!=v->end()) {
00401         hadListener=true;
00402         v->erase(last,v->end());
00403       }
00404     }
00405   }
00406   return hadListener;
00407 }
00408 
00409 void EventRouter::EventMapper::clean() {
00410   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00411     clean((EventBase::EventGeneratorID_t)eg);
00412 }
00413 void EventRouter::EventMapper::clean(EventBase::EventGeneratorID_t egid) {
00414   // first, remove any empty sid vectors from all the mappings
00415   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00416     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00417     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00418       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00419       bool done=false;
00420       while(!done) {
00421         done=true;
00422         for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) { // go through each sourceID vector
00423           if((*mapit).second.size()==0) {
00424             mapping->erase(mapit);
00425             done=false;
00426             break;
00427           }
00428         }
00429       }
00430     }
00431   }
00432   // now remove any empty mappings
00433   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00434     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00435     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00436       if(mapping->size()==0) {
00437         delete mapping;
00438         filteredevents[egid][et]=NULL;
00439       }
00440     }
00441   }
00442 }
00443 
00444 void EventRouter::EventMapper::clear() {
00445   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00446     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00447       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00448       if(mapping!=NULL) { // don't beat a dead horse!
00449         mapping->erase(mapping->begin(),mapping->end());
00450         delete mapping;
00451         filteredevents[eg][et]=NULL;
00452       }
00453     }
00454   }
00455 }
00456 
00457 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid) {
00458   if(allevents[egid].size()>0)
00459     return true;
00460   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00461     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00462     if(mapping!=NULL) {
00463       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00464       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00465         if((*mapit).second.size()>0)
00466           return true;
00467     }
00468   }
00469   return false;
00470 }
00471 
00472 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, unsigned int sid) {
00473   if(allevents[egid].size()>0)
00474     return true;
00475   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00476     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00477     if(mapping!=NULL) {
00478       SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00479       if(mapit!=mapping->end() && (*mapit).second.size()>0)
00480         return true;
00481     }
00482   }
00483   return false;
00484 }
00485 
00486 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00487   if(allevents[egid].size()>0)
00488     return true;
00489   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00490   if(mapping!=NULL) {
00491     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00492     if(mapit!=mapping->end())
00493       return ((*mapit).second.size()>0);
00494   }
00495   return false;
00496 }
00497 
00498 template<class T>
00499 void EventRouter::EventMapper::getMapping(const EventBase& e, std::vector<T*>& ls) {
00500   // first get all the filtered subscribers (tricky!)
00501   std::vector<void*>* elv=NULL;
00502   SIDtoListenerVectorMap_t* sidtovm=filteredevents[e.getGeneratorID()][e.getTypeID()];
00503   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00504     SIDtoListenerVectorMap_t::iterator mapit=sidtovm->find(e.getSourceID()); // find listening for this source id
00505     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00506       elv=&(*mapit).second; // now go through them all
00507       for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00508         ls.push_back(static_cast<T*>(*elit));
00509     }
00510   }
00511   // now get the 'all events' subscribers
00512   elv=&allevents[e.getGeneratorID()];
00513   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00514     ls.push_back(static_cast<T*>(*elit));
00515 }
00516 
00517 bool EventRouter::EventMapper::verifyMapping(void * listener, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00518   // first check the 'all events' subscribers
00519   std::vector<void*>* elv=&allevents[egid];
00520   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00521     if(*elit==listener)
00522       return true;
00523   
00524   // then check all the filtered subscribers (tricky!)
00525   SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][etid];
00526   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00527     SIDtoListenerVectorMap_t::iterator mapit=sidtovm->find(sid); // find listening for this source id
00528     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00529       elv=&(*mapit).second; // now go through them all
00530       for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00531         if(*elit==listener)
00532           return true;
00533     }
00534   }
00535 
00536   // if we haven't found it, doesn't exist:
00537   return false;
00538 }
00539 
00540 bool EventRouter::EventMapper::verifyMappingAll(void* listener, EventBase::EventGeneratorID_t egid) {
00541   std::vector<void*>* elv=&allevents[egid];
00542   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00543     if(*elit==listener)
00544       return true;
00545   // if not in the all listeners, can't be listening for *every* source id
00546   return false;
00547 }
00548 
00549 bool EventRouter::EventMapper::verifyMappingAny(void* listener, EventBase::EventGeneratorID_t egid) {
00550   // first check the 'all events' subscribers
00551   std::vector<void*>* elv=&allevents[egid];
00552   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00553     if(*elit==listener)
00554       return true;
00555   
00556   // then check all the filtered subscribers (tricky!)
00557   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00558     SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00559     if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00560       SIDtoListenerVectorMap_t::iterator mapit=sidtovm->begin(); // for each of the source ids
00561       for(;mapit!=sidtovm->end();mapit++) {
00562         elv=&(*mapit).second; // now go through them all
00563         for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00564           if(*elit==listener)
00565             return true;
00566       }
00567     }
00568   }
00569 
00570   // if we haven't found any, none exist:
00571   return false;
00572 }
00573 
00574 bool EventRouter::EventMapper::verifyMappingAll(void* listener, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00575   // first check the 'all events' subscribers
00576   std::vector<void*>* elv=&allevents[egid];
00577   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00578     if(*elit==listener)
00579       return true;
00580   
00581   // then check all the filtered subscribers (tricky!)
00582   // must be found in ALL etids
00583   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00584     SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00585     if(sidtovm==NULL)
00586       return false;
00587     // there's a map (at least one EL is filtering on this EGID and ETID)
00588     SIDtoListenerVectorMap_t::iterator mapit=sidtovm->find(sid); // find listening for this source id
00589     if(mapit==sidtovm->end())
00590       return false;
00591     // there's at least one is filtering on this sourceID as well
00592     elv=&(*mapit).second; // now go through them all
00593     std::vector<void*>::iterator elit=elv->begin();
00594     while(elit!=elv->end() && *elit!=listener)
00595       elit++;
00596     if(elit==elv->end())
00597       return false;
00598     //if we didn't return false, we found a match... continue checking other ETIDs
00599   }
00600 
00601   // we only got here if we *did* find listener in each of the ETIDs
00602   return true;
00603 }
00604 
00605 bool EventRouter::EventMapper::verifyMappingAny(void* listener, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00606   // first check the 'all events' subscribers
00607   std::vector<void*>* elv=&allevents[egid];
00608   for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00609     if(*elit==listener)
00610       return true;
00611   
00612   // then check all the filtered subscribers (tricky!)
00613   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00614     SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00615     if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00616       SIDtoListenerVectorMap_t::iterator mapit=sidtovm->find(sid); // find listening for this source id
00617       if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00618         elv=&(*mapit).second; // now go through them all
00619         for(std::vector<void*>::iterator elit=elv->begin(); elit!=elv->end(); elit++)
00620           if(*elit==listener)
00621             return true;
00622       }
00623     }
00624   }
00625 
00626   // if we haven't found it, doesn't exist:
00627   return false;
00628 }
00629 
00630 /*! @file
00631  * @brief Implements EventRouter class, for distribution and trapping of events to listeners
00632  * @author ejt (Creator)
00633  *
00634  * $Author: ejt $
00635  * $Name: tekkotsu-2_3 $
00636  * $Revision: 1.16 $
00637  * $State: Exp $
00638  * $Date: 2005/01/29 00:01:57 $
00639  */
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 // Use hasListeners(*) it's faster, i doubt anyone would really care how many... (but just in case...)
00648 /*
00649 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid) {
00650   unsigned int ans=allevents[egid].size();
00651   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00652     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00653     if(mapping!=NULL) {
00654       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00655       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00656         ans+=(*mapit).second.size();
00657     }
00658   }
00659   return ans;
00660 }
00661 
00662 bool EventRouter::numListeners(EventBase::EventGeneratorID_t egid, unsigned int sid) {
00663   unsigned int ans=allevents[egid].size();
00664   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00665     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00666     if(mapping!=NULL) {
00667       SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00668       if(mapit!=mapping->end())
00669         ans+=(*mapit).second.size();
00670     }
00671   }
00672   return false;
00673 }
00674 
00675 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00676   unsigned int ans=allevents[egid].size();
00677   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00678   if(mapping!=NULL) {
00679     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00680     if(mapit!=mapping->end())
00681       ans+=(*mapit).second.size();
00682   }
00683   return ans;
00684 }
00685 */

Tekkotsu v2.3
Generated Sat Jan 29 02:25:21 2005 by Doxygen 1.4.0