MyGUI 3.2.2

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