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 "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