Signalv2ImplVC6.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __SIGNALV2IMPLVC6__
00023 #define __SIGNALV2IMPLVC6__
00024
00025 #ifndef __SIGNALV2__
00026 #error "This is an implementation header. You are not allowed to include it directly!"
00027 #endif
00028
00029 #include <list>
00030 #include <utility>
00031
00032 namespace SigSlot
00033 {
00034
00035 template < typename ParmType1, typename ParmType2 >
00036 class Signalv2 : public Signal
00037 {
00038
00039 public:
00040 typedef typename CBL::Functor2<ParmType1,ParmType2> tCallbackType;
00041
00042
00043
00044 struct tCallback
00045 {
00046 tConnectionId mConnection;
00047 Slot* mSlot;
00048 tCallbackType mCallback;
00049
00050 tCallback( tConnectionId id, Slot* slot, tCallbackType cb )
00051 : mConnection( id ), mSlot( slot ), mCallback( cb )
00052 {
00053 }
00054 };
00055
00056 typedef tCallbackType* tCallbackPtr;
00057 typedef std::list<tCallbackPtr> tCallList;
00058 typedef typename std::list<tCallbackPtr >::iterator tCallIterator;
00059 typedef std::list<tCallback> tCallbackList;
00060 typedef typename std::list<tCallback>::iterator tCbListIterator;
00061 typedef typename std::list<tCallback>::const_iterator const_tCbListIterator;
00062
00063
00064 protected:
00065
00066 void AddCallback( tConnectionId pConnection, Slot* slot, tCallbackType cb )
00067 {
00068 mCallbacks.push_back( tCallback( pConnection, slot, cb ) );
00069 }
00070
00071 bool HasNoCallbacks( ) const
00072 {
00073 return mCallbacks.empty();
00074 }
00075
00076 tCallList& GetCalls( )
00077 {
00078 mCalls.clear();
00079
00080 tCbListIterator i = mCallbacks.begin();
00081 tCbListIterator end = mCallbacks.end();
00082
00083 while ( i!=end)
00084 {
00085 mCalls.push_back( &(i->mCallback) );
00086 i++;
00087 }
00088
00089 return mCalls;
00090 }
00091
00092 void RemoveCall( tConnectionId id )
00093 {
00094 tCbListIterator i = mCallbacks.begin();
00095 tCbListIterator end = mCallbacks.end();
00096
00097 while ( i!=end )
00098 {
00099 if ( i->mConnection == id )
00100 {
00101 mCallbacks.erase( i );
00102 break;
00103 }
00104 i++;
00105 }
00106 }
00107
00108 void DestroyConnections()
00109 {
00110 tCbListIterator elem;
00111
00112 while ( !mCallbacks.empty() )
00113 {
00114 elem = mCallbacks.begin();
00115
00116 elem->mSlot->Unbind( elem->mConnection );
00117 }
00118 }
00119
00120
00121
00122 public:
00123
00124 virtual ~Signalv2()
00125 {
00126 DestroyConnections();
00127 }
00128
00129 void Connect( Slotv2<ParmType1,ParmType2>& slot )
00130 {
00131 Connection c( AssignConnection(), this );
00132
00133 AddCallback( c.GetID(), &slot, slot.GetMethod() );
00134
00135 slot.Bind(c);
00136 }
00137
00138
00139 void Emit( ParmType1 parm1, ParmType2 parm2 )
00140 {
00141 if ( HasNoCallbacks() )
00142 return;
00143
00144 tCallList calls = GetCalls();
00145 tCallIterator i = calls.begin();
00146 tCallIterator end = calls.end();
00147
00148 while ( i != end )
00149 {
00150 (*(*i))( parm1, parm2 );
00151 i++;
00152 }
00153
00154 }
00155
00156 void FreeConnection( Connection* pConnection )
00157 {
00158 RemoveCall( pConnection->GetID() );
00159 FreeConnectionId( pConnection->GetID() );
00160 }
00161
00162 private:
00163
00164 tCallList mCalls;
00165 tCallbackList mCallbacks;
00166
00167
00168 };
00169
00170 }
00171
00172
00173
00174 #endif // Signalv2ImplVC6.hxx
00175