YSTest: yevt.hpp 源文件

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
36 YSL_BEGIN
37
42 template<typename... _tParams>
43 DeclI(, GIHEvent)
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
68 EventArgsType;
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
188 typedef u8 EventPriority;
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;
213 typedef typename HandlerType::EventArgsType EventArgsType;
214 typedef typename HandlerType::FuncType FuncType;
219 typedef multimap<EventPriority, HandlerType, std::greater<EventPriority>>
220 ContainerType;
221 typedef typename ContainerType::size_type SizeType;
222
227 ContainerType List;
228
233 yconstfn DefDeCtor(GEvent)
238 yconstfn DefDeCopyCtor(GEvent)
242 yconstfn DefDeMoveCtor(GEvent)
243
244 private:
249 template<typename _tHandler>
250 GEvent(_tHandler&& h)
251 : List()
252 {
253 Add(yforward(h));
254 }
255
256 public:
260 DefDeCopyAssignment(GEvent)
264 DefDeMoveAssignment(GEvent)
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:
514 typedef typename GDependency<_tEvent>::DependentType DependentType;
515 typedef typename GDependency<_tEvent>::PointerType PointerType;
516 typedef typename GDependency<_tEvent>::ConstReferenceType
517 ConstReferenceType;
518 typedef typename GDependency<_tEvent>::ReferentType ReferentType;
519 typedef typename GDependency<_tEvent>::ReferenceType ReferenceType;
520 typedef DependentType EventType;
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
527 GDependencyEvent(PointerType p = PointerType())
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
681 inline ImplI(GIHEvent<_tBaseArgs>)
682 DefClone(const override, GEventWrapper, Clone)
683 };
684
685
691 template<typename _tBaseArgs>
692 class GEventPointerWrapper
693 {
694 public:
695 typedef GIHEvent<_tBaseArgs> ItemType;
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