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