Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <conio.h>
- #include <Windows.h>
- #include <vector>
- #include <string>
- #include <queue>
- #include <functional>
- #include <unordered_map>
- #include <typeinfo>
- // http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html
- // http://www.codeproject.com/Articles/384572/Implementation-of-Delegates-in-Cplusplus
- // http://geekswithblogs.net/raccoon_tim/archive/2011/09/28/lambdas-and-events-in-c.aspx
- // http://stackoverflow.com/questions/16868129/how-to-store-variadic-template-arguments
- // http://www.cplusplus.com/forum/general/63061/
- struct IBaseFunctor
- {
- virtual ~IBaseFunctor()
- {
- }
- virtual void Call() = 0;
- };
- template< typename TARGET, typename RESULT, typename... ARGS >
- struct CDerivedFunctorDelegate : IBaseFunctor
- {
- CDerivedFunctorDelegate(TARGET* ptr, RESULT(TARGET::*pmfn)(ARGS...), ARGS&&... data)
- : m_Func(std::bind(pmfn, ptr, std::forward<ARGS>(data)...))
- {
- }
- CDerivedFunctorDelegate(TARGET& ref, RESULT(TARGET::*pmfn)(ARGS...), ARGS&&... data)
- : m_Func(std::bind(pmfn, ref, std::forward<ARGS>(data)...))
- {
- }
- virtual void Call() override
- {
- m_Func();
- }
- private:
- std::function< void() > m_Func;
- };
- template<typename RESULT, typename... ARGS>
- struct CDerivedFunctor : IBaseFunctor
- {
- CDerivedFunctor(RESULT(*pmfn)(ARGS...), ARGS&&... data)
- : m_Func(std::bind(pmfn, std::forward<ARGS>(data)...))
- {
- }
- virtual void Call() override
- {
- m_Func();
- }
- private:
- std::function< void() > m_Func;
- };
- template< typename T, typename R, typename... ARGS > inline // helper to deduce the types
- CDerivedFunctorDelegate<T, R, ARGS...> *MakeFunctor(T* p, R (T::*pmf)(ARGS...), ARGS&&... data)
- {
- return new CDerivedFunctorDelegate<T, R, ARGS...>(p, pmf, std::forward<ARGS>(data)...);
- }
- template< typename T, typename R, typename... ARGS > inline // helper to deduce the types
- CDerivedFunctorDelegate<T, R, ARGS...> *MakeFunctor(T& r, R (T::*pmf)(ARGS...), ARGS&&... data)
- {
- return new CDerivedFunctorDelegate<T, R, ARGS...>(r, pmf, std::forward<ARGS>(data)...);
- }
- template<typename R, typename... ARGS > inline // helper to deduce the types
- CDerivedFunctor<R, ARGS...> *MakeFunctor(R (*pmf)(ARGS...), ARGS&&... data)
- {
- return new CDerivedFunctor<R, ARGS...>(pmf, std::forward<ARGS>(data)...);
- }
- enum class E_EVSYS_MSG : DWORD
- {
- STARTUP = 0,
- SHUTDOWN,
- MATHSQRT,
- SETMATHX
- };
- class CEventManager
- {
- public:
- static CEventManager *const GetInstance()
- {
- static CEventManager pInstance;
- return &pInstance;
- };
- template <typename R, typename... ARGS>
- bool RegCallback(E_EVSYS_MSG const &_eType, R (*pmf)(ARGS...), ARGS&&... data)
- {
- auto Func = MakeFunctor(pmf, std::forward<ARGS>(data)...);
- m_Callbacks[_eType].push_back(Func);
- return true;
- };
- template <typename T, typename R, typename... ARGS>
- bool RegCallback(E_EVSYS_MSG const &_eType, T *r, R(T::*pmf)(ARGS...), ARGS&&... data)
- {
- auto Func = MakeFunctor(r, pmf, std::forward<ARGS>(data)...);
- m_Callbacks[_eType].push_back(Func);
- return true;
- };
- void CallEvent(E_EVSYS_MSG const &_eType)
- {
- auto &FuncsVector = m_Callbacks[_eType];
- for (auto f : FuncsVector)
- f->Call();
- };
- void CallEvent(E_EVSYS_MSG const &_eType, void *pInstance)
- {
- auto &FuncsVector = m_Callbacks[_eType];
- for (auto f : FuncsVector)
- f->Call();
- };
- private:
- std::unordered_map<E_EVSYS_MSG, std::vector<IBaseFunctor *>> m_Callbacks;
- //std::queue<E_EVSYS_MSG, void *> m_Queue;
- };
- void SomeCallback(float ff, int nn)
- {
- printf("%d %0.1f\n", nn, ff);
- }
- class CMath
- {
- public:
- float f1;
- float f2;
- float fSqrt()
- {
- return f1 * f2 + f2 * f1;
- }
- };
- int main()
- {
- HRTimer timer;
- struct test
- {
- void foo(int f, char c, std::vector<int> aa)
- {
- printf("void test::foo(int,char,vector)\n %d", aa.size());
- }
- void bar(int, double)
- {
- printf("void test::bar(long,double,test)\n");
- }
- int data;
- } test_it, another;
- //auto fm = std::mem_fn(&test::bar, test_it);
- //void (*func) = std::bind(&test::bar, std::placeholders::_1, 10, 20.0f);
- //ff(&test_it);
- //ff();
- //ff(&test_it);
- //CMath aa;
- CEventManager::GetInstance()->RegCallback(E_EVSYS_MSG::MATHSQRT, &test_it, &test::bar, 10, 100.0);
- CEventManager::GetInstance()->RegCallback(E_EVSYS_MSG::MATHSQRT, &SomeCallback, 10.0f, 100);
- CEventManager::GetInstance()->CallEvent(E_EVSYS_MSG::MATHSQRT);
- _getch();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment