YSTest  PreAlpha_b400_20130424
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
yevt.hpp
浏览该文件的文档.
1 /*
2  Copyright by FrankHB 2010 - 2013.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #ifndef YSL_INC_Core_yevt_hpp_
29 #define YSL_INC_Core_yevt_hpp_ 1
30 
31 #include "yobject.h"
32 #include "yfunc.hpp"
33 #include <ystdex/iterator.hpp> // for ystdex::get_value;
34 #include <ystdex/container.hpp> // for ystdex::erase_all_if;
35 
37 
42 template<typename... _tParams>
44  DeclIEntry(size_t operator()(_tParams...) const)
45  DeclIEntry(GIHEvent* Clone() const)
46 EndDecl
47 
48 
56 template<typename>
57 class GHEvent;
58 
60 template<typename _tRet, typename... _tParams>
61 class GHEvent<_tRet(_tParams...)>
62  : protected std::function<void(_tParams...)>
63 {
64 public:
65  typedef tuple<_tParams...> TupleType;
66  typedef typename std::conditional<std::tuple_size<TupleType>::value == 0,
67  void, typename std::tuple_element<0, TupleType>::type>::type
69  typedef void FuncType(_tParams...);
70  typedef std::function<FuncType> BaseType;
71 
72 private:
73  typedef bool(*Comparer)(const GHEvent&, const GHEvent&);
74  template<class _tFunctor>
75  struct GEquality
76  {
78 
79  typedef typename std::decay<_tFunctor>::type decayed_type;
80 
81 #if YB_HAS_NOEXCEPT
82  static yconstexpr bool except_helper = noexcept(std::declval<
83  const decayed_type>() == std::declval<const decayed_type>());
84 #endif
85 
86  static bool
87  AreEqual(const GHEvent& x, const GHEvent& y)
88 #if YB_HAS_NOEXCEPT
89  // NOTE: Use helper to prevent constexpr checking fail.
90  ynoexcept(except_helper)
91 #endif
92  {
93  if(const auto p = x.template target<decayed_type>())
94  if(const auto q = y.template target<decayed_type>())
95  return p == q || *p == *q;
96  return false;
97  }
99  };
100 
101  Comparer comp_eq;
102 
103 public:
108  yconstfn
109  GHEvent(FuncType* f)
110  : BaseType(f), comp_eq(GEquality<FuncType>::AreEqual)
111  {}
116  template<class _fCallable>
117  yconstfn
118  GHEvent(_fCallable&& f, typename std::enable_if<std::is_constructible<
119  BaseType, _fCallable>::value, int>::type = 0)
120  : BaseType(yforward(f)), comp_eq(GetComparer(f, f))
121  {}
125  template<class _type>
126  yconstfn
127  GHEvent(_type& obj, void(_type::*pm)(_tParams...))
128  : BaseType(ExpandMemberFirstBinder<_type, void, _tParams...>(obj,
129  pm)), comp_eq(GEquality<ExpandMemberFirstBinder<_type, void,
130  _tParams...>>::AreEqual)
131  {}
132  yconstfn DefDeCopyCtor(GHEvent)
133  yconstfn DefDeMoveCtor(GHEvent)
134 
135  DefDeCopyAssignment(GHEvent)
139  DefDeMoveAssignment(GHEvent)
140 
141  yconstfn bool
142  operator==(const GHEvent& h) const
143  {
144  return
145 #if defined(YF_DLL) || defined(YF_BUILD_DLL)
146  BaseType::target_type() == h.BaseType::target_type()
147 #else
148  comp_eq == h.comp_eq
149 #endif
150  && (comp_eq(*this, h));
151  }
152 
156  using BaseType::operator();
157 
158 private:
160 
161  template<typename _type>
162  static yconstfn Comparer
163  GetComparer(_type& x, _type& y, decltype(x == y) = false) ynothrow
164  {
165  return GEquality<_type>::AreEqual;
166  }
167  template<typename _type, typename _tUnused>
168  static yconstfn Comparer
169  GetComparer(_type&, _tUnused&) ynothrow
170  {
171  return GHEvent::AreAlwaysEqual;
172  }
173 
174  static yconstfn bool
175  AreAlwaysEqual(const GHEvent&, const GHEvent&) ynothrow
176  {
177  return true;
178  }
180 };
182 
183 
189 
190 
195 yconstexpr EventPriority DefaultEventPriority(0x80);
196 
197 
204 template<typename>
205 class GEvent;
206 
208 template<typename _tRet, typename... _tParams>
209 class GEvent<_tRet(_tParams...)>
210 {
211 public:
212  typedef GHEvent<_tRet(_tParams...)> HandlerType;
214  typedef typename HandlerType::FuncType FuncType;
219  typedef multimap<EventPriority, HandlerType, std::greater<EventPriority>>
221  typedef typename ContainerType::size_type SizeType;
222 
228 
243 
244 private:
249  template<typename _tHandler>
250  GEvent(_tHandler&& h)
251  : List()
252  {
253  Add(yforward(h));
254  }
255 
256 public:
269  template<typename _type>
270  inline GEvent&
271  operator=(_type&& _arg)
272  {
273  return *this = HandlerType(yforward(_arg));
274  }
275 
280  inline GEvent&
281  operator+=(const HandlerType& h)
282  {
283  return Add(h);
284  }
289  inline GEvent&
290  operator+=(HandlerType&& h)
291  {
292  return Add(std::move(h));
293  }
298  template<typename _type>
299  inline GEvent&
300  operator+=(_type&& _arg)
301  {
302  return Add(HandlerType(yforward(_arg)));
303  }
304 
308  GEvent&
309  operator-=(const HandlerType& h)
310  {
311  ystdex::erase_all_if<ContainerType>(List, List.begin(), List.end(),
312  [&](decltype(*List.begin())& pr){
313  return pr.second == h;
314  });
315  return *this;
316  }
321  inline GEvent&
322  operator-=(HandlerType&& h)
323  {
324  return *this -= static_cast<const HandlerType&>(h);
325  }
330  template<typename _type>
331  inline GEvent&
332  operator-=(_type&& _arg)
333  {
334  return *this -= HandlerType(yforward(_arg));
335  }
336 
342  inline GEvent&
343  Add(const HandlerType& h, EventPriority prior = DefaultEventPriority)
344  {
345  List.insert(make_pair(prior, h));
346  return *this;
347  }
353  inline GEvent&
354  Add(HandlerType&& h, EventPriority prior = DefaultEventPriority)
355  {
356  List.insert(make_pair(prior, std::move(h)));
357  return *this;
358  }
364  template<typename _type>
365  inline GEvent&
366  Add(_type&& _arg, EventPriority prior = DefaultEventPriority)
367  {
368  return Add(HandlerType(yforward(_arg)), prior);
369  }
375  template<class _tObj, class _type>
376  inline GEvent&
377  Add(_tObj& obj, void(_type::*pm)(EventArgsType),
378  EventPriority prior = DefaultEventPriority)
379  {
380  return Add(HandlerType(static_cast<_type&>(obj), std::move(pm)), prior);
381  }
382 
387  template<class _tObj, class _type>
388  inline GEvent&
389  Remove(_tObj& obj, void(_type::*pm)(EventArgsType))
390  {
391  return *this -= HandlerType(static_cast<_type&>(obj), std::move(pm));
392  }
393 
397  bool
398  Contains(const HandlerType& h) const
399  {
400  using ystdex::get_value;
401 
402  return std::find(List.cbegin() | get_value, List.cend() | get_value, h)
403  != List.cend();
404  }
409  template<typename _type>
410  inline bool
411  Contains(_type&& _arg) const
412  {
413  return Contains(HandlerType(yforward(_arg)));
414  }
415 
421  SizeType
422  operator()(_tParams... args) const
423  {
424  SizeType n(0);
425 
426  for(const auto& pr : List)
427  {
428  try
429  {
430  pr.second(yforward(args)...);
431  }
432  catch(std::bad_function_call&)
433  {}
434  ++n;
435  }
436  return n;
437  }
438 
442  inline DefGetter(const ynothrow, SizeType, Size, List.size())
443 
447  inline PDefH(void, Clear, )
448  ImplRet(List.clear())
449 
450  /*
451  \brief 交换。
452  */
453  inline PDefH(void, Swap, GEvent& e) ynothrow
454  ImplRet(List.swap(e))
455 };
457 
463 template<typename _tRet, typename... _tParams>
464 inline GEvent<_tRet(_tParams...)>&
465 AddUnique(GEvent<_tRet(_tParams...)>& evt,
466  const typename GEvent<_tRet(_tParams...)>::HandlerType& h,
467  EventPriority prior = DefaultEventPriority)
468 {
469  return (evt -= h).Add(h, prior);
470 }
471 template<typename _tRet, typename... _tParams>
472 inline GEvent<_tRet(_tParams...)>&
473 AddUnique(GEvent<_tRet(_tParams...)>& evt, typename GEvent<_tRet(_tParams...)>
474  ::HandlerType&& h, EventPriority prior = DefaultEventPriority)
475 {
476  return (evt -= h).Add(std::move(h), prior);
477 }
478 template<typename _type, typename _tRet, typename... _tParams>
479 inline GEvent<_tRet(_tParams...)>&
480 AddUnique(GEvent<_tRet(_tParams...)>& evt, _type&& arg,
481  EventPriority prior = DefaultEventPriority)
482 {
483  return AddUnique(evt, HandlerType(yforward(arg)), prior);
484 }
485 template<class _type, typename _tRet, typename... _tParams>
486 inline GEvent<_tRet(_tParams...)>&
487 AddUnique(GEvent<_tRet(_tParams...)>& evt, _type& obj,
488  void(_type::*pm)(typename GEvent<_tRet(_tParams...)>::EventArgsType),
489  EventPriority prior = DefaultEventPriority)
490 {
491  return AddUnique(evt, HandlerType(static_cast<_type&>(obj), std::move(pm)),
492  prior);
493 }
495 
496 
501 #define DeclDelegate(_name, _tEventArgs) \
502  typedef GHEvent<void(_tEventArgs)> _name;
503 
504 
510 template<class _tEvent, class _tOwnerPointer = shared_ptr<_tEvent>>
511 class GDependencyEvent : public GDependency<_tEvent, _tOwnerPointer>
512 {
513 public:
521  typedef typename EventType::EventArgsType EventArgsType;
522  typedef typename EventType::SEventType SEventType;
523  typedef typename EventType::FuncType FuncType;
524  typedef typename EventType::HandlerType HandlerType;
525  typedef typename EventType::SizeType SizeType;
526 
528  : GDependency<_tEvent>(p)
529  {}
530 
534  template<typename _type>
535  inline ReferenceType
536  operator+=(_type _arg)
537  {
538  return this->GetNewRef().operator+=(_arg);
539  }
540 
544  template<typename _type>
545  inline ReferenceType
546  operator-=(_type _arg)
547  {
548  return this->GetNewRef().operator-=(_arg);
549  }
550 
554  template<class _type>
555  inline ReferenceType
556  Add(_type& obj, void(_type::*pm)(EventArgsType))
557  {
558  return this->GetNewRef().Add(obj, pm);
559  }
560 
564  template<class _type>
565  inline ReferenceType
566  Remove(_type& obj, void(_type::*pm)(EventArgsType))
567  {
568  return this->GetNewRef().Remove(obj, pm);
569  }
570 
574  inline SizeType
575  operator()(EventArgsType&& e) const
576  {
577  return this->GetRef().operator()(std::move(e));
578  }
579 
583  inline DefGetterMem(const ynothrow, SizeType, Size, this->GetRef())
584 
585 
588  inline PDefH(void, Clear, )
589  ImplBodyMem(this->GetNewRef(), Clear, )
590 };
591 
592 
598 #define EventT(_tEventHandler) GEvent<void(_tEventHandler::EventArgsType)>
599 #define DepEventT(_tEventHandler) \
600  typename GDependencyEvent(EventT(_tEventHandler))
601 
602 
608 #define DeclEvent(_tEventHandler, _name) \
609  EventT(_tEventHandler) _name;
610 #define DeclDepEvent(_tEventHandler, _name) \
611  DepEventT(_tEventHandler) _name;
612 
613 
619 #define DeclEventRef(_tEventHandler, _name) \
620  EventT(_tEventHandler)& _name;
621 #define DeclDepEventRef(_tEventHandler, _name) \
622  DepEventT(_tEventHandler)& _name;
623 
624 
629 
630 #define DeclIEventEntry(_tEventHandler, _name) \
631  DeclIEntry(const EventT(_tEventHandler)& yJOIN(Get, _name)() const)
632 
633 #define DeclIDepEventEntry(_tEventHandler, _name) \
634  DeclIEntry(const DepEventT(_tEventHandler)& yJOIN(Get, _name)() const)
635 
636 
642 #define DefEventGetter(_q, _tEventHandler, _name, _member) \
643  DefGetter(_q, EventT(_tEventHandler)&, _name, _member)
644 #define DefEventGetterBase(_q, _tEventHandler, _name, _base) \
645  DefGetterBase(_q, EventT(_tEventHandler)&, _name, _base)
646 #define DefEventGetterMem(_q, _tEventHandler, _name, _member) \
647  DefGetterMem(_q, EventT(_tEventHandler)&, _name, _member)
648 #define DefDepEventGetter(_q, _tEventHandler, _name, _member) \
649  DefGetter(_q, DepEventT(_tEventHandler)&, _name, _member)
650 #define DefDepEventGetterBase(_q, _tEventHandler, _name, _base) \
651  DefGetterBase(_q, DepEventT(_tEventHandler)&, _name, _base)
652 #define DefDepEventGetterMem(_q, _tEventHandler, _name, _member) \
653  DefGetterMem(_q, DepEventT(_tEventHandler)&, _name, _member)
654 
655 
656 
661 template<class _tEvent, typename _tBaseArgs>
662 class GEventWrapper : public _tEvent,
663  implements GIHEvent<_tBaseArgs>
664 {
665 public:
666  typedef _tEvent EventType;
667  typedef _tBaseArgs BaseArgsType;
668  typedef typename EventType::EventArgsType EventArgsType;
669 
675  inline ImplI(GIHEvent<_tBaseArgs>) size_t
676  operator()(BaseArgsType e) const
677  {
678  return EventType::operator()(EventArgsType(yforward(e)));
679  }
680 
682  DefClone(const override, GEventWrapper, Clone)
683 };
684 
685 
691 template<typename _tBaseArgs>
693 {
694 public:
696  typedef unique_ptr<ItemType> PointerType;
697 
698 private:
699 #if YB_HAS_NOEXCEPT
700  template<typename _type>
701  struct except_helper_t
702  {
703  static yconstexpr bool value
704  = noexcept(PointerType(std::declval<_type>()));
705  };
706 #endif
707 
708  PointerType ptr;
709 
710 public:
712  template<typename _type>
713  inline
714  GEventPointerWrapper(_type&& p)
715 #if YB_HAS_NOEXCEPT
716  // NOTE: Use helper to prevent constexpr checking fail.
717  ynoexcept(except_helper_t<_type>::value)
718 #endif
719  : ptr(yforward(p))
720  {
721  YAssert(bool(p), "Null pointer found.");
722  }
726  GEventPointerWrapper(const GEventPointerWrapper& item)
727  : ptr(ClonePolymorphic(item.ptr))
728  {}
729  DefDeMoveCtor(GEventPointerWrapper)
730 
731  yconstfn DefCvt(const ynothrow, const ItemType&, *ptr)
732  yconstfn DefCvt(ynothrow, ItemType&, *ptr)
733 };
734 
735 
740 #define DefExtendEventMap(_n, _b) \
741  DefExtendClass(YF_API, _n, public _b)
742 
743 YSL_END
744 
745 #endif
746