Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

EventTranslator.cc

Go to the documentation of this file.
00001 #include "EventTranslator.h"
00002 #include "Events/LocomotionEvent.h"
00003 #include "Events/VisionObjectEvent.h"
00004 #include "Events/TextMsgEvent.h"
00005 #include "Events/EventRouter.h"
00006 #include "Shared/debuget.h"
00007 #include "Shared/ProjectInterface.h"
00008 #include <iostream>
00009 
00010 #ifdef PLATFORM_APERIOS
00011 #  include <OPENR/OSubject.h>
00012 #else
00013 #  include "IPC/MessageQueue.h"
00014 #endif
00015 #include "IPC/RCRegion.h"
00016 
00017 using namespace std;
00018 
00019 EventTranslator::eventLookup_t EventTranslator::eventLookup;
00020 
00021 EventTranslator::~EventTranslator() {
00022   for(eventLookup_t::iterator it=eventLookup.begin(); it!=eventLookup.end(); ++it)
00023     delete (*it).second;
00024   eventLookup.clear();
00025 }
00026 
00027 void
00028 EventTranslator::encodeEvent(const EventBase& event, bool onlyReady/*=false*/) {
00029   event.setSaveFormat(EventBase::BINARY);
00030   const unsigned int headerlen=sizeof(event.getClassTypeID());
00031   const unsigned int bufsize=headerlen+event.getBinSize();
00032   char * buf=bufferRequest(bufsize);
00033   if(buf==NULL) {
00034     cerr << "ERROR: EventTranslator unable to transmit event because requested buffer was NULL" << endl;
00035     return;
00036   }
00037   unsigned int header=event.getClassTypeID();
00038   memcpy(buf,&header,headerlen);
00039   unsigned int used=event.saveBuffer(buf+headerlen,bufsize-headerlen);
00040   if(used==0) {
00041     cerr << "ERROR: EventTranslator unable to transmit event because EventBase::saveBuffer failed (buffer==" << (void*)(buf+headerlen) << ", size==" << bufsize-headerlen << ")" << endl;
00042     post(buf,0,onlyReady);
00043     return;
00044   }
00045   post(buf,used,onlyReady);
00046   return;
00047 }
00048 
00049 EventBase*
00050 EventTranslator::decodeEvent(const char * entry, unsigned int size) {
00051   const unsigned int headerlen=sizeof(unsigned int);
00052   unsigned int header=0;
00053   memcpy(&header,entry,headerlen);
00054   //cout << "decodeEvent(" << (void*)entry << ","<< size << ") header is " << header << " (" << entry[0] << entry[1] << entry[2] << entry[3] << ")" << endl;
00055   eventLookup_t::iterator it=eventLookup.find(header);
00056   if(it==eventLookup.end()) {
00057     cerr << "ERROR: EventTranslator unable to translate buffer because header does not match a previously registered class type id" << endl;
00058     return NULL;
00059   }
00060   EventBase* evt=static_cast<EventBase*>((*it).second->constructTemplate());
00061   evt->setSaveFormat(EventBase::BINARY);
00062   if(evt->loadBuffer(entry+headerlen,size-headerlen)==0) {
00063     cerr << "ERROR: EventTranlator unable to translate buffer because data is malformed (EventBase::loadBuffer failed)" << endl;
00064     return NULL;
00065   }
00066   //cout << "decodes to " << evt->getDescription() << endl;
00067   return evt;
00068 }
00069 
00070 void
00071 NoOpEventTranslator::encodeEvent(const EventBase& event, bool /*onlyReady=false*/) {
00072   evtRouter.postEvent(event);
00073 }
00074 
00075 char*
00076 IPCEventTranslator::bufferRequest(unsigned int size) {
00077   ASSERT(curRegion==NULL,"WARNING: IPCEventTranslator::bufferRequest() curRegion was not NULL");
00078   try {
00079     curRegion = new RCRegion(size);
00080     return curRegion->Base();
00081   } catch(...) {
00082     curRegion=NULL;
00083     throw;
00084   }
00085 }
00086 
00087 void
00088 IPCEventTranslator::post(const char* buf, unsigned int /*size*/, bool onlyReady) {
00089   ASSERTRET(curRegion!=NULL,"ERROR: IPCEventTranslator::post(buf,size) was NULL");
00090   if(buf!=curRegion->Base()) {
00091     cerr << "ERROR: IPCEventTranslator::post(buf,size) buf does not match value given from previous bufferRequest()" << endl;
00092     return;
00093   }
00094 #ifdef PLATFORM_APERIOS
00095   if(!onlyReady) {
00096     subject.SetData(curRegion);
00097     subject.NotifyObservers();
00098   } else {
00099     for(ObserverConstIterator it=subject.begin(); it!=subject.end(); ++it) {
00100       if(subject.IsReady(*it)) {
00101         subject.SetData(*it,curRegion);
00102         subject.NotifyObserver(*it);
00103       }
00104     }
00105   }
00106 #else
00107   if(!onlyReady || subject.getMessageSN(subject.newest())==subject.getMessagesRead()) {
00108     try {
00109       subject.sendMessage(curRegion);
00110     } catch(const std::exception& ex) {
00111       static char errmsg[256];
00112       strncpy(errmsg,("Occurred during IPCEventTranslator::post(), dropping interprocess event "+curName).c_str(),256);
00113       ProjectInterface::uncaughtException(__FILE__,__LINE__,errmsg,&ex);
00114     } catch(...) {
00115       static char errmsg[256];
00116       strncpy(errmsg,("Occurred during IPCEventTranslator::post(), dropping interprocess event "+curName).c_str(),256);
00117       ProjectInterface::uncaughtException(__FILE__,__LINE__,errmsg,NULL);
00118     }
00119   }
00120 #endif
00121   curRegion->RemoveReference();
00122   curRegion=NULL;
00123 }
00124   
00125 
00126 /*! @file
00127  * @brief Implements EventTranslator, which receives events from EventRouters in non-Main processes and adds them into a SharedQueue for Main to pick up
00128  * @author ejt (Creator)
00129  *
00130  * $Author: ejt $
00131  * $Name: tekkotsu-3_0 $
00132  * $Revision: 1.22 $
00133  * $State: Exp $
00134  * $Date: 2006/09/28 21:00:27 $
00135  */
00136 

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