TemplateDispatcher.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #pragma once
  2. #include "CEventBase.h"
  3. #include "SystemResources.h"
  4. namespace ns_mess
  5. {
  6. class __declspec(dllexport) bond_stop_key {}; // 用于停止固晶的消息
  7. class __declspec(dllexport) step_run_error {}; // 用于Step执行出错抛出消息
  8. template<typename PreviousDispatcher, typename Msg, typename Func>
  9. class __declspec(dllexport) CTemplateDispatcher
  10. {
  11. CMyQueue* m_Queue;
  12. PreviousDispatcher* prev;
  13. string m_chDescribe;
  14. Func func;
  15. string m_chClass;
  16. string m_chState;
  17. bool m_bChained;
  18. CTemplateDispatcher(CTemplateDispatcher const&) = delete;
  19. CTemplateDispatcher& operator=(CTemplateDispatcher const&) = delete;
  20. template<typename Dispatcher, typename OtherMsg, typename OtherFunc>
  21. friend class CTemplateDispatcher; // 所有特化的TemplateDispatcher类型实例都是友元类
  22. std::string GetClassName(std::string cls)
  23. {
  24. std::string className = cls;
  25. int firstSpaceIndex = (int)className.find_first_of(" ") + 1;
  26. int lastSpaceIndex = (int)className.find_last_of(" ");
  27. int nameLength = lastSpaceIndex - firstSpaceIndex - 2;
  28. return className.substr(firstSpaceIndex, nameLength);
  29. }
  30. void WaitAndDispatch()
  31. {
  32. for (;;)
  33. {
  34. auto msg = m_Queue->WaitMessage();
  35. if (DispatchMessage(msg))
  36. break;
  37. }
  38. }
  39. template<typename step>
  40. long LocalFunctionRun(wrapped_message<Msg>* wm)
  41. {
  42. auto f1 = [&](step const& msg)->bool
  43. {
  44. string n = GetClassName(typeid(msg).name());
  45. return wm->contents.EventRun(m_chDescribe, m_chClass,m_chState,n);
  46. };
  47. return f1(wm->contents);
  48. }
  49. bool DispatchMessage(std::shared_ptr<MESSAGE_BASE> const& msg)
  50. {
  51. if (dynamic_cast<wrapped_message<bond_stop_key>*>(msg.get()))
  52. {
  53. throw bond_stop_key();
  54. }
  55. else
  56. {
  57. wrapped_message<Msg>* wrapper = dynamic_cast<wrapped_message<Msg>*>(msg.get());
  58. if (wrapper)
  59. {
  60. long re = LocalFunctionRun<Msg>(wrapper);
  61. if (OK == re)
  62. {
  63. func(wrapper->contents);
  64. }
  65. else if(FSM_NOT_EXECUTE != re)
  66. {
  67. throw step_run_error();
  68. }
  69. return (re == OK ? true : false);
  70. }
  71. else
  72. {
  73. return prev->DispatchMessage(msg);
  74. }
  75. }
  76. }
  77. public:
  78. CTemplateDispatcher(CTemplateDispatcher&& other) :
  79. m_Queue(other.m_Queue), prev(other.prev), m_chDescribe(other.m_chDescribe), m_chClass(other.m_chClass), m_chState(other.m_chState),
  80. func(std::move(other.func)),m_bChained(other.m_bChained)
  81. {
  82. other.m_bChained = true;
  83. }
  84. CTemplateDispatcher(CMyQueue* q_, PreviousDispatcher* prev_,string describe_, string clas_,string state_,Func&& f_) :
  85. m_Queue(q_), prev(prev_), m_chDescribe(describe_), m_chClass(clas_),m_chState(state_), func(std::forward<Func>(f_)), m_bChained(false)
  86. {
  87. prev_->m_bChained = true;
  88. }
  89. template<typename OtherMsg, typename OtherFunc>
  90. CTemplateDispatcher<CTemplateDispatcher, OtherMsg, OtherFunc>
  91. HandleMessage(string sStepDescribe, string sClas,string sState,OtherFunc&& of)
  92. {
  93. return CTemplateDispatcher<CTemplateDispatcher, OtherMsg,OtherFunc>(
  94. m_Queue, this, sStepDescribe, sClas,sState, std::forward<OtherFunc>(of));
  95. }
  96. ~CTemplateDispatcher() noexcept(false)
  97. {
  98. if (!m_bChained)
  99. {
  100. WaitAndDispatch();
  101. }
  102. }
  103. };
  104. }