Aleks11

Deferred function calling

Mar 14th, 2014
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.44 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <Windows.h>
  4.  
  5. #include <vector>
  6. #include <string>
  7. #include <queue>
  8. #include <functional>
  9. #include <unordered_map>
  10. #include <typeinfo>
  11.  
  12. // http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html
  13. // http://www.codeproject.com/Articles/384572/Implementation-of-Delegates-in-Cplusplus
  14. // http://geekswithblogs.net/raccoon_tim/archive/2011/09/28/lambdas-and-events-in-c.aspx
  15. // http://stackoverflow.com/questions/16868129/how-to-store-variadic-template-arguments
  16. // http://www.cplusplus.com/forum/general/63061/
  17.  
  18. struct IBaseFunctor
  19. {
  20.     virtual ~IBaseFunctor()
  21.     {
  22.     }
  23.     virtual void Call() = 0;
  24. };
  25.  
  26. template< typename TARGET, typename RESULT, typename... ARGS >
  27. struct CDerivedFunctorDelegate : IBaseFunctor
  28. {
  29.     CDerivedFunctorDelegate(TARGET* ptr, RESULT(TARGET::*pmfn)(ARGS...), ARGS&&... data)
  30.         : m_Func(std::bind(pmfn, ptr, std::forward<ARGS>(data)...))
  31.     {
  32.     }
  33.  
  34.     CDerivedFunctorDelegate(TARGET& ref, RESULT(TARGET::*pmfn)(ARGS...), ARGS&&... data)
  35.         : m_Func(std::bind(pmfn, ref, std::forward<ARGS>(data)...))
  36.     {
  37.     }
  38.  
  39.     virtual void Call() override
  40.     {
  41.         m_Func();
  42.     }
  43. private:
  44.     std::function< void() > m_Func;
  45. };
  46.  
  47. template<typename RESULT, typename... ARGS>
  48. struct CDerivedFunctor : IBaseFunctor
  49. {
  50.     CDerivedFunctor(RESULT(*pmfn)(ARGS...), ARGS&&... data)
  51.         : m_Func(std::bind(pmfn, std::forward<ARGS>(data)...))
  52.     {
  53.     }
  54.  
  55.     virtual void Call() override
  56.     {
  57.         m_Func();
  58.     }
  59. private:
  60.     std::function< void() > m_Func;
  61. };
  62.  
  63. template< typename T, typename R, typename... ARGS > inline // helper to deduce the types
  64. CDerivedFunctorDelegate<T, R, ARGS...> *MakeFunctor(T* p, R (T::*pmf)(ARGS...), ARGS&&... data)
  65. {
  66.     return new CDerivedFunctorDelegate<T, R, ARGS...>(p, pmf, std::forward<ARGS>(data)...);
  67. }
  68.  
  69. template< typename T, typename R, typename... ARGS > inline // helper to deduce the types
  70. CDerivedFunctorDelegate<T, R, ARGS...> *MakeFunctor(T& r, R (T::*pmf)(ARGS...), ARGS&&... data)
  71. {
  72.     return new CDerivedFunctorDelegate<T, R, ARGS...>(r, pmf, std::forward<ARGS>(data)...);
  73. }
  74.  
  75. template<typename R, typename... ARGS > inline // helper to deduce the types
  76. CDerivedFunctor<R, ARGS...> *MakeFunctor(R (*pmf)(ARGS...), ARGS&&... data)
  77. {
  78.     return new CDerivedFunctor<R, ARGS...>(pmf, std::forward<ARGS>(data)...);
  79. }
  80.  
  81. enum class E_EVSYS_MSG : DWORD
  82. {
  83.     STARTUP = 0,
  84.     SHUTDOWN,
  85.     MATHSQRT,
  86.     SETMATHX
  87. };
  88.  
  89. class CEventManager
  90. {
  91. public:
  92.     static CEventManager *const GetInstance()
  93.     {
  94.         static CEventManager pInstance;
  95.         return &pInstance;
  96.     };
  97.  
  98.     template <typename R, typename... ARGS>
  99.         bool RegCallback(E_EVSYS_MSG const &_eType, R (*pmf)(ARGS...), ARGS&&... data)
  100.     {
  101.         auto Func = MakeFunctor(pmf, std::forward<ARGS>(data)...);
  102.  
  103.         m_Callbacks[_eType].push_back(Func);
  104.  
  105.         return true;
  106.     };
  107.  
  108.     template <typename T, typename R, typename... ARGS>
  109.         bool RegCallback(E_EVSYS_MSG const &_eType, T *r, R(T::*pmf)(ARGS...), ARGS&&... data)
  110.     {
  111.         auto Func = MakeFunctor(r, pmf, std::forward<ARGS>(data)...);
  112.  
  113.         m_Callbacks[_eType].push_back(Func);
  114.  
  115.         return true;
  116.     };
  117.  
  118.     void CallEvent(E_EVSYS_MSG const &_eType)
  119.     {
  120.         auto &FuncsVector = m_Callbacks[_eType];
  121.  
  122.         for (auto f : FuncsVector)
  123.             f->Call();
  124.     };
  125.  
  126.     void CallEvent(E_EVSYS_MSG const &_eType, void *pInstance)
  127.     {
  128.         auto &FuncsVector = m_Callbacks[_eType];
  129.  
  130.         for (auto f : FuncsVector)
  131.             f->Call();
  132.     };
  133. private:
  134.     std::unordered_map<E_EVSYS_MSG, std::vector<IBaseFunctor *>> m_Callbacks;
  135.     //std::queue<E_EVSYS_MSG, void *>   m_Queue;
  136. };
  137.  
  138. void SomeCallback(float ff, int nn)
  139. {
  140.     printf("%d %0.1f\n", nn, ff);
  141. }
  142.  
  143. class CMath
  144. {
  145. public:
  146.     float f1;
  147.     float f2;
  148.  
  149.     float fSqrt()
  150.     {
  151.         return f1 * f2 + f2 * f1;
  152.     }
  153. };
  154.  
  155.  
  156. int main()
  157. {
  158.     HRTimer timer;
  159.  
  160.     struct test
  161.     {
  162.         void foo(int f, char c, std::vector<int> aa)
  163.         {
  164.             printf("void test::foo(int,char,vector)\n %d", aa.size());
  165.         }
  166.         void bar(int, double)
  167.         {
  168.             printf("void test::bar(long,double,test)\n");
  169.         }
  170.    
  171.         int data;
  172.     } test_it, another;
  173.  
  174.     //auto fm = std::mem_fn(&test::bar, test_it);
  175.  
  176.     //void (*func) = std::bind(&test::bar, std::placeholders::_1, 10, 20.0f);
  177.     //ff(&test_it);
  178.  
  179.     //ff();
  180.     //ff(&test_it);
  181.  
  182.     //CMath aa;
  183.  
  184.     CEventManager::GetInstance()->RegCallback(E_EVSYS_MSG::MATHSQRT, &test_it, &test::bar, 10, 100.0);
  185.     CEventManager::GetInstance()->RegCallback(E_EVSYS_MSG::MATHSQRT, &SomeCallback, 10.0f, 100);
  186.  
  187.     CEventManager::GetInstance()->CallEvent(E_EVSYS_MSG::MATHSQRT);
  188.  
  189.     _getch();
  190.     return 0;
  191. }
Advertisement
Add Comment
Please, Sign In to add comment