00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 namespace delegates
00025 {
00026
00027 #define MYGUI_COMBINE(a, b) MYGUI_COMBINE1(a, b)
00028 #define MYGUI_COMBINE1(a, b) a##b
00029
00030 #define MYGUI_I_DELEGATE MYGUI_COMBINE(IDelegate, MYGUI_SUFFIX)
00031
00032 #define MYGUI_C_STATIC_DELEGATE MYGUI_COMBINE(CStaticDelegate, MYGUI_SUFFIX)
00033 #define MYGUI_C_METHOD_DELEGATE MYGUI_COMBINE(CMethodDelegate, MYGUI_SUFFIX)
00034
00035 #define MYGUI_C_DELEGATE MYGUI_COMBINE(CDelegate, MYGUI_SUFFIX)
00036 #define MYGUI_C_MULTI_DELEGATE MYGUI_COMBINE(CMultiDelegate, MYGUI_SUFFIX)
00037
00038
00039
00040 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
00041 class MYGUI_I_DELEGATE
00042 {
00043 public:
00044 virtual ~MYGUI_I_DELEGATE() { }
00045 virtual bool isType( const std::type_info& _type) = 0;
00046 virtual void invoke( MYGUI_PARAMS ) = 0;
00047 virtual bool compare( MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS * _delegate) const = 0;
00048 virtual bool compare(IDelegateUnlink * _unlink) const { return false; }
00049 };
00050
00051
00052
00053 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
00054 class MYGUI_C_STATIC_DELEGATE : public MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS
00055 {
00056 public:
00057 typedef void (*Func)( MYGUI_PARAMS );
00058
00059 MYGUI_C_STATIC_DELEGATE (Func _func) : mFunc(_func) { }
00060
00061 virtual bool isType( const std::type_info& _type) { return typeid( MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS ) == _type; }
00062
00063 virtual void invoke( MYGUI_PARAMS )
00064 {
00065 mFunc( MYGUI_ARGS );
00066 }
00067
00068 virtual bool compare( MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS * _delegate) const
00069 {
00070 if (nullptr == _delegate || !_delegate->isType(typeid(MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS)) ) return false;
00071 MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS * cast = static_cast<MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS *>(_delegate);
00072 return cast->mFunc == mFunc;
00073 }
00074 virtual bool compare(IDelegateUnlink * _unlink) const { return false; }
00075
00076 private:
00077 Func mFunc;
00078 };
00079
00080
00081
00082 template MYGUI_T_TEMPLATE_PARAMS
00083 class MYGUI_C_METHOD_DELEGATE : public MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS
00084 {
00085 public:
00086 typedef void (T::*Method)( MYGUI_PARAMS );
00087
00088 MYGUI_C_METHOD_DELEGATE(IDelegateUnlink * _unlink, T * _object, Method _method) : mUnlink(_unlink), mObject(_object), mMethod(_method) { }
00089
00090 virtual bool isType( const std::type_info& _type) { return typeid( MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS ) == _type; }
00091
00092 virtual void invoke( MYGUI_PARAMS )
00093 {
00094 (mObject->*mMethod)( MYGUI_ARGS );
00095 }
00096
00097 virtual bool compare( MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS * _delegate) const
00098 {
00099 if (nullptr == _delegate || !_delegate->isType(typeid(MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS)) ) return false;
00100 MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS * cast = static_cast< MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS * >(_delegate);
00101 return cast->mObject == mObject && cast->mMethod == mMethod;
00102 }
00103
00104 virtual bool compare(IDelegateUnlink * _unlink) const
00105 {
00106 return mUnlink == _unlink;
00107 }
00108
00109 private:
00110 IDelegateUnlink *mUnlink;
00111 T * mObject;
00112 Method mMethod;
00113 };
00114
00115 }
00116
00117
00118
00119
00120
00121 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
00122 inline delegates::MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS * newDelegate( void (*_func)( MYGUI_PARAMS ) )
00123 {
00124 return new delegates::MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS (_func);
00125 }
00126
00127
00128
00129
00130
00131 template MYGUI_T_TEMPLATE_PARAMS
00132 inline delegates::MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS * newDelegate( T * _object, void (T::*_method)( MYGUI_PARAMS ) )
00133 {
00134 return new delegates::MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS (delegates::GetDelegateUnlink(_object), _object, _method);
00135 }
00136
00137 namespace delegates
00138 {
00139
00140 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
00141 class MYGUI_C_DELEGATE
00142 {
00143 public:
00144 typedef MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS IDelegate;
00145
00146 MYGUI_C_DELEGATE () : mDelegate(nullptr) { }
00147 MYGUI_C_DELEGATE (const MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& _event)
00148 {
00149
00150 mDelegate = _event.mDelegate;
00151 const_cast< MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
00152 }
00153 ~MYGUI_C_DELEGATE () { clear(); }
00154
00155 bool empty() const { return mDelegate == nullptr; }
00156
00157 void clear()
00158 {
00159 if (mDelegate)
00160 {
00161 delete mDelegate;
00162 mDelegate = nullptr;
00163 }
00164 }
00165
00166 MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS & operator=(IDelegate* _delegate)
00167 {
00168 delete mDelegate;
00169 mDelegate = _delegate;
00170 return *this;
00171 }
00172
00173 MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS & operator=(const MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& _event)
00174 {
00175
00176 delete mDelegate;
00177 mDelegate = _event.mDelegate;
00178 const_cast< MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
00179
00180 return *this;
00181 }
00182
00183 void operator()( MYGUI_PARAMS )
00184 {
00185 if (mDelegate == nullptr) return;
00186 mDelegate->invoke( MYGUI_ARGS );
00187 }
00188
00189 private:
00190 IDelegate * mDelegate;
00191 };
00192
00193
00194
00195 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
00196 class MYGUI_C_MULTI_DELEGATE
00197 {
00198 public:
00199 typedef MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS IDelegate;
00200 typedef MYGUI_TYPENAME std::list<IDelegate* > ListDelegate;
00201 typedef MYGUI_TYPENAME ListDelegate::iterator ListDelegateIterator;
00202 typedef MYGUI_TYPENAME ListDelegate::const_iterator ConstListDelegateIterator;
00203
00204 MYGUI_C_MULTI_DELEGATE () { }
00205 ~MYGUI_C_MULTI_DELEGATE () { clear(); }
00206
00207 bool empty() const
00208 {
00209 for (ConstListDelegateIterator iter = mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
00210 {
00211 if (*iter) return false;
00212 }
00213 return true;
00214 }
00215
00216 void clear()
00217 {
00218 for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
00219 {
00220 if (*iter)
00221 {
00222 delete (*iter);
00223 (*iter) = nullptr;
00224 }
00225 }
00226 }
00227
00228 void clear(IDelegateUnlink * _unlink)
00229 {
00230 for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
00231 {
00232 if ((*iter) && (*iter)->compare(_unlink))
00233 {
00234 delete (*iter);
00235 (*iter) = nullptr;
00236 }
00237 }
00238 }
00239
00240 MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS & operator+=(IDelegate* _delegate)
00241 {
00242 for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
00243 {
00244 if ((*iter) && (*iter)->compare(_delegate))
00245 {
00246 MYGUI_ASSERT(false, "dublicate delegate");
00247 }
00248 }
00249 mListDelegates.push_back(_delegate);
00250 return *this;
00251 }
00252
00253 MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS & operator-=(IDelegate* _delegate)
00254 {
00255 for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
00256 {
00257 if ((*iter) && (*iter)->compare(_delegate))
00258 {
00259
00260 if ((*iter) != _delegate) delete (*iter);
00261 (*iter) = nullptr;
00262 break;
00263 }
00264 }
00265 delete _delegate;
00266 return *this;
00267 }
00268
00269 void operator()( MYGUI_PARAMS )
00270 {
00271 ListDelegateIterator iter = mListDelegates.begin();
00272 while (iter != mListDelegates.end())
00273 {
00274 if (nullptr == (*iter))
00275 {
00276 iter = mListDelegates.erase(iter);
00277 }
00278 else
00279 {
00280 (*iter)->invoke( MYGUI_ARGS );
00281 ++iter;
00282 }
00283 }
00284 }
00285
00286 private:
00287
00288 MYGUI_C_MULTI_DELEGATE (const MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS & _event);
00289 MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS & operator=(const MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS & _event);
00290
00291
00292 private:
00293 ListDelegate mListDelegates;
00294
00295 };
00296
00297
00298 #undef MYGUI_COMBINE
00299 #undef MYGUI_COMBINE1
00300
00301 #undef MYGUI_I_DELEGATE
00302
00303 #undef MYGUI_C_STATIC_DELEGATE
00304 #undef MYGUI_C_METHOD_DELEGATE
00305
00306 #undef MYGUI_C_DELEGATE
00307 #undef MYGUI_C_MULTI_DELEGATE
00308
00309 #undef MYGUI_SUFFIX
00310 #undef MYGUI_TEMPLATE
00311 #undef MYGUI_TEMPLATE_PARAMS
00312 #undef MYGUI_TEMPLATE_ARGS
00313 #undef MYGUI_T_TEMPLATE_PARAMS
00314 #undef MYGUI_T_TEMPLATE_ARGS
00315 #undef MYGUI_PARAMS
00316 #undef MYGUI_ARGS
00317 #undef MYGUI_TYPENAME
00318
00319 }