00001 #ifndef EVENT_SENDER_H 00002 #define EVENT_SENDER_H 00003 00023 #include <list> 00024 #include <typeinfo> 00025 #include <string> 00026 #include <sstream> 00027 00028 #include "Listener.h" // uses inline 00029 #include "EventFWD.h" 00030 #include "PolymorphEvent.h" 00031 //class PolymorphEvent; 00032 00033 template <typename EvType> 00034 class EventSender 00035 { 00036 public: // types 00038 typedef Listener<EvType> TListener; 00039 00040 private: // types 00042 friend class Listener<EvType>; 00044 typedef std::list<TListener*> Registry; 00045 00046 public: // static methods 00047 class IllegalSendError; 00048 inline static void remove(TListener&); 00049 inline static void add(TListener&); 00050 inline static void send(const EvType&); 00051 inline static bool isSending(); 00052 inline static bool hasListeners(); 00053 inline static unsigned int getNumListeners(); 00054 inline static unsigned int getMinNumIgnored(); 00055 00056 private: // construct/destroy singleton 00057 EventSender(): _isBusySending(false), _eventIgnored(0) {} 00058 ~EventSender(); 00059 00060 private: // methods called by Listener 00061 void registerListener(TListener*); 00062 void removeListener(TListener*); 00063 void incEventIgnored() {_eventIgnored ++;} 00064 static EventSender<EvType>& instance(); // MUST NOT BE INLINE 00065 00066 private: // utility methods 00067 void sendEvent(const EvType&); 00068 void cleanupQueues(); 00069 bool removeFrom(Registry&, TListener*); 00070 inline std::string lisnrID(TListener* = NULL) const; 00071 //bool hasListener(TListener*) const; 00072 00073 private: // data 00075 Registry _registry; 00076 00078 bool _isBusySending; 00080 unsigned int _eventIgnored; 00082 Registry _registrationQueue; 00084 Registry _removalQueue; 00085 }; 00086 00091 template <> 00092 class EventSender<PolymorphEvent> 00093 { 00094 public: 00100 static void send(const PolymorphEvent& event) 00101 { 00102 event.send(); 00103 } 00104 }; 00105 00106 /* Include IllegalSendError in this header so users don't have 00107 to include manually. It has to be included after class definition 00108 since it is an inner class to EventSender. 00109 */ 00110 #include "IllegalSendError.h" 00111 00117 template<typename EvType> 00118 inline bool 00119 EventSender<EvType>::hasListeners() 00120 { 00121 return ! instance()._registry.empty(); 00122 } 00123 00130 template<typename EvType> 00131 inline unsigned int 00132 EventSender<EvType>::getMinNumIgnored() 00133 { 00134 return instance()._eventIgnored; 00135 } 00136 00141 template<typename EvType> 00142 inline unsigned int 00143 EventSender<EvType>::getNumListeners() 00144 { 00145 return instance()._registry.size(); 00146 } 00147 00164 template<typename EvType> 00165 inline void 00166 EventSender<EvType>::send(const EvType& event) 00167 { 00168 instance().sendEvent(event); 00169 } 00170 00174 template<typename EvType> 00175 inline bool 00176 EventSender<EvType>::isSending() 00177 { 00178 return instance()._isBusySending; 00179 } 00180 00184 template<typename EvType> 00185 inline void 00186 EventSender<EvType>::remove(TListener& listener) 00187 { 00188 listener.TListener::ignoreEvents(); 00189 } 00190 00194 template<typename EvType> 00195 inline void 00196 EventSender<EvType>::add(TListener& listener) 00197 { 00198 listener.TListener::listenForEvents(); 00199 } 00200 00202 template<typename EvType> 00203 inline std::string 00204 EventSender<EvType>::lisnrID(TListener* lisnr) 00205 const 00206 { 00207 std::ostringstream lisnrStr; 00208 lisnrStr << typeid(TListener).name(); 00209 if (lisnr) lisnrStr << ":" << lisnr; 00210 return lisnrStr.str(); 00211 } 00212 00213 //#ifdef __GNUG__ 00214 // // because gcc doesn't handle separate template definition 00215 // #include "EventSender.cc" 00216 //#endif 00217 00218 #endif // EVENT_SENDER_H 00219
1.5.6