00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __UT_Notifier_C__
00022 #define __UT_Notifier_C__
00023
00024 #include "UT_Notifier.h"
00025 #include "UT_NotifierList.h"
00026 #include "UT_Assert.h"
00027
00028 template <typename EVENT_TYPE>
00029 UT_NotifierImpl<EVENT_TYPE>::UT_NotifierImpl()
00030 : myNotifyingFlag( false ),
00031 myPendingRemovalFlag( false )
00032 {
00033 }
00034
00035 template <typename EVENT_TYPE>
00036 UT_NotifierImpl<EVENT_TYPE>::~UT_NotifierImpl()
00037 {
00038 removeAllObservers();
00039 }
00040
00041
00042 template <typename EVENT_TYPE>
00043 int
00044 UT_NotifierImpl<EVENT_TYPE>::getObserverIndex( const UT_NotifierList &list)const
00045 {
00046 int i;
00047
00048 for( i = 0; i < myObservers.entries(); i ++ )
00049 if( myObservers(i).myFirst == &list )
00050 return i;
00051
00052 return -1;
00053 }
00054
00055
00056 template <typename EVENT_TYPE>
00057 bool
00058 UT_NotifierImpl<EVENT_TYPE>::hasObserver( const UT_NotifierList &list ) const
00059 {
00060 return ( 0 <= getObserverIndex( list ));
00061 }
00062
00063
00064 template <typename EVENT_TYPE>
00065 void
00066 UT_NotifierImpl<EVENT_TYPE>::addObserver( UT_NotifierList &list,
00067 Callback &callback)
00068 {
00069 bool already_registered;
00070
00071
00072 already_registered = hasObserver( list );
00073 UT_ASSERT( ! already_registered );
00074
00075
00076 if( ! already_registered )
00077 {
00078 ObserverPair pair( &list, callback );
00079
00080
00081 myObservers.append( pair );
00082 list.addNotifier( *this );
00083 }
00084 }
00085
00086
00087 template <typename EVENT_TYPE>
00088 void
00089 UT_NotifierImpl<EVENT_TYPE>::removeObserver( UT_NotifierList &list )
00090 {
00091 int i;
00092
00093
00094 i = getObserverIndex( list );
00095 if( 0 <= i )
00096 {
00097
00098 list.removeNotifier( *this );
00099 if( myNotifyingFlag )
00100 {
00101 myObservers(i).myFirst = NULL;
00102 myPendingRemovalFlag = true;
00103 }
00104 else
00105 {
00106 myObservers.remove( i );
00107 }
00108 }
00109 else
00110 {
00111 UT_ASSERT( ! "no observer to remove" );
00112 }
00113 }
00114
00115
00116 template <typename EVENT_TYPE>
00117 void
00118 UT_NotifierImpl<EVENT_TYPE>::removeAllObservers()
00119 {
00120 int i;
00121
00122
00123 for( i = myObservers.entries(); i -- > 0; )
00124 {
00125 if( myObservers(i).myFirst )
00126 myObservers(i).myFirst->removeNotifier( *this );
00127 myObservers.remove( i );
00128 }
00129 }
00130
00131 template <typename EVENT_TYPE>
00132 void
00133 UT_NotifierImpl<EVENT_TYPE>::pruneObservers()
00134 {
00135 int i;
00136
00137
00138 for( i = myObservers.entries(); i -- > 0; )
00139 if( myObservers(i).myFirst == NULL )
00140 myObservers.remove( i );
00141
00142
00143 myPendingRemovalFlag = false;
00144 }
00145
00146 template <typename EVENT_TYPE>
00147 void
00148 UT_NotifierImpl<EVENT_TYPE>::notifyObservers( EVENT_TYPE event )
00149 {
00150 int i, n;
00151 bool old_notifying;
00152
00153
00154 old_notifying = myNotifyingFlag;
00155 myNotifyingFlag = true;
00156
00157
00158
00159
00160 n = myObservers.entries();
00161 for( i = 0; i < n; i++ )
00162 if( myObservers(i).myFirst )
00163 myObservers(i).mySecond( event );
00164
00165
00166 myNotifyingFlag = old_notifying;
00167
00168
00169 if( !myNotifyingFlag && myPendingRemovalFlag )
00170 pruneObservers();
00171 }
00172
00173 #endif // __UT_Notifier_C__