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

Tekkotsu v2.4
Generated Wed Aug 10 11:04:37 2005 by Doxygen 1.4.4