• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

MyGUI_DelegateImplement.h

Go to the documentation of this file.
00001 
00007 /*
00008     This file is part of MyGUI.
00009 
00010     MyGUI is free software: you can redistribute it and/or modify
00011     it under the terms of the GNU Lesser General Public License as published by
00012     the Free Software Foundation, either version 3 of the License, or
00013     (at your option) any later version.
00014 
00015     MyGUI is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public License
00021     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
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     // базовый класс всех делегатов
00041     MYGUI_TEMPLATE   MYGUI_TEMPLATE_PARAMS
00042     class MYGUI_I_DELEGATE
00043     {
00044     public:
00045         virtual ~MYGUI_I_DELEGATE() { }
00046         virtual bool isType( const std::type_info& _type) = 0;
00047         virtual void invoke( MYGUI_PARAMS ) = 0;
00048         virtual bool compare(  MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS  * _delegate) = 0;
00049         virtual bool compare(IDelegateUnlink * _unlink) { return false; }
00050     };
00051 
00052 
00053     // делегат для статической функции
00054     MYGUI_TEMPLATE   MYGUI_TEMPLATE_PARAMS
00055     class MYGUI_C_STATIC_DELEGATE : public  MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS
00056     {
00057     public:
00058         typedef void (*Func)( MYGUI_PARAMS );
00059 
00060         MYGUI_C_STATIC_DELEGATE (Func _func) : mFunc(_func) { }
00061 
00062         virtual bool isType( const std::type_info& _type) { return typeid( MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS ) == _type; }
00063 
00064         virtual void invoke( MYGUI_PARAMS )
00065         {
00066             mFunc( MYGUI_ARGS );
00067         }
00068 
00069         virtual bool compare(  MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS  * _delegate)
00070         {
00071             if (nullptr == _delegate || false == _delegate->isType(typeid(MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS)) ) return false;
00072             MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS * cast = static_cast<MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS *>(_delegate);
00073             return cast->mFunc == mFunc;
00074         }
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)
00098         {
00099             if (nullptr == _delegate || false == _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)
00105         {
00106             return mUnlink == _unlink;
00107         }
00108 
00109     private:
00110         IDelegateUnlink *mUnlink;
00111         T * mObject;
00112         Method mMethod;
00113     };
00114 
00115 
00116     // шаблон для создания делегата статической функции
00117     // параметры : указатель на функцию
00118     // пример : newDelegate(funk_name);
00119     // пример : newDelegate(class_name::static_method_name);
00120     MYGUI_TEMPLATE   MYGUI_TEMPLATE_PARAMS
00121     inline  MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS  * newDelegate( void (*_func)( MYGUI_PARAMS ) )
00122     {
00123         return new  MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS  (_func);
00124     }
00125 
00126 
00127     // шаблон для создания делегата метода класса
00128     // параметры : указатель на объект класса и указатель на метод класса
00129     // пример : newDelegate(&object_name, &class_name::method_name);
00130     template MYGUI_T_TEMPLATE_PARAMS
00131     inline  MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS  * newDelegate( T * _object, void (T::*_method)( MYGUI_PARAMS ) )
00132     {
00133         return new  MYGUI_C_METHOD_DELEGATE  MYGUI_T_TEMPLATE_ARGS  (GetDelegateUnlink(_object), _object, _method);
00134     }
00135 
00136 
00137     // шаблон класса делегата
00138     MYGUI_TEMPLATE   MYGUI_TEMPLATE_PARAMS
00139     class MYGUI_C_DELEGATE
00140     {
00141     public:
00142         typedef  MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS  IDelegate;
00143 
00144         MYGUI_C_DELEGATE () : mDelegate(nullptr) { }
00145         MYGUI_C_DELEGATE (const MYGUI_C_DELEGATE  MYGUI_TEMPLATE_ARGS& _event)
00146         {
00147             // забираем себе владение
00148             mDelegate = _event.mDelegate;
00149             const_cast< MYGUI_C_DELEGATE  MYGUI_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
00150         }
00151         ~MYGUI_C_DELEGATE () { clear(); }
00152 
00153         bool empty() { return mDelegate == nullptr; }
00154 
00155         void clear()
00156         {
00157             if (mDelegate)
00158             {
00159                 delete mDelegate;
00160                 mDelegate = nullptr;
00161             }
00162         }
00163 
00164         MYGUI_C_DELEGATE  MYGUI_TEMPLATE_ARGS & operator=(IDelegate* _delegate)
00165         {
00166             if (mDelegate)
00167             {
00168                 delete mDelegate;
00169             }
00170             mDelegate = _delegate;
00171             return *this;
00172         }
00173 
00174         MYGUI_C_DELEGATE  MYGUI_TEMPLATE_ARGS & operator=(const MYGUI_C_DELEGATE  MYGUI_TEMPLATE_ARGS& _event)
00175         {
00176             // забираем себе владение
00177             if (mDelegate != nullptr) delete mDelegate;
00178             mDelegate = _event.mDelegate;
00179             const_cast< MYGUI_C_DELEGATE  MYGUI_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
00180 
00181             return *this;
00182         }
00183 
00184         void operator()( MYGUI_PARAMS )
00185         {
00186             if (mDelegate == nullptr) return;
00187             mDelegate->invoke( MYGUI_ARGS );
00188         }
00189 
00190     private:
00191         IDelegate * mDelegate;
00192     };
00193 
00194 
00195     // шаблон класса мульти делегата
00196     MYGUI_TEMPLATE   MYGUI_TEMPLATE_PARAMS
00197     class MYGUI_C_MULTI_DELEGATE
00198     {
00199     public:
00200         typedef  MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS  IDelegate;
00201         typedef MYGUI_TYPENAME std::list<IDelegate* /*, Allocator<IDelegate*>*/ > ListDelegate;
00202         typedef MYGUI_TYPENAME ListDelegate::iterator ListDelegateIterator;
00203 
00204         MYGUI_C_MULTI_DELEGATE () { }
00205         ~MYGUI_C_MULTI_DELEGATE () { clear(); }
00206 
00207         bool empty()
00208         {
00209           for (ListDelegateIterator 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         MYGUI_C_MULTI_DELEGATE (const MYGUI_C_MULTI_DELEGATE  MYGUI_TEMPLATE_ARGS & _event) { }
00288         MYGUI_C_MULTI_DELEGATE  MYGUI_TEMPLATE_ARGS & operator=(const MYGUI_C_MULTI_DELEGATE  MYGUI_TEMPLATE_ARGS & _event)
00289         {
00290             return *this;
00291         }
00292 
00293 
00294     private:
00295         ListDelegate mListDelegates;
00296 
00297     };
00298 
00299 
00300     #undef MYGUI_COMBINE
00301     #undef MYGUI_COMBINE1
00302 
00303     #undef MYGUI_I_DELEGATE
00304 
00305     #undef MYGUI_C_STATIC_DELEGATE
00306     #undef MYGUI_C_METHOD_DELEGATE
00307 
00308     #undef MYGUI_C_DELEGATE
00309     #undef MYGUI_C_MULTI_DELEGATE
00310 
00311     #undef MYGUI_SUFFIX
00312     #undef MYGUI_TEMPLATE
00313     #undef MYGUI_TEMPLATE_PARAMS
00314     #undef MYGUI_TEMPLATE_ARGS
00315     #undef MYGUI_T_TEMPLATE_PARAMS
00316     #undef MYGUI_T_TEMPLATE_ARGS
00317     #undef MYGUI_PARAMS
00318     #undef MYGUI_ARGS
00319     #undef MYGUI_TYPENAME
00320 
00321 } // namespace delegates

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1