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

Tekkotsu v4.0
Generated Thu Nov 22 00:54:53 2007 by Doxygen 1.5.4