Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

EventTranslator.h

Go 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