Created
January 8, 2014 08:19
-
-
Save heroboy/8313489 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <functional> | |
| template<typename FuncT> class Event; | |
| template<typename FuncT> | |
| class _EventBase | |
| { | |
| protected: | |
| std::vector<std::function<FuncT>* > funcs; | |
| public: | |
| _EventBase() | |
| { | |
| } | |
| ~_EventBase() | |
| { | |
| for(auto it=funcs.begin();it!=funcs.end();++it) | |
| { | |
| if (*it != nullptr) | |
| delete *it; | |
| } | |
| } | |
| template<typename T> | |
| void * Advise(T&& f) | |
| { | |
| std::function<FuncT> * p = new std::function<FuncT>(std::forward<T>(f)); | |
| funcs.push_back(p); | |
| return (void*)p; | |
| } | |
| void Unadvise(void * p) | |
| { | |
| if (p == NULL) return; | |
| bool bHasDelete = false;; | |
| for(auto it=funcs.begin();it!=funcs.end();++it) | |
| { | |
| if (*it == (std::function<FuncT>*)p) | |
| { | |
| bHasDelete = true; | |
| delete *it; | |
| *it = NULL; | |
| } | |
| } | |
| ATLASSERT(bHasDelete); | |
| } | |
| //C# like operator | |
| template<typename T> | |
| void * operator+=(T&& f) | |
| { | |
| return Advise(std::forward<T>(f)); | |
| } | |
| void operator-=(void *p) | |
| { | |
| Unadvise(p); | |
| } | |
| }; | |
| #define IMPLEMENT_OPERATOR \ | |
| void operator()(ARG_LIST1){\ | |
| bool bHasNull = false;\ | |
| size_t count = funcs.size();\ | |
| for(size_t i=0;i<count;++i)\ | |
| {\ | |
| if (funcs[i])\ | |
| {\ | |
| (*funcs[i])(ARG_LIST2);\ | |
| }\ | |
| else\ | |
| {\ | |
| bHasNull = true;\ | |
| }\ | |
| }\ | |
| if (bHasNull)\ | |
| {\ | |
| auto newEnd = std::remove(funcs.begin(),funcs.end(),nullptr);\ | |
| funcs.erase(newEnd,funcs.end());\ | |
| }\ | |
| } | |
| class Event0:public _EventBase<void()> | |
| { | |
| public: | |
| #define ARG_LIST1 | |
| #define ARG_LIST2 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename Arg0> | |
| class Event1:public _EventBase<void(Arg0)> | |
| { | |
| public: | |
| #define ARG_LIST1 Arg0 a0 | |
| #define ARG_LIST2 a0 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename Arg0,typename Arg1> | |
| class Event2:public _EventBase<void(Arg0,Arg1)> | |
| { | |
| public: | |
| #define ARG_LIST1 Arg0 a0,Arg1 a1 | |
| #define ARG_LIST2 a0,a1 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename Arg0,typename Arg1,typename Arg2> | |
| class Event3:public _EventBase<void(Arg0,Arg1,Arg2)> | |
| { | |
| public: | |
| #define ARG_LIST1 Arg0 a0,Arg1 a1,Arg2 a2 | |
| #define ARG_LIST2 a0,a1,a2 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3> | |
| class Event4:public _EventBase<void(Arg0,Arg1,Arg2,Arg3)> | |
| { | |
| public: | |
| #define ARG_LIST1 Arg0 a0,Arg1 a1,Arg2 a2,Arg3 a3 | |
| #define ARG_LIST2 a0,a1,a2,a3 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3,typename Arg4> | |
| class Event5:public _EventBase<void(Arg0,Arg1,Arg2,Arg3,Arg4)> | |
| { | |
| public: | |
| #define ARG_LIST1 Arg0 a0,Arg1 a1,Arg2 a2,Arg3 a3,Arg4 a4 | |
| #define ARG_LIST2 a0,a1,a2,a3,a4 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5> | |
| class Event6:public _EventBase<void(Arg0,Arg1,Arg2,Arg3,Arg4,Arg5)> | |
| { | |
| public: | |
| #define ARG_LIST1 Arg0 a0,Arg1 a1,Arg2 a2,Arg3 a3,Arg4 a4,Arg5 a5 | |
| #define ARG_LIST2 a0,a1,a2,a3,a4,a5 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5,typename Arg6> | |
| class Event7:public _EventBase<void(Arg0,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6)> | |
| { | |
| public: | |
| #define ARG_LIST1 Arg0 a0,Arg1 a1,Arg2 a2,Arg3 a3,Arg4 a4,Arg5 a5,Arg6 a6 | |
| #define ARG_LIST2 a0,a1,a2,a3,a4,a5,a6 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5,typename Arg6,typename Arg7> | |
| class Event8:public _EventBase<void(Arg0,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7)> | |
| { | |
| public: | |
| #define ARG_LIST1 Arg0 a0,Arg1 a1,Arg2 a2,Arg3 a3,Arg4 a4,Arg5 a5,Arg6 a6,Arg7 a7 | |
| #define ARG_LIST2 a0,a1,a2,a3,a4,a5,a6,a7 | |
| IMPLEMENT_OPERATOR | |
| #undef ARG_LIST1 | |
| #undef ARG_LIST2 | |
| }; | |
| template<typename T> | |
| class Event; | |
| template<> | |
| class Event<void()>:public Event0{}; | |
| template<typename Arg0> | |
| class Event<void(Arg0)>:public Event1<Arg0>{}; | |
| template<typename Arg0,typename Arg1> | |
| class Event<void(Arg0,Arg1)>:public Event2<Arg0,Arg1>{}; | |
| template<typename Arg0,typename Arg1,typename Arg2> | |
| class Event<void(Arg0,Arg1,Arg2)>:public Event3<Arg0,Arg1,Arg2>{}; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3> | |
| class Event<void(Arg0,Arg1,Arg2,Arg3)>:public Event4<Arg0,Arg1,Arg2,Arg3>{}; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3,typename Arg4> | |
| class Event<void(Arg0,Arg1,Arg2,Arg3,Arg4)>:public Event5<Arg0,Arg1,Arg2,Arg3,Arg4>{}; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5> | |
| class Event<void(Arg0,Arg1,Arg2,Arg3,Arg4,Arg5)>:public Event6<Arg0,Arg1,Arg2,Arg3,Arg4,Arg5>{}; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5,typename Arg6> | |
| class Event<void(Arg0,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6)>:public Event7<Arg0,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6>{}; | |
| template<typename Arg0,typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5,typename Arg6,typename Arg7> | |
| class Event<void(Arg0,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7)>:public Event8<Arg0,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7>{}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment