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 void
00020 EventTranslator::encodeEvent(const EventBase& event, bool onlyReady/*=false*/) {
00021   event.setSaveFormat(EventBase::BINARY);
00022   EventBase::classTypeID_t header=event.getClassTypeID();
00023   const unsigned int bufsize=LoadSave::getSerializedSize(header)+event.getBinSize();
00024   char * const buf=bufferRequest(bufsize);
00025   if(buf==NULL) {
00026     cerr << "ERROR: EventTranslator unable to transmit event because requested buffer was NULL" << endl;
00027     return;
00028   }
00029   char * cur=buf;
00030   unsigned int remain=bufsize;
00031   if(!LoadSave::encodeInc(header,cur,remain,"Ran out of space encoding event header")) return;
00032   unsigned int used=event.saveBuffer(cur,remain);
00033   if(used==0) {
00034     cerr << "ERROR: EventTranslator unable to transmit event because EventBase::saveBuffer failed (buffer==" << (void*)(cur) << ", size==" << remain << ")" << endl;
00035     post(buf,0,onlyReady);
00036     return;
00037   }
00038   cur+=used;
00039   remain-=used;
00040   ASSERT(cur-buf==(int)(bufsize-remain),"used count does not match offset");
00041   post(buf,bufsize-remain,onlyReady);
00042   return;
00043 }
00044 
00045 EventBase*
00046 EventTranslator::decodeEvent(const char * entry, unsigned int size) {
00047   EventBase::classTypeID_t header;
00048   if(!LoadSave::decodeInc(header,entry,size,"Ran out of space decoding event")) return NULL;
00049   //cout << "decodeEvent(" << (void*)entry << ","<< size << ") header is " << header << " (" << entry[0] << entry[1] << entry[2] << entry[3] << ")" << endl;
00050   EventBase* evt=EventBase::getTypeRegistry().create(header);
00051   if(evt==NULL) {
00052     cerr << "ERROR: EventTranslator unable to translate buffer because header does not match a previously registered class type id" << endl;
00053     return NULL;
00054   }
00055   evt->setSaveFormat(EventBase::BINARY);
00056   if(evt->loadBuffer(entry,size)==0) {
00057     cerr << "ERROR: EventTranlator unable to translate buffer because data is malformed (EventBase::loadBuffer failed)" << endl;
00058     return NULL;
00059   }
00060   //cout << "decodes to " << evt->getDescription() << endl;
00061   return evt;
00062 }
00063 
00064 void
00065 NoOpEventTranslator::encodeEvent(const EventBase& event, bool /*onlyReady=false*/) {
00066   evtRouter.postEvent(event);
00067 }
00068 
00069 char*
00070 IPCEventTranslator::bufferRequest(unsigned int size) {
00071   ASSERT(curRegion==NULL,"WARNING: IPCEventTranslator::bufferRequest() curRegion was not NULL");
00072   try {
00073     curRegion = new RCRegion(size);
00074     return curRegion->Base();
00075   } catch(...) {
00076     curRegion=NULL;
00077     throw;
00078   }
00079 }
00080 
00081 void
00082 IPCEventTranslator::post(const char* buf, unsigned int size, bool onlyReady) {
00083   ASSERTRET(curRegion!=NULL,"ERROR: IPCEventTranslator::post(buf,size) was NULL");
00084   if(size==0) {
00085     curRegion->RemoveReference();
00086     curRegion=NULL;
00087     return;
00088   }
00089   if(buf!=curRegion->Base()) {
00090     cerr << "ERROR: IPCEventTranslator::post(buf,size) buf does not match value given from previous bufferRequest()" << endl;
00091     return;
00092   }
00093 #ifdef PLATFORM_APERIOS
00094   if(!onlyReady) {
00095     subject.SetData(curRegion);
00096     subject.NotifyObservers();
00097   } else {
00098     for(ObserverConstIterator it=subject.begin(); it!=subject.end(); ++it) {
00099       if(subject.IsReady(*it)) {
00100         subject.SetData(*it,curRegion);
00101         subject.NotifyObserver(*it);
00102       }
00103     }
00104   }
00105 #else
00106   if(!onlyReady || subject.getMessageSN(subject.newest())==subject.getMessagesRead()) {
00107     try {
00108       subject.sendMessage(curRegion);
00109     } catch(const std::exception& ex) {
00110       static char errmsg[256];
00111       strncpy(errmsg,("Occurred during IPCEventTranslator::post(), dropping interprocess event "+curName).c_str(),256);
00112       ProjectInterface::uncaughtException(__FILE__,__LINE__,errmsg,&ex);
00113     } catch(...) {
00114       static char errmsg[256];
00115       strncpy(errmsg,("Occurred during IPCEventTranslator::post(), dropping interprocess event "+curName).c_str(),256);
00116       ProjectInterface::uncaughtException(__FILE__,__LINE__,errmsg,NULL);
00117     }
00118   }
00119 #endif
00120   curRegion->RemoveReference();
00121   curRegion=NULL;
00122 }
00123   
00124 
00125 /*! @file
00126  * @brief Implements EventTranslator, which receives events from EventRouters in non-Main processes and adds them into a SharedQueue for Main to pick up
00127  * @author ejt (Creator)
00128  *
00129  * $Author: ejt $
00130  * $Name: tekkotsu-4_0 $
00131  * $Revision: 1.23 $
00132  * $State: Exp $
00133  * $Date: 2007/05/21 17:02:39 $
00134  */
00135 

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