MyGUI 3.2.0

- Main Page
- Related Pages
- Namespaces
- Data Structures
- Files
- Examples

- File List
- Globals

MyGUI_DelegateImplement.h
Go to the documentation of this file.
1
6 /*
7 This file is part of MyGUI.
8
9 MyGUI is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 MyGUI is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 namespace delegates
24 {
25
26 #define MYGUI_COMBINE(a, b) MYGUI_COMBINE1(a, b)
27 #define MYGUI_COMBINE1(a, b) a##b
28
29 #define MYGUI_I_DELEGATE MYGUI_COMBINE(IDelegate, MYGUI_SUFFIX)
30
31 #define MYGUI_C_STATIC_DELEGATE MYGUI_COMBINE(CStaticDelegate, MYGUI_SUFFIX)
32 #define MYGUI_C_METHOD_DELEGATE MYGUI_COMBINE(CMethodDelegate, MYGUI_SUFFIX)
33
34 #define MYGUI_C_DELEGATE MYGUI_COMBINE(CDelegate, MYGUI_SUFFIX)
35 #define MYGUI_C_MULTI_DELEGATE MYGUI_COMBINE(CMultiDelegate, MYGUI_SUFFIX)
36
37
38 // базовый класс всех делегатов
39 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
40 class MYGUI_I_DELEGATE
41 {
42 public:
43 virtual ~MYGUI_I_DELEGATE() { }
44 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
45 virtual bool isType( const std::type_info& _type) = 0;
46 #endif
47 virtual void invoke( MYGUI_PARAMS ) = 0;
48 virtual bool compare( MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS* _delegate) const = 0;
49 virtual bool compare(IDelegateUnlink* _unlink) const
50 {
51 return false;
52 }
53 };
54
55
56 // делегат для статической функции
57 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
58 class MYGUI_C_STATIC_DELEGATE : public MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS
59 {
60 public:
61 typedef void (*Func)( MYGUI_PARAMS );
62
63 MYGUI_C_STATIC_DELEGATE (Func _func) : mFunc(_func) { }
64
65 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
66 virtual bool isType( const std::type_info& _type)
67 {
68 return typeid( MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS ) == _type;
69 }
70 #endif
71
72 virtual void invoke( MYGUI_PARAMS )
73 {
74 mFunc( MYGUI_ARGS );
75 }
76
77 virtual bool compare( MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS* _delegate) const
78 {
79 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
80 if (nullptr == _delegate || !_delegate->isType(typeid(MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS)) ) return false;
81 MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS* cast = static_cast<MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS*>(_delegate);
82 #else
83 MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS* cast = dynamic_cast<MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS*>(_delegate);
84 if (nullptr == cast) return false;
85 #endif
86 return cast->mFunc == mFunc;
87 }
88 virtual bool compare(IDelegateUnlink* _unlink) const
89 {
90 return false;
91 }
92
93 private:
94 Func mFunc;
95 };
96
97
98 // делегат для метода класса
99 template MYGUI_T_TEMPLATE_PARAMS
100 class MYGUI_C_METHOD_DELEGATE : public MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS
101 {
102 public:
103 typedef void (T::*Method)( MYGUI_PARAMS );
104
105 MYGUI_C_METHOD_DELEGATE(IDelegateUnlink* _unlink, T* _object, Method _method) : mUnlink(_unlink), mObject(_object), mMethod(_method) { }
106
107 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
108 virtual bool isType( const std::type_info& _type)
109 {
110 return typeid( MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS ) == _type;
111 }
112 #endif
113
114 virtual void invoke( MYGUI_PARAMS )
115 {
116 (mObject->*mMethod)( MYGUI_ARGS );
117 }
118
119 virtual bool compare( MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS* _delegate) const
120 {
121 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
122 if (nullptr == _delegate || !_delegate->isType(typeid(MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS)) ) return false;
123 MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS* cast = static_cast< MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS* >(_delegate);
124 #else
125 MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS* cast = dynamic_cast< MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS* >(_delegate);
126 if (nullptr == cast) return false;
127 #endif
128 return cast->mObject == mObject && cast->mMethod == mMethod;
129 }
130
131 virtual bool compare(IDelegateUnlink* _unlink) const
132 {
133 return mUnlink == _unlink;
134 }
135
136 private:
137 IDelegateUnlink* mUnlink;
138 T* mObject;
139 Method mMethod;
140 };
141
142 } // namespace delegates
143
144 // шаблон для создания делегата статической функции
145 // параметры : указатель на функцию
146 // пример : newDelegate(funk_name);
147 // пример : newDelegate(class_name::static_method_name);
148 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
149 inline delegates::MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS* newDelegate( void (*_func)( MYGUI_PARAMS ) )
150 {
151 return new delegates::MYGUI_C_STATIC_DELEGATE MYGUI_TEMPLATE_ARGS (_func);
152 }
153
154
155 // шаблон для создания делегата метода класса
156 // параметры : указатель на объект класса и указатель на метод класса
157 // пример : newDelegate(&object_name, &class_name::method_name);
158 template MYGUI_T_TEMPLATE_PARAMS
159 inline delegates::MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS* newDelegate( T* _object, void (T::*_method)( MYGUI_PARAMS ) )
160 {
161 return new delegates::MYGUI_C_METHOD_DELEGATE MYGUI_T_TEMPLATE_ARGS (delegates::GetDelegateUnlink(_object), _object, _method);
162 }
163
164 namespace delegates
165 {
166 // шаблон класса делегата
167 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
168 class MYGUI_C_DELEGATE
169 {
170 public:
171 typedef MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS IDelegate;
172
173 MYGUI_C_DELEGATE () : mDelegate(nullptr) { }
174 MYGUI_C_DELEGATE (const MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& _event) : mDelegate(nullptr)
175 {
176 // забираем себе владение
177 IDelegate* del = _event.mDelegate;
178 const_cast< MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
179
180 if (mDelegate != nullptr && !mDelegate->compare(del))
181 delete mDelegate;
182
183 mDelegate = del;
184 }
185 ~MYGUI_C_DELEGATE ()
186 {
187 clear();
188 }
189
190 bool empty() const
191 {
192 return mDelegate == nullptr;
193 }
194
195 void clear()
196 {
197 if (mDelegate)
198 {
199 delete mDelegate;
200 mDelegate = nullptr;
201 }
202 }
203
204 MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& operator=(IDelegate* _delegate)
205 {
206 delete mDelegate;
207 mDelegate = _delegate;
208 return *this;
209 }
210
211 MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& operator=(const MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& _event)
212 {
213 // забираем себе владение
214 IDelegate* del = _event.mDelegate;
215 const_cast< MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
216
217 if (mDelegate != nullptr && !mDelegate->compare(del))
218 delete mDelegate;
219
220 mDelegate = del;
221
222 return *this;
223 }
224
225 void operator()( MYGUI_PARAMS )
226 {
227 if (mDelegate == nullptr) return;
228 mDelegate->invoke( MYGUI_ARGS );
229 }
230
231 private:
232 IDelegate* mDelegate;
233 };
234
235
236 // шаблон класса мульти делегата
237 MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS
238 class MYGUI_C_MULTI_DELEGATE
239 {
240 public:
241 typedef MYGUI_I_DELEGATE MYGUI_TEMPLATE_ARGS IDelegate;
242 typedef MYGUI_TYPENAME std::list<IDelegate* /*, Allocator<IDelegate*>*/ > ListDelegate;
243 typedef MYGUI_TYPENAME ListDelegate::iterator ListDelegateIterator;
244 typedef MYGUI_TYPENAME ListDelegate::const_iterator ConstListDelegateIterator;
245
246 MYGUI_C_MULTI_DELEGATE () { }
247 ~MYGUI_C_MULTI_DELEGATE ()
248 {
249 clear();
250 }
251
252 bool empty() const
253 {
254 for (ConstListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
255 {
256 if (*iter) return false;
257 }
258 return true;
259 }
260
261 void clear()
262 {
263 for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
264 {
265 if (*iter)
266 {
267 delete (*iter);
268 (*iter) = nullptr;
269 }
270 }
271 }
272
273 void clear(IDelegateUnlink* _unlink)
274 {
275 for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
276 {
277 if ((*iter) && (*iter)->compare(_unlink))
278 {
279 delete (*iter);
280 (*iter) = nullptr;
281 }
282 }
283 }
284
285 MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS& operator+=(IDelegate* _delegate)
286 {
287 for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
288 {
289 if ((*iter) && (*iter)->compare(_delegate))
290 {
291 MYGUI_EXCEPT("Trying to add same delegate twice.");
292 }
293 }
294 mListDelegates.push_back(_delegate);
295 return *this;
296 }
297
298 MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS& operator-=(IDelegate* _delegate)
299 {
300 for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
301 {
302 if ((*iter) && (*iter)->compare(_delegate))
303 {
304 // проверяем на идентичность делегатов
305 if ((*iter) != _delegate) delete (*iter);
306 (*iter) = nullptr;
307 break;
308 }
309 }
310 delete _delegate;
311 return *this;
312 }
313
314 void operator()( MYGUI_PARAMS )
315 {
316 ListDelegateIterator iter = mListDelegates.begin();
317 while (iter != mListDelegates.end())
318 {
319 if (nullptr == (*iter))
320 {
321 iter = mListDelegates.erase(iter);
322 }
323 else
324 {
325 (*iter)->invoke( MYGUI_ARGS );
326 ++iter;
327 }
328 }
329 }
330
331 MYGUI_C_MULTI_DELEGATE (const MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS& _event)
332 {
333 // забираем себе владение
334 ListDelegate del = _event.mListDelegates;
335 const_cast< MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS& >(_event).mListDelegates.clear();
336
337 safe_clear(del);
338
339 mListDelegates = del;
340 }
341
342 MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS& operator=(const MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS& _event)
343 {
344 // забираем себе владение
345 ListDelegate del = _event.mListDelegates;
346 const_cast< MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS& >(_event).mListDelegates.clear();
347
348 safe_clear(del);
349
350 mListDelegates = del;
351
352 return *this;
353 }
354
355 MYGUI_OBSOLETE("use : operator += ")
356 MYGUI_C_MULTI_DELEGATE MYGUI_TEMPLATE_ARGS& operator=(IDelegate* _delegate)
357 {
358 clear();
359 *this += _delegate;
360 return *this;
361 }
362
363 private:
364 void safe_clear(ListDelegate& _delegates)
365 {
366 for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
367 {
368 if (*iter)
369 {
370 IDelegate* del = (*iter);
371 (*iter) = nullptr;
372 delete_is_not_found(del, _delegates);
373 }
374 }
375 }
376
377 void delete_is_not_found(IDelegate* _del, ListDelegate& _delegates)
378 {
379 for (ListDelegateIterator iter = _delegates.begin(); iter != _delegates.end(); ++iter)
380 {
381 if ((*iter) && (*iter)->compare(_del))
382 {
383 return;
384 }
385 }
386
387 delete _del;
388 }
389
390 private:
391 ListDelegate mListDelegates;
392 };
393
394
395 #undef MYGUI_COMBINE
396 #undef MYGUI_COMBINE1
397
398 #undef MYGUI_I_DELEGATE
399
400 #undef MYGUI_C_STATIC_DELEGATE
401 #undef MYGUI_C_METHOD_DELEGATE
402
403 #undef MYGUI_C_DELEGATE
404 #undef MYGUI_C_MULTI_DELEGATE
405
406 #undef MYGUI_SUFFIX
407 #undef MYGUI_TEMPLATE
408 #undef MYGUI_TEMPLATE_PARAMS
409 #undef MYGUI_TEMPLATE_ARGS
410 #undef MYGUI_T_TEMPLATE_PARAMS
411 #undef MYGUI_T_TEMPLATE_ARGS
412 #undef MYGUI_PARAMS
413 #undef MYGUI_ARGS
414 #undef MYGUI_TYPENAME
415
416 } // namespace delegates
MYGUI_T_TEMPLATE_ARGS
#define MYGUI_T_TEMPLATE_ARGS
Definition: MyGUI_Delegate.h:154
MYGUI_C_MULTI_DELEGATE
#define MYGUI_C_MULTI_DELEGATE
Definition: MyGUI_DelegateImplement.h:35
delegates::CMultiDelegateMYGUI_SUFFIX::operator-=
CMultiDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator-=(IDelegate *_delegate)
Definition: MyGUI_DelegateImplement.h:298
delegates::CMethodDelegateMYGUI_SUFFIX::invoke
virtual void invoke(MYGUI_PARAMS)
Definition: MyGUI_DelegateImplement.h:114
MYGUI_PARAMS
#define MYGUI_PARAMS
Definition: MyGUI_Delegate.h:155
delegates::CMultiDelegateMYGUI_SUFFIX::ListDelegateIterator
MYGUI_TYPENAME ListDelegate::iterator ListDelegateIterator
Definition: MyGUI_DelegateImplement.h:243
delegates::CMultiDelegateMYGUI_SUFFIX::IDelegate
IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS IDelegate
Definition: MyGUI_DelegateImplement.h:241
MyGUI::newDelegate
delegates::IDelegate0 * newDelegate(void(*_func)())
Definition: MyGUI_Delegate.h:150
MYGUI_C_METHOD_DELEGATE
#define MYGUI_C_METHOD_DELEGATE
Definition: MyGUI_DelegateImplement.h:32
MyGUI::delegates::GetDelegateUnlink
IDelegateUnlink * GetDelegateUnlink(void *_base)
Definition: MyGUI_Delegate.h:60
delegates::CMultiDelegateMYGUI_SUFFIX::operator=
CMultiDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator=(const CMultiDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS &_event)
Definition: MyGUI_DelegateImplement.h:342
delegates::CMultiDelegateMYGUI_SUFFIX::clear
void clear(IDelegateUnlink *_unlink)
Definition: MyGUI_DelegateImplement.h:273
delegates::CMethodDelegateMYGUI_SUFFIX::compare
virtual bool compare(IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS *_delegate) const
Definition: MyGUI_DelegateImplement.h:119
delegates::CMultiDelegateMYGUI_SUFFIX::operator()
void operator()(MYGUI_PARAMS)
Definition: MyGUI_DelegateImplement.h:314
delegates::CMultiDelegateMYGUI_SUFFIX::ConstListDelegateIterator
MYGUI_TYPENAME ListDelegate::const_iterator ConstListDelegateIterator
Definition: MyGUI_DelegateImplement.h:244
nullptr
#define nullptr
Definition: MyGUI_Prerequest.h:47
MYGUI_TEMPLATE
#define MYGUI_TEMPLATE
Definition: MyGUI_Delegate.h:150
MYGUI_I_DELEGATE
#define MYGUI_I_DELEGATE
Definition: MyGUI_DelegateImplement.h:29
delegates::CDelegateMYGUI_SUFFIX::operator()
void operator()(MYGUI_PARAMS)
Definition: MyGUI_DelegateImplement.h:225
delegates::CDelegateMYGUI_SUFFIX::operator=
CDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator=(IDelegate *_delegate)
Definition: MyGUI_DelegateImplement.h:204
delegates::IDelegateMYGUI_SUFFIX::compare
virtual bool compare(IDelegateUnlink *_unlink) const
Definition: MyGUI_DelegateImplement.h:49
MYGUI_EXCEPT
#define MYGUI_EXCEPT(dest)
Definition: MyGUI_Diagnostic.h:49
delegates::CMethodDelegateMYGUI_SUFFIX::isType
virtual bool isType(const std::type_info &_type)
Definition: MyGUI_DelegateImplement.h:108
MYGUI_TYPENAME
#define MYGUI_TYPENAME
Definition: MyGUI_Delegate.h:157
MYGUI_T_TEMPLATE_PARAMS
#define MYGUI_T_TEMPLATE_PARAMS
Definition: MyGUI_Delegate.h:153
delegates::CDelegateMYGUI_SUFFIX::IDelegate
IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS IDelegate
Definition: MyGUI_DelegateImplement.h:171
MYGUI_TEMPLATE_PARAMS
#define MYGUI_TEMPLATE_PARAMS
Definition: MyGUI_Delegate.h:151
delegates::CDelegateMYGUI_SUFFIX::empty
bool empty() const
Definition: MyGUI_DelegateImplement.h:190
MYGUI_TEMPLATE_ARGS
#define MYGUI_TEMPLATE_ARGS
Definition: MyGUI_Delegate.h:152
delegates::CMultiDelegateMYGUI_SUFFIX::empty
bool empty() const
Definition: MyGUI_DelegateImplement.h:252
MYGUI_C_STATIC_DELEGATE
#define MYGUI_C_STATIC_DELEGATE
Definition: MyGUI_DelegateImplement.h:31
delegates::CDelegateMYGUI_SUFFIX::operator=
CDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator=(const CDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS &_event)
Definition: MyGUI_DelegateImplement.h:211
delegates::CMethodDelegateMYGUI_SUFFIX::compare
virtual bool compare(IDelegateUnlink *_unlink) const
Definition: MyGUI_DelegateImplement.h:131
MYGUI_ARGS
#define MYGUI_ARGS
Definition: MyGUI_Delegate.h:156
delegates::CStaticDelegateMYGUI_SUFFIX::compare
virtual bool compare(IDelegateUnlink *_unlink) const
Definition: MyGUI_DelegateImplement.h:88
delegates::CMultiDelegateMYGUI_SUFFIX::clear
void clear()
Definition: MyGUI_DelegateImplement.h:261
MYGUI_C_DELEGATE
#define MYGUI_C_DELEGATE
Definition: MyGUI_DelegateImplement.h:34
delegates::CStaticDelegateMYGUI_SUFFIX::isType
virtual bool isType(const std::type_info &_type)
Definition: MyGUI_DelegateImplement.h:66
delegates::CDelegateMYGUI_SUFFIX::clear
void clear()
Definition: MyGUI_DelegateImplement.h:195
delegates::CMultiDelegateMYGUI_SUFFIX::operator+=
CMultiDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator+=(IDelegate *_delegate)
Definition: MyGUI_DelegateImplement.h:285
delegates::CStaticDelegateMYGUI_SUFFIX::invoke
virtual void invoke(MYGUI_PARAMS)
Definition: MyGUI_DelegateImplement.h:72
delegates::CMultiDelegateMYGUI_SUFFIX::ListDelegate
MYGUI_TYPENAME std::list< IDelegate * > ListDelegate
Definition: MyGUI_DelegateImplement.h:242
delegates::CStaticDelegateMYGUI_SUFFIX::compare
virtual bool compare(IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS *_delegate) const
Definition: MyGUI_DelegateImplement.h:77
MYGUI_OBSOLETE
#define MYGUI_OBSOLETE(text)
Definition: MyGUI_Diagnostic.h:111