Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

EventRouter.cc

Go to the documentation of this file.
00001 #include "EventRouter.h"
00002 #include "Shared/Profiler.h"
00003 #include "Behaviors/BehaviorBase.h"
00004 #include "Shared/ProjectInterface.h"
00005 #include <algorithm>
00006 #include "Events/TimerEvent.h"
00007 
00008 EventRouter * erouter=NULL;
00009 
00010 EventRouter::EventRouter()
00011   : timers(), trappers(), listeners(), postings()
00012 {}
00013 
00014 void EventRouter::postEvent(EventBase* e) { processEvent(*e); delete e; }
00015 
00016 //! @todo handle recursive calls
00017 void EventRouter::processTimers() {
00018   //    cout << "processTimers..." << flush;
00019   unsigned int curtime=get_time();
00020   TimerEntry curTimer(curtime);
00021   timer_it_t last_it=upper_bound(timers.begin(),timers.end(),&curTimer,TimerEntryPtrCmp());
00022   std::vector<TimerEntry*> process(timers.begin(),last_it); //copy these out for safe keeping
00023   for(timer_it_t it=process.begin(); it!=process.end(); it++) //increment the timers we're processing
00024     if(!(*it)->repeat)
00025       (*it)->next=(unsigned int)-1;
00026     else if((*it)->delay==0)
00027       (*it)->next=curtime+1;
00028     else while((*it)->next<=curtime)
00029       (*it)->next+=(*it)->delay;
00030   sort(timers.begin(),last_it,TimerEntryPtrCmp()); //re-sort the timers we're processing (at the beginning of timers)
00031   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)
00032   //  if(process.size()>0) chkTimers();
00033   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
00034     TimerEvent e((*it)->el,EventBase::timerEGID,(*it)->sid,EventBase::statusETID,(*it)->next-(*it)->delay);
00035     try {
00036       (*it)->el->processEvent(e);
00037     } catch(const std::exception& ex) {
00038       std::string msg="Occurred while processing event "+e.getName()+" by ";
00039       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>((*it)->el))
00040         msg+="listener "+beh->getName();
00041       else
00042         msg+="unnamed EventListener";
00043       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),&ex))
00044         throw;
00045     } catch(...) {
00046       std::string msg="Occurred while processing event "+e.getName()+" by ";
00047       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>((*it)->el))
00048         msg+="listener "+beh->getName();
00049       else
00050         msg+="unnamed EventListener";
00051       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),NULL))
00052         throw;
00053     }
00054     postEvent(e);
00055   }
00056   //  if(process.size()>0) chkTimers();
00057   static const TimerEntry deadTimer((unsigned int)-1); // matches all the dead ones as set in the incrementation phase
00058   last_it=lower_bound(timers.begin(),timers.end(),&deadTimer,TimerEntryPtrCmp()); //find the beginning of all the non-repeating timers we're clearing
00059   for(timer_it_t it=last_it; it!=timers.end(); it++) // delete all of them
00060     delete *it;
00061   timers.erase(last_it,timers.end()); //and then remove them from the timer list
00062   //  if(process.size()>0) chkTimers();
00063   //    cout << "done" << endl;
00064 }
00065 
00066 /*! timers are unique by EventListener and source ID - can't have two timers for the same el and sid\n
00067  *  a delay of 0 with repeating will cause an event to be sent at every opportunity, use sparingly\n
00068  *  a delay of -1U will call removeTimer() if it already exists, otherwise is ignored\n
00069  *
00070  *  @param el the EventListener to send the timer event to
00071  *  @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)
00072  *  @param delay the delay between the first (and future) calls
00073  *  @param repeat set to true if you want to keep receiving this event, otherwise it will only send once */
00074 void EventRouter::addTimer(EventListener* el, unsigned int sid, unsigned int delay, bool repeat) {
00075   if(delay==-1U) {
00076     removeTimer(el,sid);
00077     return;
00078   }
00079   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00080     if((*it)->el==el && (*it)->sid==sid) {
00081       (*it)->Set(delay,repeat);
00082       // now put that timer back into the correct place in the ordering (think before touching this! ;)
00083       if(it!=timers.begin() && (*it)->next<(*(it-1))->next)
00084         rotate(upper_bound(timers.begin(),it,*it,TimerEntryPtrCmp()),it,it+1);
00085       else if(it+1!=timers.end() && (*it)->next>(*(it+1))->next)
00086         rotate(it,it+1,lower_bound(it+1,timers.end(),*it,TimerEntryPtrCmp()));
00087       return;
00088     }
00089   //didn't find a pre-existing one
00090   TimerEntry * add=new TimerEntry(el,sid,delay,repeat);
00091   timers.insert(lower_bound(timers.begin(),timers.end(),add,TimerEntryPtrCmp()),add);
00092   //  chkTimers();
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(std::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::addListener(EventListener* el, EventBase::EventGeneratorID_t egid) {
00120   bool hadListener=hasListeners(egid);
00121   listeners.addMapping(el,egid); 
00122   if(!hadListener)
00123     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00124   else
00125     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00126 }
00127 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00128   bool hadListener=hasListeners(egid);
00129   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00130     listeners.addMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00131   if(!hadListener)
00132     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00133   else
00134     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00135 }
00136 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00137   bool hadListener=hasListeners(egid);
00138   listeners.addMapping(el,egid,sid,etid);
00139   if(!hadListener)
00140     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00141   else
00142     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00143 }
00144 void EventRouter::addListener(EventListener* el, const EventBase& e) {
00145   bool hadListener=hasListeners(e.getGeneratorID());
00146   listeners.addMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID());
00147   if(!hadListener)
00148     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::activateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00149   else
00150     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00151 }
00152 
00153 void EventRouter::removeListener(EventListener* el) {
00154   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00155     EventBase::EventGeneratorID_t egid=(EventBase::EventGeneratorID_t)eg;
00156     if(!listeners.removeMapping(el,egid))
00157       continue; //nothing was removed, don't want to clean up or throw an event
00158     listeners.clean(egid);
00159     if(!hasListeners(egid))
00160       postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00161     else
00162       postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00163   }
00164 }
00165 void EventRouter::removeListener(EventListener* el, EventBase::EventGeneratorID_t egid) {
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(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00171   else
00172     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00173 }
00174 void EventRouter::removeListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00175   unsigned int removed=0;
00176   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00177     removed+=listeners.removeMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00178   if(!removed)
00179     return; //nothing was removed, don't want to clean up or throw an event
00180   listeners.clean(egid);
00181   if(!hasListeners(egid))
00182     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00183   else
00184     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00185 }
00186 void EventRouter::removeListener(EventListener* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00187   if(!listeners.removeMapping(el,egid,sid,etid))
00188     return; //nothing was removed, don't want to clean up or throw an event
00189   listeners.clean(egid);
00190   if(!hasListeners(egid))
00191     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00192   else
00193     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00194 }
00195 void EventRouter::removeListener(EventListener* el, const EventBase& e) {
00196   if(!listeners.removeMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID()))
00197     return; //nothing was removed, don't want to clean up or throw an event
00198   listeners.clean(e.getGeneratorID());
00199   if(!hasListeners(e.getGeneratorID()))
00200     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::deactivateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],0));
00201   else
00202     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00203 }
00204 
00205 void EventRouter::addTrapper(EventTrapper* el, const EventBase& e) {
00206   bool hadListener=hasListeners(e.getGeneratorID());
00207   trappers.addMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID());
00208   if(!hadListener)
00209     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::activateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00210   else
00211     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00212 }
00213 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00214 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid) {
00215   bool hadListener=hasListeners(egid);
00216   trappers.addMapping(el,egid);
00217   if(!hadListener)
00218     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00219   else
00220     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00221 }
00222 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00223 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00224   bool hadListener=hasListeners(egid);
00225   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00226     trappers.addMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00227   if(!hadListener)
00228     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00229   else
00230     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00231 }
00232 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00233 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00234   bool hadListener=hasListeners(egid);
00235   trappers.addMapping(el,egid,sid,etid);
00236   if(!hadListener)
00237     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00238   else
00239     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00240 }
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) {
00244   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00245     addTrapper(el,(EventBase::EventGeneratorID_t)eg);
00246 }
00247 
00248 
00249 void EventRouter::removeTrapper(EventTrapper* el, const EventBase& e) {
00250   if(!trappers.removeMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID()))
00251     return; //nothing was removed, don't want to clean up or throw an event
00252   trappers.clean(e.getGeneratorID());
00253   if(!hasListeners(e.getGeneratorID()))
00254     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::deactivateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],0));
00255   else
00256     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00257 }
00258 void EventRouter::removeTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid) {
00259   if(!trappers.removeMapping(el,egid))
00260     return; //nothing was removed, don't want to clean up or throw an event
00261   trappers.clean(egid);
00262   if(!hasListeners(egid))
00263     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00264   else
00265     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00266 }
00267 void EventRouter::removeTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, unsigned int sid) {
00268   int removed=0;
00269   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00270     removed+=trappers.removeMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00271   if(!removed)
00272     return; //nothing was removed, don't want to clean up or throw an event
00273   trappers.clean(egid);
00274   if(!hasListeners(egid))
00275     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00276   else
00277     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00278 }
00279 void EventRouter::removeTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00280   if(!trappers.removeMapping(el,egid,sid,etid))
00281     return; //nothing was removed, don't want to clean up or throw an event
00282   trappers.clean(egid);
00283   if(!hasListeners(egid))
00284     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00285   else
00286     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00287 }
00288 
00289 void EventRouter::removeTrapper(EventTrapper* el) {
00290   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00291     removeTrapper(el,(EventBase::EventGeneratorID_t)eg);
00292 }
00293 
00294 void EventRouter::processEvent(const EventBase& e) {
00295   PostingStatus ps(trappers,listeners,e);
00296   postings.push(&ps);
00297   while(postings.size()>0) {
00298 #ifdef DEBUG
00299     unsigned int presize=postings.size();
00300     postings.front()->process();
00301     ASSERT(postings.size()==0 || postings.size()==presize,"partial queue completion?");
00302 #else
00303     postings.front()->process();
00304 #endif
00305     if(postings.size()>0) // in case a sub-post took over and finished off the queue
00306       postings.pop();
00307   }
00308 }
00309 
00310 void EventRouter::PostingStatus::process() {
00311   while(tit!=t.end()) {
00312     // increment before processing so if a new post is done during the processing, we pick up on the *next* entry
00313     EventTrapper * et=*tit++;
00314     if(!trappers.verifyMapping(et,e))
00315       continue;
00316     try {
00317       if(et->trapEvent(e))
00318         return;
00319     } catch(const std::exception& ex) {
00320       std::string msg="Occurred while processing event "+e.getName()+" by ";
00321       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>(et))
00322         msg+="trapper "+beh->getName();
00323       else
00324         msg+="unnamed EventTrapper";
00325       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),&ex))
00326         throw;
00327     } catch(...) {
00328       std::string msg="Occurred while processing event "+e.getName()+" by ";
00329       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>(et))
00330         msg+="trapper "+beh->getName();
00331       else
00332         msg+="unnamed EventTrapper";
00333       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),NULL))
00334         throw;
00335     }
00336   }
00337   while(lit!=l.end()) {
00338     // increment before processing so if a new post is done during the processing, we pick up on the *next* entry
00339     EventListener * el=*lit++;
00340     if(!listeners.verifyMapping(el,e))
00341       continue;
00342     try {
00343       el->processEvent(e);
00344     } catch(const std::exception& ex) {
00345       std::string msg="Occurred while processing event "+e.getName()+" by ";
00346       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>(el))
00347         msg+="listener "+beh->getName();
00348       else
00349         msg+="unnamed EventListener";
00350       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),&ex))
00351         throw;
00352     } catch(...) {
00353       std::string msg="Occurred while processing event "+e.getName()+" by ";
00354       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>(el))
00355         msg+="listener "+beh->getName();
00356       else
00357         msg+="unnamed EventListener";
00358       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),NULL))
00359         throw;
00360     }
00361   }
00362 }
00363 
00364 EventRouter::EventMapper::EventMapper() {
00365   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00366     for(unsigned int et=0; et<EventBase::numETIDs; et++)
00367       filteredevents[eg][et]=NULL;
00368 }
00369 
00370 void EventRouter::EventMapper::addMapping(void* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00371   if(filteredevents[egid][etid]==NULL) //if this is the first subscriber to this EGID and ETID
00372     filteredevents[egid][etid]=new SIDtoListenerVectorMap_t(); 
00373   SIDtoListenerVectorMap_t::iterator it=filteredevents[egid][etid]->find(sid); // now find subscribers to the source id as well
00374   std::vector<void*>* elv=NULL;
00375   if(it==filteredevents[egid][etid]->end()) { // if this is the first subscriber to the source ID
00376     std::pair<const unsigned int,std::vector<void*> > p(sid,std::vector<void*>());
00377     //    p.first=sid; //p.second is a vector, only needs to be constructed
00378     filteredevents[egid][etid]->insert(p);
00379     elv=&(*filteredevents[egid][etid]->find(sid)).second;
00380   } else {
00381     elv=&(*it).second;
00382   }
00383   elv->push_back(el); // now that everything's set up, we can add the listener
00384 }
00385 
00386 bool EventRouter::EventMapper::removeMapping(void* el, EventBase::EventGeneratorID_t egid) {
00387   // remove listener from allevents
00388   unsigned int numlist=allevents[egid].size();
00389   allevents[egid].erase(std::remove(allevents[egid].begin(),allevents[egid].end(),el),allevents[egid].end());
00390   bool hadListener=allevents[egid].size()!=numlist;
00391   
00392   // now remove listener from all of the filtered events
00393   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00394     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00395     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00396       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00397       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) {// go through each sourceID, delete EL
00398         std::vector<void*> * v=&(*mapit).second;
00399         std::vector<void*>::iterator last=std::remove(v->begin(),v->end(),el);
00400         if(last!=v->end()) {
00401           hadListener=true;
00402           v->erase(last,v->end());
00403         }
00404       }
00405     }
00406   }
00407   return hadListener;
00408 }
00409 
00410 bool EventRouter::EventMapper::removeMapping(void* el, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00411   bool hadListener=false;
00412   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00413   if(mapping!=NULL) { // if there are subscribers to this egid/etid
00414     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00415     if(mapit!=mapping->end()) {
00416       std::vector<void*> * v=&(*mapit).second;
00417       std::vector<void*>::iterator last=std::remove(v->begin(),v->end(),el);
00418       if(last!=v->end()) {
00419         hadListener=true;
00420         v->erase(last,v->end());
00421       }
00422     }
00423   }
00424   return hadListener;
00425 }
00426 
00427 void EventRouter::EventMapper::clean() {
00428   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00429     clean((EventBase::EventGeneratorID_t)eg);
00430 }
00431 void EventRouter::EventMapper::clean(EventBase::EventGeneratorID_t egid) {
00432   // first, remove any empty sid vectors from all the 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       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00437       bool done=false;
00438       while(!done) {
00439         done=true;
00440         for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) { // go through each sourceID vector
00441           if((*mapit).second.size()==0) {
00442             mapping->erase(mapit);
00443             done=false;
00444             break;
00445           }
00446         }
00447       }
00448     }
00449   }
00450   // now remove any empty mappings
00451   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00452     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00453     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00454       if(mapping->size()==0) {
00455         delete mapping;
00456         filteredevents[egid][et]=NULL;
00457       }
00458     }
00459   }
00460 }
00461 
00462 void EventRouter::EventMapper::clear() {
00463   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00464     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00465       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00466       if(mapping!=NULL) { // don't beat a dead horse!
00467         mapping->erase(mapping->begin(),mapping->end());
00468         delete mapping;
00469         filteredevents[eg][et]=NULL;
00470       }
00471     }
00472   }
00473 }
00474 
00475 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid) const {
00476   if(allevents[egid].size()>0)
00477     return true;
00478   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00479     const SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00480     if(mapping!=NULL) {
00481       SIDtoListenerVectorMap_t::const_iterator mapit=mapping->begin();
00482       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00483         if((*mapit).second.size()>0)
00484           return true;
00485     }
00486   }
00487   return false;
00488 }
00489 
00490 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, unsigned int sid) const {
00491   if(allevents[egid].size()>0)
00492     return true;
00493   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00494     const SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00495     if(mapping!=NULL) {
00496       SIDtoListenerVectorMap_t::const_iterator mapit=mapping->find(sid);
00497       if(mapit!=mapping->end() && (*mapit).second.size()>0)
00498         return true;
00499     }
00500   }
00501   return false;
00502 }
00503 
00504 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) const {
00505   if(allevents[egid].size()>0)
00506     return true;
00507   const SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00508   if(mapping!=NULL) {
00509     SIDtoListenerVectorMap_t::const_iterator mapit=mapping->find(sid);
00510     if(mapit!=mapping->end())
00511       return ((*mapit).second.size()>0);
00512   }
00513   return false;
00514 }
00515 
00516 template<class T>
00517 void EventRouter::EventMapper::getMapping(const EventBase& e, std::vector<T*>& ls) const {
00518   // first get all the filtered subscribers (tricky!)
00519   const std::vector<void*>* elv=NULL;
00520   const SIDtoListenerVectorMap_t* sidtovm=filteredevents[e.getGeneratorID()][e.getTypeID()];
00521   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00522     SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->find(e.getSourceID()); // find listening for this source id
00523     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00524       elv=&(*mapit).second; // now go through them all
00525       for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00526         ls.push_back(static_cast<T*>(*elit));
00527     }
00528   }
00529   // now get the 'all events' subscribers
00530   elv=&allevents[e.getGeneratorID()];
00531   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00532     ls.push_back(static_cast<T*>(*elit));
00533 }
00534 
00535 bool EventRouter::EventMapper::verifyMapping(void * listener, EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) const {
00536   // first check the 'all events' subscribers
00537   const std::vector<void*>* elv=&allevents[egid];
00538   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00539     if(*elit==listener)
00540       return true;
00541   
00542   // then check all the filtered subscribers (tricky!)
00543   const SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][etid];
00544   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00545     const SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->find(sid); // find listening for this source id
00546     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00547       elv=&(*mapit).second; // now go through them all
00548       for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00549         if(*elit==listener)
00550           return true;
00551     }
00552   }
00553 
00554   // if we haven't found it, doesn't exist:
00555   return false;
00556 }
00557 
00558 bool EventRouter::EventMapper::verifyMappingAll(void* listener, EventBase::EventGeneratorID_t egid) const {
00559   const std::vector<void*>* elv=&allevents[egid];
00560   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00561     if(*elit==listener)
00562       return true;
00563   // if not in the all listeners, can't be listening for *every* source id
00564   return false;
00565 }
00566 
00567 bool EventRouter::EventMapper::verifyMappingAny(void* listener, EventBase::EventGeneratorID_t egid) const {
00568   // first check the 'all events' subscribers
00569   const std::vector<void*>* elv=&allevents[egid];
00570   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00571     if(*elit==listener)
00572       return true;
00573   
00574   // then check all the filtered subscribers (tricky!)
00575   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00576     const SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00577     if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00578       SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->begin(); // for each of the source ids
00579       for(;mapit!=sidtovm->end();mapit++) {
00580         elv=&(*mapit).second; // now go through them all
00581         for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00582           if(*elit==listener)
00583             return true;
00584       }
00585     }
00586   }
00587 
00588   // if we haven't found any, none exist:
00589   return false;
00590 }
00591 
00592 bool EventRouter::EventMapper::verifyMappingAll(void* listener, EventBase::EventGeneratorID_t egid, unsigned int sid) const {
00593   // first check the 'all events' subscribers
00594   const std::vector<void*>* elv=&allevents[egid];
00595   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00596     if(*elit==listener)
00597       return true;
00598   
00599   // then check all the filtered subscribers (tricky!)
00600   // must be found in ALL etids
00601   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00602     const SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00603     if(sidtovm==NULL)
00604       return false;
00605     // there's a map (at least one EL is filtering on this EGID and ETID)
00606     const SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->find(sid); // find listening for this source id
00607     if(mapit==sidtovm->end())
00608       return false;
00609     // there's at least one is filtering on this sourceID as well
00610     elv=&(*mapit).second; // now go through them all
00611     std::vector<void*>::const_iterator elit=elv->begin();
00612     while(elit!=elv->end() && *elit!=listener)
00613       elit++;
00614     if(elit==elv->end())
00615       return false;
00616     //if we didn't return false, we found a match... continue checking other ETIDs
00617   }
00618 
00619   // we only got here if we *did* find listener in each of the ETIDs
00620   return true;
00621 }
00622 
00623 bool EventRouter::EventMapper::verifyMappingAny(void* listener, EventBase::EventGeneratorID_t egid, unsigned int sid) const {
00624   // first check the 'all events' subscribers
00625   const std::vector<void*>* elv=&allevents[egid];
00626   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00627     if(*elit==listener)
00628       return true;
00629   
00630   // then check all the filtered subscribers (tricky!)
00631   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00632     const SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00633     if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00634       SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->find(sid); // find listening for this source id
00635       if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00636         elv=&(*mapit).second; // now go through them all
00637         for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00638           if(*elit==listener)
00639             return true;
00640       }
00641     }
00642   }
00643 
00644   // if we haven't found it, doesn't exist:
00645   return false;
00646 }
00647 
00648 /*! @file
00649  * @brief Implements EventRouter class, for distribution and trapping of events to listeners
00650  * @author ejt (Creator)
00651  *
00652  * $Author: ejt $
00653  * $Name: tekkotsu-3_0 $
00654  * $Revision: 1.28 $
00655  * $State: Exp $
00656  * $Date: 2006/09/27 21:15:51 $
00657  */
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 // Use hasListeners(*) it's faster, i doubt anyone would really care how many... (but just in case...)
00666 /*
00667 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid) {
00668   unsigned int ans=allevents[egid].size();
00669   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00670     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00671     if(mapping!=NULL) {
00672       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00673       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00674         ans+=(*mapit).second.size();
00675     }
00676   }
00677   return ans;
00678 }
00679 
00680 bool EventRouter::numListeners(EventBase::EventGeneratorID_t egid, unsigned int sid) {
00681   unsigned int ans=allevents[egid].size();
00682   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00683     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00684     if(mapping!=NULL) {
00685       SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00686       if(mapit!=mapping->end())
00687         ans+=(*mapit).second.size();
00688     }
00689   }
00690   return false;
00691 }
00692 
00693 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid, unsigned int sid, EventBase::EventTypeID_t etid) {
00694   unsigned int ans=allevents[egid].size();
00695   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00696   if(mapping!=NULL) {
00697     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00698     if(mapit!=mapping->end())
00699       ans+=(*mapit).second.size();
00700   }
00701   return ans;
00702 }
00703 */

Tekkotsu v3.0
Generated Wed Oct 4 00:03:43 2006 by Doxygen 1.4.7