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) {
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
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
00067 return evt;
00068 }
00069
00070 void
00071 NoOpEventTranslator::encodeEvent(const EventBase& event, bool ) {
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 , 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
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136