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) {
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
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
00061 return evt;
00062 }
00063
00064 void
00065 NoOpEventTranslator::encodeEvent(const EventBase& event, bool ) {
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
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135