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 #include "EventTranslator.h"
00008 #include "Shared/string_util.h"
00009 #include "Shared/debuget.h"
00010 
00011 #ifndef TGT_IS_DYNAMIC
00012 #  include "Events/RemoteRouter.h"
00013 #  include "Events/EventProxy.h"
00014 #endif
00015 
00016 #include <sstream>
00017 
00018 #ifndef PLATFORM_APERIOS
00019 #  include "IPC/Thread.h"
00020 #  include "Shared/MarkScope.h"
00021 #  include "IPC/ThreadedMessageQueue.h"
00022 #endif
00023 
00024 EventRouter * erouter=NULL;
00025 
00026 EventRouter::EventRouter() :
00027 #ifndef TGT_IS_DYNAMIC
00028   proxies(), rrouters(), sck(NULL), nextProxyPort(defaultPort+1),
00029 #endif
00030   timers(), trappers(), listeners(), postings()
00031 #ifndef PLATFORM_APERIOS
00032   , eventQueue(new ThreadedMessageQueue<EventBase*>)
00033 #endif
00034 {
00035   for(unsigned int i=0; i<ProcessID::NumProcesses; ++i) {
00036     forwards[i]=NULL;
00037   }
00038 }
00039 
00040 EventRouter::~EventRouter() {
00041 #ifndef PLATFORM_APERIOS
00042   delete eventQueue;
00043   eventQueue=NULL;
00044 #endif
00045   reset();
00046   removeAllTimers();
00047   for(unsigned int i=0; i<ProcessID::NumProcesses; ++i) {
00048     delete forwards[i];
00049     forwards[i]=NULL;
00050   }
00051 
00052 #ifndef TGT_IS_DYNAMIC
00053   //Delete all the event proxies
00054   //printf("Deleting %zu EventProxies and %zu RemoteRouters\n", proxies.size(), rrouters.size());
00055   for (std::list<EventProxy *>::iterator pi = proxies.begin(); pi != proxies.end(); pi++)
00056     delete *pi;
00057   
00058   //Delete the remote routers
00059   for (std::map<int, RemoteRouter *>::iterator mi = rrouters.begin(); mi != rrouters.end(); mi++)
00060     delete (*mi).second;
00061 #endif
00062   
00063 }
00064 
00065 #ifndef PLATFORM_APERIOS
00066 void EventRouter::queueEvent(EventBase* e) { eventQueue->send(e); }
00067 
00068 void EventRouter::requeueEvent(EventBase* e) { eventQueue->remove(SameID(e)); queueEvent(e); }
00069 #endif
00070 
00071 
00072 //! @todo handle recursive calls
00073 void EventRouter::processTimers() {
00074   // std::cout << "processTimers..." << std::flush;
00075   unsigned int curtime=get_time();
00076   TimerEntry curTimer(curtime);
00077   timer_it_t last_it=upper_bound(timers.begin(),timers.end(),&curTimer,TimerEntryPtrCmp());
00078   std::vector<TimerEntry*> process(timers.begin(),last_it); //copy these out for safe keeping
00079   for(timer_it_t it=process.begin(); it!=process.end(); it++) //increment the timers we're processing
00080     if(!(*it)->repeat)
00081       (*it)->next=(unsigned int)-1;
00082     else if((*it)->delay==0)
00083       (*it)->next=curtime+1;
00084     else while((*it)->next<=curtime)
00085       (*it)->next+=(*it)->delay;
00086   sort(timers.begin(),last_it,TimerEntryPtrCmp()); //re-sort the timers we're processing (at the beginning of timers)
00087   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)
00088   //  if(process.size()>0) chkTimers();
00089   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
00090     if(find(timers.begin(),timers.end(),*it)==timers.end())
00091       continue; // the timer has been removed during processesing of a previous timer...
00092     TimerEvent e((*it)->el,EventBase::timerEGID,(*it)->sid,EventBase::statusETID,(*it)->next-(*it)->delay);
00093     try {
00094       (*it)->el->processEvent(e);
00095     } catch(const std::exception& ex) {
00096       std::string msg="Occurred while processing event "+e.getName()+" by ";
00097       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>((*it)->el))
00098         msg+="listener "+beh->getName();
00099       else
00100         msg+="unnamed EventListener";
00101       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),&ex))
00102         throw;
00103     } catch(...) {
00104       std::string msg="Occurred while processing event "+e.getName()+" by ";
00105       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>((*it)->el))
00106         msg+="listener "+beh->getName();
00107       else
00108         msg+="unnamed EventListener";
00109       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),NULL))
00110         throw;
00111     }
00112     postEvent(e);
00113   }
00114   //  if(process.size()>0) chkTimers();
00115   static const TimerEntry deadTimer((unsigned int)-1); // matches all the dead ones as set in the incrementation phase
00116   last_it=lower_bound(timers.begin(),timers.end(),&deadTimer,TimerEntryPtrCmp()); //find the beginning of all the non-repeating timers we're clearing
00117   for(timer_it_t it=last_it; it!=timers.end(); it++) // delete all of them
00118     delete *it;
00119   timers.erase(last_it,timers.end()); //and then remove them from the timer list
00120   //  if(process.size()>0) chkTimers();
00121   //    cout << "done" << endl;
00122 }
00123 
00124 /*! timers are unique by EventListener and source ID - can't have two timers for the same el and sid\n
00125  *  a delay of 0 with repeating will cause an event to be sent at every opportunity, use sparingly\n
00126  *  a delay of -1U will call removeTimer() if it already exists, otherwise is ignored\n
00127  *
00128  *  @param el the EventListener to send the timer event to
00129  *  @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)
00130  *  @param delay the delay between the first (and future) calls
00131  *  @param repeat set to true if you want to keep receiving this event, otherwise it will only send once */
00132 void EventRouter::addTimer(EventListener* el, size_t sid, unsigned int delay, bool repeat) {
00133   if(delay==-1U) {
00134     removeTimer(el,sid);
00135     return;
00136   }
00137   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00138     if((*it)->el==el && (*it)->sid==sid) {
00139       (*it)->Set(delay,repeat);
00140       // now put that timer back into the correct place in the ordering (think before touching this! ;)
00141       if(it!=timers.begin() && (*it)->next<(*(it-1))->next)
00142         rotate(upper_bound(timers.begin(),it,*it,TimerEntryPtrCmp()),it,it+1);
00143       else if(it+1!=timers.end() && (*it)->next>(*(it+1))->next)
00144         rotate(it,it+1,lower_bound(it+1,timers.end(),*it,TimerEntryPtrCmp()));
00145       return;
00146     }
00147   //didn't find a pre-existing one
00148   TimerEntry * add=new TimerEntry(el,sid,delay,repeat);
00149   timers.insert(lower_bound(timers.begin(),timers.end(),add,TimerEntryPtrCmp()),add);
00150   //  chkTimers();
00151 }
00152 
00153 void EventRouter::removeTimer(const EventListener* el) {
00154   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00155     if((*it)->el==el) {
00156       delete *it;
00157       *it=NULL;
00158     }
00159   timers.erase(std::remove(timers.begin(),timers.end(),(const TimerEntry*)NULL),timers.end());
00160 }
00161 
00162 void EventRouter::removeTimer(const EventListener* el, size_t sid) {
00163   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00164     if((*it)->el==el && (*it)->sid==sid) {
00165       delete *it;
00166       timers.erase(it);
00167       return;
00168     }
00169 }
00170 
00171 void EventRouter::removeAllTimers() {
00172   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00173     delete *it;
00174   timers.erase(timers.begin(),timers.end());
00175 }
00176 
00177 const EventRouter::TimerEntry* EventRouter::getNextTimerInfo(const EventListener* el) {
00178   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00179     if((*it)->el==el)
00180       return *it;
00181   return NULL;
00182 }
00183 
00184 const EventRouter::TimerEntry* EventRouter::getNextTimerInfo(const EventListener* el, size_t sid) {
00185   for(timer_it_t it=timers.begin(); it!=timers.end(); it++)
00186     if((*it)->el==el && (*it)->sid==sid)
00187       return *it;
00188   return NULL;
00189 }
00190 
00191 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid) {
00192   bool hadListener=hasListeners(egid);
00193   listeners.addMapping(el,egid); 
00194   if(!hadListener)
00195     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00196   else
00197     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00198 }
00199 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid, size_t sid) {
00200   bool hadListener=hasListeners(egid);
00201   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00202     listeners.addMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00203   if(!hadListener)
00204     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00205   else
00206     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00207 }
00208 void EventRouter::addListener(EventListener* el, EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) {
00209   bool hadListener=hasListeners(egid);
00210   listeners.addMapping(el,egid,sid,etid);
00211   if(!hadListener)
00212     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00213   else
00214     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00215 }
00216 void EventRouter::addListener(EventListener* el, const EventBase& e) {
00217   bool hadListener=hasListeners(e.getGeneratorID());
00218   listeners.addMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID());
00219   if(!hadListener)
00220     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::activateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00221   else
00222     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00223 }
00224 
00225 #ifndef TGT_IS_DYNAMIC
00226 //Start of remote event code------------------
00227 void EventRouter::addRemoteListener(EventListener* el, int host,
00228                   EventBase::EventGeneratorID_t egid) {
00229   RemoteRouter &rr = remoteRouterForHost(host);
00230   addListener(el, egid);
00231   rr.addListener(egid);
00232 }
00233 
00234 void EventRouter::addRemoteListener(EventListener* el, int host,
00235                   EventBase::EventGeneratorID_t egid, size_t sid) {
00236   RemoteRouter &rr = remoteRouterForHost(host);
00237   addListener(el, egid, sid);
00238   rr.addListener(egid, sid);
00239 }
00240 
00241 void EventRouter::addRemoteListener(EventListener* el, int host, const EventBase& e){
00242   addRemoteListener(el, host, e.getGeneratorID(), e.getSourceID(), e.getTypeID());
00243 }
00244 
00245 void EventRouter::addRemoteListener(EventListener* el, int host,
00246                   EventBase::EventGeneratorID_t egid, size_t sid,
00247                   EventBase::EventTypeID_t etid) {
00248   RemoteRouter &rr = remoteRouterForHost(host);
00249   addListener(el, egid, sid, etid);
00250   rr.addListener(egid, sid, etid);
00251 }
00252 
00253 
00254 void EventRouter::removeRemoteListener(const EventListener* el, int host,
00255                      EventBase::EventGeneratorID_t egid) {
00256   RemoteRouter &rr = remoteRouterForHost(host);
00257   removeListener(el, egid);
00258   rr.removeListener(egid);
00259 }
00260 
00261 void EventRouter::removeRemoteListener(const EventListener* el, int host,
00262                      EventBase::EventGeneratorID_t egid, size_t sid) {
00263   RemoteRouter &rr = remoteRouterForHost(host);
00264   removeListener(el, egid, sid);
00265   rr.removeListener(egid, sid); 
00266 }
00267     
00268 void EventRouter::removeRemoteListener(const EventListener* el, int host,
00269                      const EventBase& e) {
00270   removeRemoteListener(el, host, e.getGeneratorID(), e.getSourceID(), e.getTypeID()); 
00271 }
00272 
00273 void EventRouter::removeRemoteListener(const EventListener* el, int host,
00274                      EventBase::EventGeneratorID_t egid, size_t sid,
00275                      EventBase::EventTypeID_t etid) {
00276   RemoteRouter &rr = remoteRouterForHost(host);
00277   removeListener(el, egid, sid, etid);
00278   rr.removeListener(egid, sid, etid);
00279 }
00280 
00281 
00282 void EventRouter::requestRemoteStateUpdates(int host, RemoteState::StateType type,
00283                       unsigned int interval) {
00284   RemoteRouter &rr = remoteRouterForHost(host);
00285   rr.requestStateUpdates(type, interval);
00286 }
00287 
00288 void EventRouter::stopRemoteStateUpdates(int host, RemoteState::StateType type) {
00289   RemoteRouter &rr = remoteRouterForHost(host);
00290   rr.stopStateUpdates(type);
00291 }
00292 
00293 RemoteRouter &EventRouter::remoteRouterForHost(int host) {
00294   RemoteRouter *rr = rrouters[host];
00295   if (rr) {
00296     printf("Returning existing remote router for host %s\n", string_util::intToStringIP(host).c_str());
00297     return *rr;
00298   } else {
00299     rrouters[host] = rr = new RemoteRouter(host);
00300     printf("Returning new remote router for host %s\n", string_util::intToStringIP(host).c_str());
00301     return *rr;
00302   }
00303 }
00304 
00305 /* This is called in MMCombo.cc on startup. */
00306 bool EventRouter::serveRemoteEventRequests() {
00307   if (sck)
00308     return false;
00309   sck = wireless->socket(Socket::SOCK_STREAM);
00310   wireless->setReceiver(sck, this);
00311   wireless->setDaemon(sck, true);
00312   wireless->listen(sck, EventRouter::defaultPort);
00313   return true;
00314 }
00315 
00316 int EventRouter::processData(char* /* data*/, int bytes) {
00317   if (bytes != sizeof(int)) {
00318     std::cerr << "Unknown data received" << std::endl;
00319     return -1;
00320   }
00321   
00322   int nextPort = nextProxyPort++;
00323   std::cout << "Starting EventProxy on port " << nextPort
00324     << " for host " << string_util::intToStringIP(sck->getPeerAddress()) << std::endl;
00325   proxies.push_back(new EventProxy(nextPort));
00326 
00327   //Send the port to the RemoteRouter
00328   sck->write((byte *)&nextPort, sizeof(int));
00329 
00330   //Start listening again
00331   wireless->close(sck);
00332   
00333   return 0;
00334 }
00335 
00336 //End of remote event code
00337 #endif
00338 
00339 void EventRouter::removeListener(const EventListener* el) {
00340   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00341     EventBase::EventGeneratorID_t egid=(EventBase::EventGeneratorID_t)eg;
00342     if(!listeners.removeMapping(el,egid))
00343       continue; //nothing was removed, don't want to clean up or throw an event
00344     listeners.clean(egid);
00345     if(!hasListeners(egid))
00346       postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00347     else
00348       postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00349   }
00350 }
00351 void EventRouter::removeListener(const EventListener* el, EventBase::EventGeneratorID_t egid) {
00352   if(!listeners.removeMapping(el,egid))
00353     return; //nothing was removed, don't want to clean up or throw an event
00354   listeners.clean(egid);
00355   if(!hasListeners(egid))
00356     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00357   else
00358     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00359 }
00360 void EventRouter::removeListener(const EventListener* el, EventBase::EventGeneratorID_t egid, size_t sid) {
00361   unsigned int removed=0;
00362   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00363     removed+=listeners.removeMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00364   if(!removed)
00365     return; //nothing was removed, don't want to clean up or throw an event
00366   listeners.clean(egid);
00367   if(!hasListeners(egid))
00368     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00369   else
00370     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00371 }
00372 void EventRouter::removeListener(const EventListener* el, EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) {
00373   if(!listeners.removeMapping(el,egid,sid,etid))
00374     return; //nothing was removed, don't want to clean up or throw an event
00375   listeners.clean(egid);
00376   if(!hasListeners(egid))
00377     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00378   else
00379     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00380 }
00381 void EventRouter::removeListener(const EventListener* el, const EventBase& e) {
00382   if(!listeners.removeMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID()))
00383     return; //nothing was removed, don't want to clean up or throw an event
00384   listeners.clean(e.getGeneratorID());
00385   if(!hasListeners(e.getGeneratorID()))
00386     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::deactivateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],0));
00387   else
00388     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00389 }
00390 
00391 void EventRouter::addTrapper(EventTrapper* el, const EventBase& e) {
00392   bool hadListener=hasListeners(e.getGeneratorID());
00393   trappers.addMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID());
00394   if(!hadListener)
00395     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::activateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00396   else
00397     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00398 }
00399 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00400 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid) {
00401   bool hadListener=hasListeners(egid);
00402   trappers.addMapping(el,egid);
00403   if(!hadListener)
00404     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00405   else
00406     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00407 }
00408 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00409 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, size_t sid) {
00410   bool hadListener=hasListeners(egid);
00411   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00412     trappers.addMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00413   if(!hadListener)
00414     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00415   else
00416     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00417 }
00418 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00419 void EventRouter::addTrapper(EventTrapper* el, EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) {
00420   bool hadListener=hasListeners(egid);
00421   trappers.addMapping(el,egid,sid,etid);
00422   if(!hadListener)
00423     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::activateETID,0,EventBase::EventGeneratorNames[egid],1));
00424   else
00425     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00426 }
00427 
00428 /*! Note that since timers are not broadcast, they cannot be trapped.  Only the EventListener which requested the timer will receive that timer. */
00429 void EventRouter::addTrapper(EventTrapper* el) {
00430   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00431     addTrapper(el,(EventBase::EventGeneratorID_t)eg);
00432 }
00433 
00434 
00435 void EventRouter::removeTrapper(const EventTrapper* el, const EventBase& e) {
00436   if(!trappers.removeMapping(el,e.getGeneratorID(),e.getSourceID(),e.getTypeID()))
00437     return; //nothing was removed, don't want to clean up or throw an event
00438   trappers.clean(e.getGeneratorID());
00439   if(!hasListeners(e.getGeneratorID()))
00440     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::deactivateETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],0));
00441   else
00442     postEvent(EventBase(EventBase::erouterEGID,e.getGeneratorID(),EventBase::statusETID,0,EventBase::EventGeneratorNames[e.getGeneratorID()],1));
00443 }
00444 void EventRouter::removeTrapper(const EventTrapper* el, EventBase::EventGeneratorID_t egid) {
00445   if(!trappers.removeMapping(el,egid))
00446     return; //nothing was removed, don't want to clean up or throw an event
00447   trappers.clean(egid);
00448   if(!hasListeners(egid))
00449     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00450   else
00451     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00452 }
00453 void EventRouter::removeTrapper(const EventTrapper* el, EventBase::EventGeneratorID_t egid, size_t sid) {
00454   int removed=0;
00455   for(unsigned int et=0; et<EventBase::numETIDs; et++)
00456     removed+=trappers.removeMapping(el,egid,sid,(EventBase::EventTypeID_t)et);
00457   if(!removed)
00458     return; //nothing was removed, don't want to clean up or throw an event
00459   trappers.clean(egid);
00460   if(!hasListeners(egid))
00461     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00462   else
00463     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00464 }
00465 void EventRouter::removeTrapper(const EventTrapper* el, EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) {
00466   if(!trappers.removeMapping(el,egid,sid,etid))
00467     return; //nothing was removed, don't want to clean up or throw an event
00468   trappers.clean(egid);
00469   if(!hasListeners(egid))
00470     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::deactivateETID,0,EventBase::EventGeneratorNames[egid],0));
00471   else
00472     postEvent(EventBase(EventBase::erouterEGID,egid,EventBase::statusETID,0,EventBase::EventGeneratorNames[egid],1));
00473 }
00474 
00475 void EventRouter::removeTrapper(const EventTrapper* el) {
00476   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00477     removeTrapper(el,(EventBase::EventGeneratorID_t)eg);
00478 }
00479 
00480 void EventRouter::chkTimers() {
00481   unsigned int last=0;
00482   for(timer_it_t it=timers.begin(); it!=timers.end(); it++) {
00483     if(last>(*it)->next) {
00484       std::cout << "Out of order ";
00485       dispTimers();
00486       return;
00487     }
00488     last=(*it)->next;
00489   }
00490 }
00491 
00492 //! just for debugging
00493 void EventRouter::dispTimers() {
00494   std::cout << "timers at " << get_time() << " :\t";
00495   unsigned int last=0;
00496   for(timer_it_t it=timers.begin(); it!=timers.end(); it++) {
00497     if(last>(*it)->next)
00498       std::cout << "##";
00499     BehaviorBase* beh = dynamic_cast<BehaviorBase*>((*it)->el);
00500     if ( beh != NULL )
00501       std::cout << beh->getName() << "@";
00502     std::cout << (last=(*it)->next) << '\t';
00503   }
00504   std::cout << std::endl;
00505 }
00506 
00507 
00508 void EventRouter::setForwardingAgent(ProcessID::ProcessID_t proc, EventTranslator* trans) {
00509   delete forwards[proc];
00510   forwards[proc]=trans;
00511 }
00512 
00513 void EventRouter::processEvent(const EventBase& e) {
00514   // check for forwarding *before* the lock
00515   ProcessID::ProcessID_t pid=ProcessID::getID();
00516   if(pid!=ProcessID::NumProcesses && forwards[pid]!=NULL) {
00517     if(forwards[pid]->trapEvent(e))
00518       return;
00519   }
00520   
00521 #ifndef PLATFORM_APERIOS
00522   static Thread::Lock lk;
00523   MarkScope autolock(lk);
00524 #endif
00525   PostingStatus ps(trappers,listeners,e);
00526   postings.push(&ps);
00527   while(postings.size()>0) {
00528 #ifdef DEBUG
00529     size_t presize=postings.size();
00530     postings.front()->process();
00531     ASSERT(postings.size()==0 || postings.size()==presize,"partial queue completion?");
00532 #else
00533     postings.front()->process();
00534 #endif
00535     if(postings.size()>0) // in case a sub-post took over and finished off the queue
00536       postings.pop();
00537   }
00538 }
00539 
00540 void EventRouter::PostingStatus::process() {
00541   while(tit!=t.end()) {
00542     // increment before processing so if a new post is done during the processing, we pick up on the *next* entry
00543     EventTrapper * et=*tit++;
00544     if(!trappers.verifyMapping(et,e))
00545       continue;
00546     try {
00547       if(et->trapEvent(e))
00548         return;
00549     } catch(const std::exception& ex) {
00550       std::string msg="Occurred while processing event "+e.getName()+" by ";
00551       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>(et))
00552         msg+="trapper "+beh->getName();
00553       else
00554         msg+="unnamed EventTrapper";
00555       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),&ex))
00556         throw;
00557     } catch(...) {
00558       std::string msg="Occurred while processing event "+e.getName()+" by ";
00559       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>(et))
00560         msg+="trapper "+beh->getName();
00561       else
00562         msg+="unnamed EventTrapper";
00563       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),NULL))
00564         throw;
00565     }
00566   }
00567   while(lit!=l.end()) {
00568     // increment before processing so if a new post is done during the processing, we pick up on the *next* entry
00569     EventListener * el=*lit++;
00570     if(!listeners.verifyMapping(el,e))
00571       continue;
00572     try {
00573       el->processEvent(e);
00574     } catch(const std::exception& ex) {
00575       std::string msg="Occurred while processing event "+e.getName()+" by ";
00576       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>(el))
00577         msg+="listener "+beh->getName();
00578       else
00579         msg+="unnamed EventListener";
00580       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),&ex))
00581         throw;
00582     } catch(...) {
00583       std::string msg="Occurred while processing event "+e.getName()+" by ";
00584       if(BehaviorBase * beh=dynamic_cast<BehaviorBase*>(el))
00585         msg+="listener "+beh->getName();
00586       else
00587         msg+="unnamed EventListener";
00588       if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,msg.c_str(),NULL))
00589         throw;
00590     }
00591   }
00592 }
00593 
00594 EventRouter::EventMapper::EventMapper() {
00595   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00596     for(unsigned int et=0; et<EventBase::numETIDs; et++)
00597       filteredevents[eg][et]=NULL;
00598 }
00599 
00600 void EventRouter::EventMapper::addMapping(void* el, EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) {
00601   if(filteredevents[egid][etid]==NULL) //if this is the first subscriber to this EGID and ETID
00602     filteredevents[egid][etid]=new SIDtoListenerVectorMap_t(); 
00603   SIDtoListenerVectorMap_t::iterator it=filteredevents[egid][etid]->find(sid); // now find subscribers to the source id as well
00604   std::vector<void*>* elv=NULL;
00605   if(it==filteredevents[egid][etid]->end()) { // if this is the first subscriber to the source ID
00606     std::pair<const size_t,std::vector<void*> > p(sid,std::vector<void*>());
00607     //    p.first=sid; //p.second is a vector, only needs to be constructed
00608     filteredevents[egid][etid]->insert(p);
00609     elv=&(*filteredevents[egid][etid]->find(sid)).second;
00610   } else {
00611     elv=&(*it).second;
00612   }
00613   elv->push_back(el); // now that everything's set up, we can add the listener
00614 }
00615 
00616 bool EventRouter::EventMapper::removeMapping(const void* el, EventBase::EventGeneratorID_t egid) {
00617   // remove listener from allevents
00618   size_t numlist=allevents[egid].size();
00619   allevents[egid].erase(std::remove(allevents[egid].begin(),allevents[egid].end(),el),allevents[egid].end());
00620   bool hadListener=allevents[egid].size()!=numlist;
00621   
00622   // now remove listener from all of the filtered events
00623   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00624     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00625     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00626       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00627       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) {// go through each sourceID, delete EL
00628         std::vector<void*> * v=&(*mapit).second;
00629         std::vector<void*>::iterator last=std::remove(v->begin(),v->end(),el);
00630         if(last!=v->end()) {
00631           hadListener=true;
00632           v->erase(last,v->end());
00633         }
00634       }
00635     }
00636   }
00637   return hadListener;
00638 }
00639 
00640 bool EventRouter::EventMapper::removeMapping(const void* el, EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) {
00641   bool hadListener=false;
00642   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00643   if(mapping!=NULL) { // if there are subscribers to this egid/etid
00644     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00645     if(mapit!=mapping->end()) {
00646       std::vector<void*> * v=&(*mapit).second;
00647       std::vector<void*>::iterator last=std::remove(v->begin(),v->end(),el);
00648       if(last!=v->end()) {
00649         hadListener=true;
00650         v->erase(last,v->end());
00651       }
00652     }
00653   }
00654   return hadListener;
00655 }
00656 
00657 void EventRouter::EventMapper::clean() {
00658   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++)
00659     clean((EventBase::EventGeneratorID_t)eg);
00660 }
00661 void EventRouter::EventMapper::clean(EventBase::EventGeneratorID_t egid) {
00662   // first, remove any empty sid vectors from all the mappings
00663   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00664     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00665     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00666       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00667       bool done=false;
00668       while(!done) {
00669         done=true;
00670         for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++) { // go through each sourceID vector
00671           if((*mapit).second.size()==0) {
00672             mapping->erase(mapit);
00673             done=false;
00674             break;
00675           }
00676         }
00677       }
00678     }
00679   }
00680   // now remove any empty mappings
00681   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00682     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00683     if(mapping!=NULL) { // if there are subscribers to this egid/etid
00684       if(mapping->size()==0) {
00685         delete mapping;
00686         filteredevents[egid][et]=NULL;
00687       }
00688     }
00689   }
00690 }
00691 
00692 void EventRouter::EventMapper::clear() {
00693   for(unsigned int eg=0; eg<EventBase::numEGIDs; eg++) {
00694     for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00695       SIDtoListenerVectorMap_t* mapping=filteredevents[eg][et];
00696       if(mapping!=NULL) { // don't beat a dead horse!
00697         mapping->erase(mapping->begin(),mapping->end());
00698         delete mapping;
00699         filteredevents[eg][et]=NULL;
00700       }
00701     }
00702   }
00703 }
00704 
00705 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid) const {
00706   if(allevents[egid].size()>0)
00707     return true;
00708   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00709     const SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00710     if(mapping!=NULL) {
00711       SIDtoListenerVectorMap_t::const_iterator mapit=mapping->begin();
00712       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00713         if((*mapit).second.size()>0)
00714           return true;
00715     }
00716   }
00717   return false;
00718 }
00719 
00720 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, size_t sid) const {
00721   if(allevents[egid].size()>0)
00722     return true;
00723   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00724     const SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00725     if(mapping!=NULL) {
00726       SIDtoListenerVectorMap_t::const_iterator mapit=mapping->find(sid);
00727       if(mapit!=mapping->end() && (*mapit).second.size()>0)
00728         return true;
00729     }
00730   }
00731   return false;
00732 }
00733 
00734 bool EventRouter::EventMapper::hasMapping(EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) const {
00735   if(allevents[egid].size()>0)
00736     return true;
00737   const SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00738   if(mapping!=NULL) {
00739     SIDtoListenerVectorMap_t::const_iterator mapit=mapping->find(sid);
00740     if(mapit!=mapping->end())
00741       return ((*mapit).second.size()>0);
00742   }
00743   return false;
00744 }
00745 
00746 template<class T>
00747 void EventRouter::EventMapper::getMapping(const EventBase& e, std::vector<T*>& ls) const {
00748   // first get all the filtered subscribers (tricky!)
00749   const std::vector<void*>* elv=NULL;
00750   const SIDtoListenerVectorMap_t* sidtovm=filteredevents[e.getGeneratorID()][e.getTypeID()];
00751   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00752     SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->find(e.getSourceID()); // find listening for this source id
00753     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00754       elv=&(*mapit).second; // now go through them all
00755       for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00756         ls.push_back(static_cast<T*>(*elit));
00757     }
00758   }
00759   // now get the 'all events' subscribers
00760   elv=&allevents[e.getGeneratorID()];
00761   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00762     ls.push_back(static_cast<T*>(*elit));
00763 }
00764 
00765 bool EventRouter::EventMapper::verifyMapping(const void * listener, EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) const {
00766   // first check the 'all events' subscribers
00767   const std::vector<void*>* elv=&allevents[egid];
00768   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00769     if(*elit==listener)
00770       return true;
00771   
00772   // then check all the filtered subscribers (tricky!)
00773   const SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][etid];
00774   if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00775     const SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->find(sid); // find listening for this source id
00776     if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00777       elv=&(*mapit).second; // now go through them all
00778       for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00779         if(*elit==listener)
00780           return true;
00781     }
00782   }
00783 
00784   // if we haven't found it, doesn't exist:
00785   return false;
00786 }
00787 
00788 bool EventRouter::EventMapper::verifyMappingAll(const void* listener, EventBase::EventGeneratorID_t egid) const {
00789   const std::vector<void*>* elv=&allevents[egid];
00790   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00791     if(*elit==listener)
00792       return true;
00793   // if not in the all listeners, can't be listening for *every* source id
00794   return false;
00795 }
00796 
00797 bool EventRouter::EventMapper::verifyMappingAny(const void* listener, EventBase::EventGeneratorID_t egid) const {
00798   // first check the 'all events' subscribers
00799   const std::vector<void*>* elv=&allevents[egid];
00800   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00801     if(*elit==listener)
00802       return true;
00803   
00804   // then check all the filtered subscribers (tricky!)
00805   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00806     const SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00807     if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00808       SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->begin(); // for each of the source ids
00809       for(;mapit!=sidtovm->end();mapit++) {
00810         elv=&(*mapit).second; // now go through them all
00811         for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00812           if(*elit==listener)
00813             return true;
00814       }
00815     }
00816   }
00817 
00818   // if we haven't found any, none exist:
00819   return false;
00820 }
00821 
00822 bool EventRouter::EventMapper::verifyMappingAll(const void* listener, EventBase::EventGeneratorID_t egid, size_t sid) const {
00823   // first check the 'all events' subscribers
00824   const std::vector<void*>* elv=&allevents[egid];
00825   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00826     if(*elit==listener)
00827       return true;
00828   
00829   // then check all the filtered subscribers (tricky!)
00830   // must be found in ALL etids
00831   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00832     const SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00833     if(sidtovm==NULL)
00834       return false;
00835     // there's a map (at least one EL is filtering on this EGID and ETID)
00836     const SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->find(sid); // find listening for this source id
00837     if(mapit==sidtovm->end())
00838       return false;
00839     // there's at least one is filtering on this sourceID as well
00840     elv=&(*mapit).second; // now go through them all
00841     std::vector<void*>::const_iterator elit=elv->begin();
00842     while(elit!=elv->end() && *elit!=listener)
00843       elit++;
00844     if(elit==elv->end())
00845       return false;
00846     //if we didn't return false, we found a match... continue checking other ETIDs
00847   }
00848 
00849   // we only got here if we *did* find listener in each of the ETIDs
00850   return true;
00851 }
00852 
00853 bool EventRouter::EventMapper::verifyMappingAny(const void* listener, EventBase::EventGeneratorID_t egid, size_t sid) const {
00854   // first check the 'all events' subscribers
00855   const std::vector<void*>* elv=&allevents[egid];
00856   for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00857     if(*elit==listener)
00858       return true;
00859   
00860   // then check all the filtered subscribers (tricky!)
00861   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00862     const SIDtoListenerVectorMap_t* sidtovm=filteredevents[egid][et];
00863     if(sidtovm!=NULL) { // if there's a map (at least one EL is filtering on this EGID and ETID)
00864       SIDtoListenerVectorMap_t::const_iterator mapit=sidtovm->find(sid); // find listening for this source id
00865       if(mapit!=sidtovm->end()) { // if there's at least one is filtering on this sourceID as well
00866         elv=&(*mapit).second; // now go through them all
00867         for(std::vector<void*>::const_iterator elit=elv->begin(); elit!=elv->end(); elit++)
00868           if(*elit==listener)
00869             return true;
00870       }
00871     }
00872   }
00873 
00874   // if we haven't found it, doesn't exist:
00875   return false;
00876 }
00877 
00878 /*! @file
00879  * @brief Implements EventRouter class, for distribution and trapping of events to listeners
00880  * @author ejt (Creator)
00881  */
00882 
00883 
00884 
00885 
00886 
00887 
00888 
00889 // Use hasListeners(*) it's faster, i doubt anyone would really care how many... (but just in case...)
00890 /*
00891 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid) {
00892   unsigned int ans=allevents[egid].size();
00893   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00894     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00895     if(mapping!=NULL) {
00896       SIDtoListenerVectorMap_t::iterator mapit=mapping->begin();
00897       for(mapit=mapping->begin(); mapit!=mapping->end(); mapit++)
00898         ans+=(*mapit).second.size();
00899     }
00900   }
00901   return ans;
00902 }
00903 
00904 bool EventRouter::numListeners(EventBase::EventGeneratorID_t egid, size_t sid) {
00905   size_t ans=allevents[egid].size();
00906   for(unsigned int et=0; et<EventBase::numETIDs; et++) {
00907     SIDtoListenerVectorMap_t* mapping=filteredevents[egid][et];
00908     if(mapping!=NULL) {
00909       SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00910       if(mapit!=mapping->end())
00911         ans+=(*mapit).second.size();
00912     }
00913   }
00914   return false;
00915 }
00916 
00917 unsigned int EventRouter::numListeners(EventBase::EventGeneratorID_t egid, size_t sid, EventBase::EventTypeID_t etid) {
00918   unsigned int ans=allevents[egid].size();
00919   SIDtoListenerVectorMap_t* mapping=filteredevents[egid][etid];
00920   if(mapping!=NULL) {
00921     SIDtoListenerVectorMap_t::iterator mapit=mapping->find(sid);
00922     if(mapit!=mapping->end())
00923       ans+=(*mapit).second.size();
00924   }
00925   return ans;
00926 }
00927 */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:38 2016 by Doxygen 1.6.3