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  // базовый класс всех делегатов
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  // делегат для статической функции
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;
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  // делегат для метода класса
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;
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);
118 {
120 }
121 
122 
123 // шаблон для создания делегата метода класса
124 // параметры : указатель на объект класса и указатель на метод класса
125 // пример : newDelegate(&object_name, &class_name::method_name);
128 {
130 }
131 
132 namespace delegates
133 {
134  // шаблон класса делегата
137  {
138  public:
140 
141  MYGUI_C_DELEGATE () : mDelegate(nullptr) { }
143  {
144  // take ownership
145  mDelegate = _event.mDelegate;
146  const_cast< MYGUI_C_DELEGATE MYGUI_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
147  }
148 
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 
166  {
167  delete mDelegate;
168  mDelegate = _delegate;
169  return *this;
170  }
171 
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 
190  {
191  if (mDelegate == nullptr) return;
192  mDelegate->invoke(MYGUI_ARGS);
193  }
194 
195  private:
196  IDelegate* mDelegate;
197  };
198 
199 
200  // шаблон класса мульти делегата
203  {
204  public:
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 
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 
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 
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 
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 
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 
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 += ")
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
#define MYGUI_T_TEMPLATE_ARGS
#define MYGUI_C_MULTI_DELEGATE
CMultiDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator-=(IDelegate *_delegate)
virtual bool compare(IDelegateUnlink *_unlink) const
#define MYGUI_PARAMS
MYGUI_TYPENAME ListDelegate::iterator ListDelegateIterator
IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS IDelegate
#define MYGUI_C_METHOD_DELEGATE
IDelegateUnlink * GetDelegateUnlink(void *_base)
CMultiDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator=(const CMultiDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS &_event)
MYGUI_TYPENAME ListDelegate::const_iterator ConstListDelegateIterator
#define nullptr
virtual bool compare(IDelegateUnlink *_unlink) const
#define MYGUI_TEMPLATE
#define MYGUI_I_DELEGATE
virtual bool compare(IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS *_delegate) const
CDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator=(IDelegate *_delegate)
#define MYGUI_EXCEPT(dest)
virtual bool isType(const std::type_info &_type)
#define MYGUI_TYPENAME
#define MYGUI_T_TEMPLATE_PARAMS
IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS IDelegate
#define MYGUI_TEMPLATE_PARAMS
#define MYGUI_TEMPLATE_ARGS
MYGUI_TEMPLATE MYGUI_TEMPLATE_PARAMS delegates::IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS * newDelegate(void(*_func)(MYGUI_PARAMS))
#define MYGUI_C_STATIC_DELEGATE
virtual bool compare(IDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS *_delegate) const
CDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator=(const CDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS &_event)
#define MYGUI_ARGS
#define MYGUI_C_DELEGATE
virtual bool isType(const std::type_info &_type)
CMultiDelegateMYGUI_SUFFIX MYGUI_TEMPLATE_ARGS & operator+=(IDelegate *_delegate)
virtual bool compare(IDelegateUnlink *_unlink) const
MYGUI_TYPENAME std::list< IDelegate *> ListDelegate
#define MYGUI_OBSOLETE(text)