| 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 "Shared/Factory.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 //!This should be called during initialization to register all EventBase subclasses 00042 /*! @return true upon success, false if an event matching that prototype's EventBase::getClassTypeID() was already registered */ 00043 template<class EB> 00044 static bool registerPrototype() { 00045 EB prototype; 00046 eventLookup_t::const_iterator it=eventLookup.find(prototype.getClassTypeID()); 00047 if(it!=eventLookup.end()) 00048 return false; 00049 eventLookup[prototype.getClassTypeID()]=new Factory<EB>; 00050 return true; 00051 } 00052 00053 //! set #trapRet, which can let you decide whether trapped events should be filtered or not 00054 virtual void setTrapEventValue(bool v) { trapRet=v; } 00055 00056 00057 protected: 00058 //! Shorthand for they type of #eventLookup 00059 typedef std::map<unsigned int,FactoryBase*> eventLookup_t; 00060 00061 //! Allows quick lookup of event subclasses based on their EventBase::getClassTypeID() 00062 static eventLookup_t eventLookup; 00063 00064 //! Called by encodeEvent() to request a buffer for serializing into, must be at least @a size 00065 /*! This buffer will then be sent to post(), which should free 00066 * it (or recycle it for usage by a later bufferRequest()) */ 00067 virtual char* bufferRequest(unsigned int size)=0; 00068 00069 //! Called by encodeEvent() after serialization is complete for communication to other processes 00070 /*! @param buf the data to be sent, will be a buffer previously requested from #bufferRequest 00071 * @param size the number of bytes to send 00072 * @param onlyReady if true, only send the event to observers which do not have any message backlog (if supported by transfer mechanism) 00073 * 00074 * You will always get this callback after each call to bufferRequest(), even 00075 * in the event of an error during saving. If an error occured, the callback 00076 * will receive 0 for size.*/ 00077 virtual void post(const char* buf, unsigned int size, bool onlyReady)=0; 00078 00079 //! The value which trapEvent() should return 00080 bool trapRet; 00081 00082 private: 00083 EventTranslator(const EventTranslator&); //!< don't call 00084 EventTranslator& operator=(const EventTranslator&); //!< don't call 00085 }; 00086 00087 class EventRouter; 00088 00089 //! For completeness, if you want to have events be piped directly to the local erouter instead having to be encoded and decoded 00090 /*! Unfortunately, this still entails a memory copy of the event since 00091 * we have to make a new event for posting to the event router. We 00092 * could avoid this if events were reference counted or if there was 00093 * a way to direct the EventRouter not to free the event after 00094 * processing. 00095 * 00096 * Beware of subscribing this class as a listener to the same 00097 * EventRouter that it is sending to -- could cause infinite 00098 * recursion */ 00099 class NoOpEventTranslator : public EventTranslator { 00100 public: 00101 //! constructor 00102 explicit NoOpEventTranslator(EventRouter& er) : EventTranslator(), evtRouter(er) {} 00103 00104 virtual void encodeEvent(const EventBase& event, bool onlyReady=false); 00105 00106 protected: 00107 //! should never be called, only included to satisfy interface 00108 virtual char* bufferRequest(unsigned int /*size*/) { return NULL; } 00109 //! should never be called, only included to satisfy interface 00110 virtual void post(const char* /*buf*/, unsigned int /*size*/, bool /*onlyReady*/) { } 00111 00112 EventRouter& evtRouter; //!< the EventRouter to send events to 00113 }; 00114 00115 00116 #ifdef PLATFORM_APERIOS 00117 class OSubject; 00118 #else 00119 class MessageQueueBase; 00120 #endif 00121 class RCRegion; 00122 00123 //! An implementation of EventTranslator which will forward events using the inter-process mechanisms of the current platform 00124 /*! The current implementation creates an RCRegion for each event and 00125 * then releases its reference to the region after it is sent. A 00126 * more efficient implementation might retain a queue of recycled 00127 * RCRegions to reduce allocation costs */ 00128 class IPCEventTranslator : public EventTranslator { 00129 public: 00130 00131 #ifdef PLATFORM_APERIOS 00132 typedef OSubject IPCSender_t; //!< the class for sending IPC messages on aperios 00133 #else 00134 typedef MessageQueueBase IPCSender_t; //!< the class for sending IPC messages on unix-based systems 00135 #endif 00136 00137 //! constructor 00138 explicit IPCEventTranslator(IPCSender_t& subj) : EventTranslator(), subject(subj), curRegion(NULL), curName() {} 00139 00140 //! extends base class's implementation to store @a event.getName() into #curName 00141 virtual void encodeEvent(const EventBase& event, bool onlyReady=false) { 00142 curName=event.getName(); 00143 EventTranslator::encodeEvent(event,onlyReady); 00144 } 00145 00146 protected: 00147 virtual char* bufferRequest(unsigned int size); 00148 virtual void post(const char* buf, unsigned int size, bool onlyReady); 00149 00150 IPCSender_t& subject; //!< where to post messages upon serialization, set by constructor 00151 RCRegion* curRegion; //!< the region currently being serialized into, only valid between call to bufferRequest() and following post() 00152 std::string curName; //!< name of current event being posted (for error messages) 00153 00154 private: 00155 IPCEventTranslator(const IPCEventTranslator&); //!< don't call 00156 IPCEventTranslator operator=(const IPCEventTranslator&); //!< don't call 00157 }; 00158 00159 /*! @file 00160 * @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 00161 * @author ejt (Creator) 00162 * 00163 * $Author: ejt $ 00164 * $Name: tekkotsu-3_0 $ 00165 * $Revision: 1.12 $ 00166 * $State: Exp $ 00167 * $Date: 2006/09/25 23:28:12 $ 00168 */ 00169 00170 #endif |
|
Tekkotsu v3.0 |
Generated Wed Oct 4 00:03:43 2006 by Doxygen 1.4.7 |