Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
EventTranslator.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_EventTranslator_h_ 00003 #define INCLUDED_EventTranslator_h_ 00004 00005 #include "Events/EventTrapper.h" 00006 #include "Events/EventListener.h" 00007 #include "IPC/MutexLock.h" 00008 #include <map> 00009 00010 //! EventTranslator receives events from EventRouters in non-Main processes and adds them into a SharedQueue for Main to pick up 00011 class EventTranslator : public EventTrapper, public EventListener { 00012 public: 00013 //!constructor 00014 EventTranslator() : trapRet(false) {} 00015 00016 //!destructor 00017 virtual ~EventTranslator() {} 00018 00019 //! Call this with events which should be forwarded to other processes 00020 /*! @param event the event to serialize and send 00021 * @param onlyReady if true, only send the event to observers which do not have any message backlog (if supported by transfer mechanism) */ 00022 virtual void encodeEvent(const EventBase& event, bool onlyReady=false); 00023 00024 //! Call this with events which should be forwarded to other processes (redirects to encodeEvent()) 00025 /*! By providing an EventTrapper interface, you can directly 00026 * register this class with an EventRouter instead of having to 00027 * manually forward events (although you could do that as well) 00028 * @return #trapRet, which you can set via setTrapEventValue() */ 00029 virtual bool trapEvent(const EventBase& event) { encodeEvent(event); return trapRet; } 00030 00031 //! Call this with events which should be forwarded to other processes (redirects to encodeEvent()) 00032 /*! By providing an EventListener interface, you can directly 00033 * register this class with an EventRouter instead of having to 00034 * manually forward events (although you could do that as well) */ 00035 virtual void processEvent(const EventBase& event) { encodeEvent(event); } 00036 00037 //! Called with buffers containing incoming events which should be reconstituted 00038 /*! @return the reconstituted event, or NULL if an error occured (malformed data) */ 00039 static EventBase* decodeEvent(const char* buf, unsigned int size); 00040 00041 //! set #trapRet, which can let you decide whether trapped events should be filtered or not 00042 virtual void setTrapEventValue(bool v) { trapRet=v; } 00043 00044 00045 protected: 00046 00047 //! Called by encodeEvent() to request a buffer for serializing into, must be at least @a size 00048 /*! This buffer will then be sent to post(), which should free 00049 * it (or recycle it for usage by a later bufferRequest()) */ 00050 virtual char* bufferRequest(unsigned int size)=0; 00051 00052 //! Called by encodeEvent() after serialization is complete for communication to other processes 00053 /*! @param buf the data to be sent, will be a buffer previously requested from #bufferRequest 00054 * @param size the number of bytes to send 00055 * @param onlyReady if true, only send the event to observers which do not have any message backlog (if supported by transfer mechanism) 00056 * 00057 * You will always get this callback after each call to bufferRequest(), even 00058 * in the event of an error during saving. If an error occured, the callback 00059 * will receive 0 for size.*/ 00060 virtual void post(const char* buf, unsigned int size, bool onlyReady)=0; 00061 00062 //! The value which trapEvent() should return 00063 bool trapRet; 00064 00065 private: 00066 EventTranslator(const EventTranslator&); //!< don't call 00067 EventTranslator& operator=(const EventTranslator&); //!< don't call 00068 }; 00069 00070 class EventRouter; 00071 00072 //! For completeness, if you want to have events be piped directly to the local erouter instead having to be encoded and decoded 00073 /*! Unfortunately, this still entails a memory copy of the event since 00074 * we have to make a new event for posting to the event router. We 00075 * could avoid this if events were reference counted or if there was 00076 * a way to direct the EventRouter not to free the event after 00077 * processing. 00078 * 00079 * Beware of subscribing this class as a listener to the same 00080 * EventRouter that it is sending to -- could cause infinite 00081 * recursion */ 00082 class NoOpEventTranslator : public EventTranslator { 00083 public: 00084 //! constructor 00085 explicit NoOpEventTranslator(EventRouter& er) : EventTranslator(), evtRouter(er) {} 00086 00087 virtual void encodeEvent(const EventBase& event, bool onlyReady=false); 00088 00089 protected: 00090 //! should never be called, only included to satisfy interface 00091 virtual char* bufferRequest(unsigned int /*size*/) { return NULL; } 00092 //! should never be called, only included to satisfy interface 00093 virtual void post(const char* /*buf*/, unsigned int /*size*/, bool /*onlyReady*/) { } 00094 00095 EventRouter& evtRouter; //!< the EventRouter to send events to 00096 }; 00097 00098 00099 #ifdef PLATFORM_APERIOS 00100 class OSubject; 00101 #else 00102 class MessageQueueBase; 00103 #endif 00104 class RCRegion; 00105 00106 //! An implementation of EventTranslator which will forward events using the inter-process mechanisms of the current platform 00107 /*! The current implementation creates an RCRegion for each event and 00108 * then releases its reference to the region after it is sent. A 00109 * more efficient implementation might retain a queue of recycled 00110 * RCRegions to reduce allocation costs */ 00111 class IPCEventTranslator : public EventTranslator { 00112 public: 00113 00114 #ifdef PLATFORM_APERIOS 00115 typedef OSubject IPCSender_t; //!< the class for sending IPC messages on aperios 00116 #else 00117 typedef MessageQueueBase IPCSender_t; //!< the class for sending IPC messages on unix-based systems 00118 #endif 00119 00120 //! constructor 00121 explicit IPCEventTranslator(IPCSender_t& subj) : EventTranslator(), subject(subj), curRegion(NULL), curName(), lock() {} 00122 00123 //! extends base class's implementation to store @a event.getName() into #curName 00124 virtual void encodeEvent(const EventBase& event, bool onlyReady=false) { 00125 curName=event.getName(); 00126 EventTranslator::encodeEvent(event,onlyReady); 00127 } 00128 00129 protected: 00130 virtual char* bufferRequest(unsigned int size); 00131 virtual void post(const char* buf, unsigned int size, bool onlyReady); 00132 00133 IPCSender_t& subject; //!< where to post messages upon serialization, set by constructor 00134 RCRegion* curRegion; //!< the region currently being serialized into, only valid between call to bufferRequest() and following post() 00135 std::string curName; //!< name of current event being posted (for error messages) 00136 MutexLock<ProcessID::NumProcesses> lock; //!< prevent concurrent posts, held for the duration of #curRegion 00137 00138 private: 00139 IPCEventTranslator(const IPCEventTranslator&); //!< don't call 00140 IPCEventTranslator operator=(const IPCEventTranslator&); //!< don't call 00141 }; 00142 00143 /*! @file 00144 * @brief Describes EventTranslator and IPCEventTranslator, which receives events from EventRouters in non-Main processes and adds them into a SharedQueue for Main to pick up 00145 * @author ejt (Creator) 00146 */ 00147 00148 #endif |
Tekkotsu v5.1CVS |
Generated Mon May 9 04:58:38 2016 by Doxygen 1.6.3 |