00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "CeylanEventSource.h"
00028
00029
00030 #include "CeylanLogPlug.h"
00031 #include "CeylanOperators.h"
00032 #include "CeylanEventListener.h"
00033 #include "CeylanStringUtils.h"
00034
00035
00036 #ifdef CEYLAN_USES_CONFIG_H
00037 #include "CeylanConfig.h"
00038 #endif // CEYLAN_USES_CONFIG_H
00039
00040
00041 using std::string ;
00042 using std::list ;
00043
00044
00045 using namespace Ceylan ;
00046 using namespace Ceylan::Log ;
00047
00048
00049
00050 EventSource::EventSource() :
00051 _listeners()
00052
00053 {
00054
00055 }
00056
00057
00058
00059 EventSource::EventSource( EventListener & listener ) :
00060 _listeners()
00061
00062 {
00063
00064 add( listener ) ;
00065
00066 }
00067
00068
00069
00070 EventSource::~EventSource() throw()
00071 {
00072
00073 if ( ! _listeners.empty() )
00074 {
00075
00076 LogPlug::error( "EventSource destructor: "
00077 + Ceylan::toString(
00078 static_cast<Ceylan::Uint32>( _listeners.size() ) )
00079 + " listener(s) still registered: faulty life cycle, "
00080 "temporary parachute deployed, "
00081 "the listeners should have been unsubscribed before "
00082 "(for example they may have to be deallocated before "
00083 "their sources)." ) ;
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 for ( list<EventListener *>::iterator it = _listeners.begin();
00094 it != _listeners.end(); it++ )
00095 {
00096 (*it)->forgetSource( * this ) ;
00097 }
00098
00099
00100
00101 }
00102
00103 _listeners.clear() ;
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 }
00115
00116
00117
00118 void EventSource::add( EventListener & listener )
00119 {
00120
00121 for ( list<EventListener *>::const_iterator it = _listeners.begin();
00122 it != _listeners.end(); it++ )
00123 {
00124 if ( (*it) == & listener )
00125 throw EventException( "EventSource::add: event listener ("
00126 + listener.toString() + ") is already registered." ) ;
00127
00128 }
00129
00130 #if CEYLAN_DEBUG_EVENTS
00131 LogPlug::debug( "A new event listener registered: "
00132 + listener.toString() ) ;
00133 #endif // CEYLAN_DEBUG_EVENTS
00134
00135 _listeners.push_back( & listener ) ;
00136
00137
00138 }
00139
00140
00141
00142 void EventSource::remove( const EventListener & listener )
00143 {
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 bool found = false ;
00154
00155 list<EventListener *>::iterator it = _listeners.begin() ;
00156
00157 while ( it != _listeners.end() )
00158 {
00159
00160 if ( (*it) == & listener )
00161 {
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 if ( ! found )
00173 found = true ;
00174 else
00175 LogPlug::error( "EventSource::remove: this event source "
00176 "was linked more than once with listener "
00177 + (*it)->toString() ) ;
00178
00179 #if CEYLAN_DEBUG_EVENTS
00180 LogPlug::debug( "EventSource::remove: "
00181 "this event source acknowledges "
00182 "unsubscription from listener " + (*it)->toString() ) ;
00183 #endif // CEYLAN_DEBUG_EVENTS
00184
00185
00186 it = _listeners.erase( it ) ;
00187
00188 }
00189 else
00190 {
00191 ++it ;
00192 }
00193
00194 }
00195
00196 if ( ! found )
00197 throw EventException( "EventSource::remove: event listener "
00198 + listener.toString() + " was not already registered." ) ;
00199
00200 }
00201
00202
00203
00204 void EventSource::removeAllListeners()
00205 {
00206
00207
00208 while ( ! _listeners.empty() )
00209 _listeners.front()->unsubscribeFrom( *this ) ;
00210
00211 }
00212
00213
00214
00215 const string EventSource::toString( Ceylan::VerbosityLevels level ) const
00216 {
00217
00218 if ( _listeners.empty() )
00219 {
00220 return "Event source has currently no registered listener" ;
00221 }
00222 else
00223 {
00224
00225 if ( level == Ceylan::low )
00226 return "Event source has currently "
00227 + Ceylan::toString(
00228 static_cast<Ceylan::Uint32>( _listeners.size() ) )
00229 + " registered listener(s)" ;
00230 else
00231 {
00232
00233 list<string> listenersDescription ;
00234
00235 for ( list<EventListener *>::const_iterator it = _listeners.begin();
00236 it != _listeners.end(); it++ )
00237 listenersDescription.push_back( (*it)->toString() ) ;
00238
00239 return "Event source has currently "
00240 + Ceylan::toString(
00241 static_cast<Ceylan::Uint32>( _listeners.size() ) )
00242 + " registered listener(s): "
00243 + Ceylan::formatStringList( listenersDescription ) ;
00244
00245 }
00246
00247 }
00248 }
00249
00250
00251
00252 bool EventSource::isRegistered( const EventListener & listener )
00253 {
00254
00255 for ( list<EventListener *>::const_iterator it = _listeners.begin();
00256 it != _listeners.end(); it++ )
00257 {
00258
00259 if ( (*it) == & listener )
00260 return true ;
00261
00262 }
00263
00264 return false ;
00265
00266 }
00267
00268
00269
00270 void EventSource::notifyAllListeners( const Event & newEvent )
00271 {
00272
00273
00274
00275 for ( list<EventListener *>::iterator it = _listeners.begin();
00276 it != _listeners.end(); it++ )
00277 {
00278 (*it)->beNotifiedOf( newEvent ) ;
00279 }
00280
00281 }
00282