00001
00002
00003 #ifndef EVENT_SENDER_CC_TEMPLATE
00004 #define EVENT_SENDER_CC_TEMPLATE
00005
00024 #include <algorithm>
00025 #include "EventSender.h"
00026
00033 template <typename EvType>
00034 EventSender<EvType>&
00035 EventSender<EvType>::instance()
00036 {
00037 static EventSender<EvType> eventSender;
00038 return eventSender;
00039 }
00040
00042 template <typename EvType>
00043 void
00044 EventSender<EvType>::sendEvent(const EvType& event)
00045 {
00046
00047
00048
00049
00050
00051
00052
00053 if (_isBusySending)
00054 throw IllegalSendError();
00055
00056
00057 if (_registry.empty())
00058 {
00059 theseLogs->logN(1,"No %s event registered.",lisnrID().c_str());
00060 return;
00061 }
00062
00063 assert(!_isBusySending);
00064 _isBusySending = true;
00065 _eventIgnored = 0;
00066
00067
00068 typename Registry::iterator registryIter = _registry.begin();
00069 for (typename Registry::iterator registryIter = _registry.begin();
00070 registryIter != _registry.end(); ++ registryIter)
00071 {
00072 theseLogs->logNdev(1,"Calling %s::processEventPublic",lisnrID(*registryIter).c_str());
00073 try
00074 {
00075 (*registryIter)->processEventPublic(event);
00076 }
00077 catch (const IllegalSendError&)
00078 {
00079
00080 _isBusySending = false;
00081 cleanupQueues();
00082 throw;
00083 }
00084 catch (const std::exception& e)
00085 {
00086 theseLogs->logNdebug(0,2,"BUG : %s::processEvent() threw an EXCEPTION of type %s", lisnrID(*registryIter).c_str(),typeid(e).name(),e.what());
00087 theseLogs->logNdebug(0,1,"....: The processEvent() must NOT leak ANY exception. \n\t\t\t Message is: ", e.what());
00088 }
00089 catch (...)
00090 {
00091 theseLogs->logNdebug(0,1,"BUG : %s::processEvent() threw an EXCEPTION of UNKNOWN type (not derived from std::exception).",lisnrID(*registryIter).c_str());
00092 }
00093 }
00094
00095 _isBusySending = false;
00096
00097
00098 cleanupQueues();
00099 }
00100
00104 template<typename EvType>
00105 EventSender<EvType>::~EventSender()
00106 {
00107
00108 assert(!_isBusySending);
00109
00110 while (! _registry.empty())
00111 {
00112 _registry.front()->TListener::ignoreEvents();
00113 }
00114 }
00115
00120 template<typename EvType>
00121 void
00122 EventSender<EvType>::cleanupQueues()
00123 {
00124 assert(_isBusySending == false);
00125
00126
00127 while (! _registrationQueue.empty())
00128 {
00129 typename Registry::iterator registryIter = _registrationQueue.begin();
00130 theseLogs->logNdev(1,"Registering queued %s ",lisnrID(*registryIter).c_str());
00131
00132 _registry.splice(_registry.end(), _registrationQueue, registryIter);
00133
00134 assert(std::find(_registrationQueue.begin(),
00135 _registrationQueue.end(), _registry.back())
00136 == _registrationQueue.end());
00137 }
00138
00139
00140 while (! _removalQueue.empty())
00141 {
00142 TListener* lisnr = _removalQueue.back();
00143 theseLogs->logNdev(1,"Removing queued %s ",lisnrID(lisnr).c_str());
00144 if (! removeFrom(_registry, lisnr) )
00145 theseLogs->logNdebug(1000,1,"Listener %s not in registry, removal ignored.", lisnrID(lisnr).c_str());
00146 _removalQueue.pop_back();
00147 }
00148 }
00149
00154 template<typename EvType>
00155 bool
00156 EventSender<EvType>::removeFrom(Registry& container, TListener* lisnr)
00157 {
00158
00159 typename Registry::iterator removeIter
00160 = std::find(container.begin(), container.end(), lisnr);
00161 if ( removeIter != container.end() )
00162 {
00163 container.erase(removeIter);
00164 theseLogs->logNdebug(MAX_DEBUG,1,"%s removed from list",lisnrID(lisnr).c_str());
00165 return true;
00166 }
00167
00168
00169 theseLogs->logN(1,"%s NOT found in list",lisnrID(lisnr).c_str());
00170 return false;
00171 }
00172
00184 template<typename EvType>
00185 void
00186 EventSender<EvType>::removeListener(TListener* lisnr)
00187 {
00188 if (_isBusySending)
00189 {
00190 if (! removeFrom(_registrationQueue, lisnr))
00191 {
00192 assert(std::find(_removalQueue.begin(),
00193 _removalQueue.end(), lisnr) == _removalQueue.end());
00194 _removalQueue.push_back(lisnr);
00195
00196 theseLogs->logNdev(1,"Putting %s on removal queue",lisnrID(lisnr).c_str());
00197 }
00198 else
00199 {
00200 theseLogs->logNdev(1,"%s removed from registration queue",lisnrID(lisnr).c_str());
00201 }
00202 }
00203 else
00204 {
00205 assert(_removalQueue.empty());
00206 assert(_registrationQueue.empty());
00207 const bool removed = removeFrom(_registry, lisnr);
00208 assert(removed);
00209 }
00210 }
00211
00223 template<typename EvType>
00224 void
00225 EventSender<EvType>::registerListener(TListener* lisnr)
00226 {
00227 if (_isBusySending)
00228
00229 {
00230
00231 if (! removeFrom(_removalQueue, lisnr))
00232 {
00233
00234
00235
00236 assert(std::find(_registrationQueue.begin(),
00237 _registrationQueue.end(), lisnr) == _registrationQueue.end());
00238 _registrationQueue.push_back(lisnr);
00239 theseLogs->logNdev(1,"Putting %s on registration queue ",lisnrID(lisnr).c_str());
00240 }
00241 else
00242 {
00243 theseLogs->logNdev(1,"%s removed from registration queue",lisnrID(lisnr).c_str());
00244 }
00245 }
00246 else
00247 {
00248
00249 assert(std::find(_registry.begin(), _registry.end(), lisnr)
00250 == _registry.end());
00251
00252 _registry.push_back(lisnr);
00253 theseLogs->logNdev(1,"Added (immediate) %s to listeners list ",lisnrID(lisnr).c_str());
00254 }
00255 }
00256
00257
00258 #endif // EVENT_SENDER_CC_TEMPLATE
00259