base_event.hh

Go to the documentation of this file.
00001 /*
00008  * LEGAL:   COPYRIGHT (C) 2005 JIM E. BROOKS
00009  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00010  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00011  *****************************************************************************/
00012 
00013 #ifndef BASE_EVENT_HH
00014 #define BASE_EVENT_HH 1
00015 
00016 #include "base_common.hh"
00017 
00018 namespace base {
00019 
00059 template<typename EVENT=Void>  // Void, not void
00060 class Event : public Threadable
00061 {
00062 public:
00068     class ListenerFunctor : public Shared
00069     {
00070     public:
00071                         ListenerFunctor( void ) { }
00072         virtual         ~ListenerFunctor() { }
00073         virtual void    operator()( EVENT event ) { }
00074     };
00075 
00076 private:
00077     typedef FastLock Lock;
00078 
00079 #if ! DOXYGEN
00080 // For all methods except for ctor.
00081 #define EVENT_PROLOGUE()                                    \
00082 {                                                           \
00083     /* In case Event object is persistent. */               \
00084     if ( UX(base::global.mExiting) ) return;                \
00085     THREAD_CODE( Lock::Auto autolock( mInstanceLock ); )    \
00086 }
00087 #endif
00088 
00089 public:
00090 
00091     Event( void )
00092     {
00093     //EVENT_PROLOGUE();
00094 
00095         // Ensure lock is on heap, not stack.
00096         THREAD_CODE( mInstanceLock = new Lock; )
00097     }
00098 
00099     ~Event()
00100     {
00101     EVENT_PROLOGUE();
00102 
00103         THREAD_CODE( delete mInstanceLock; )
00104     }
00105 
00107     void Listen( SharedPtr<ListenerFunctor> listener )
00108     {
00109     EVENT_PROLOGUE();
00110 
00111         mListeners.push_front( listener );
00112     }
00113 
00115     void Unlisten( SharedPtr<ListenerFunctor> listener )
00116     {
00117     EVENT_PROLOGUE();
00118 
00119         typename Listeners::iterator iter;
00120         iter = std::find( mListeners.begin(), mListeners.end(), listener );
00121         if ( iter != mListeners.end() )
00122         {
00123             mListeners.erase( iter );
00124         }
00125     }
00126 
00129     void Broadcast( EVENT event )
00130     {
00131     EVENT_PROLOGUE();
00132 
00133         // Call every listener.
00134         typename Listeners::iterator iter;
00135         for ( iter = mListeners.begin(); iter != mListeners.end(); ++iter )
00136         {
00137             ListenerFunctor& functor = (*iter).REF();
00138             functor( event );
00139         }
00140     }
00141 
00142 private:
00143     // Contain the actual functors, not copies.
00144     typedef std::list< SharedPtr<ListenerFunctor> > Listeners;
00145     Listeners   mListeners;
00146     THREAD_CODE( mutable Lock* mInstanceLock; )
00147 
00148 #undef EVENT_PROLOGUE
00149 };
00150 
00151 } // namespace base
00152 
00153 #endif // BASE_EVENT_HH
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:06 2007