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