dispatcher.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #pragma once
  2. #include <functional>
  3. #include "sender.hpp"
  4. #include "TemplateDispatcher.hpp"
  5. namespace ns_mess
  6. {
  7. typedef std::function<string()> StateFunc;
  8. class __declspec(dllexport) close_queue {}; // 用于关闭队列的消息
  9. class __declspec(dllexport) ChangeState // 用于状态切换的消息
  10. {
  11. public:
  12. StateFunc m_chState;
  13. explicit ChangeState(StateFunc s) : m_chState(s) {};
  14. };
  15. class __declspec(dllexport) CDispatcher
  16. {
  17. CMyQueue* m_Queue;
  18. bool m_bChained;
  19. CDispatcher(CDispatcher const&) = delete; // dispatcher实例不能被拷贝
  20. CDispatcher& operator=(CDispatcher const&) = delete;
  21. template<typename Dispatcher,typename Msg,typename Func> // 允许TemplateDispatcher实例访问内部成员
  22. friend class CTemplateDispatcher;
  23. void WaitAndDispatch()
  24. {
  25. for (;;)
  26. {
  27. auto msg = m_Queue->WaitMessage();
  28. DispatchMessage(msg);
  29. }
  30. }
  31. bool DispatchMessage(
  32. std::shared_ptr<MESSAGE_BASE> const& msg)
  33. {
  34. if (dynamic_cast<wrapped_message<close_queue>*>(msg.get()))
  35. {
  36. throw close_queue();
  37. }
  38. else if (dynamic_cast<wrapped_message<ChangeState>*>(msg.get()))
  39. {
  40. wrapped_message<ChangeState>* wrapper = dynamic_cast<wrapped_message<ChangeState>*>(msg.get());
  41. throw wrapper->contents;
  42. }
  43. return true;
  44. }
  45. public:
  46. CDispatcher(CDispatcher&& other) : // dispatcher实例可以移动
  47. m_Queue(other.m_Queue), m_bChained(other.m_bChained)
  48. {
  49. other.m_bChained = true; // 源不能等待消息
  50. }
  51. explicit CDispatcher(CMyQueue* q_) :
  52. m_Queue(q_), m_bChained(false)
  53. {
  54. }
  55. template<typename Message,typename Func>
  56. CTemplateDispatcher<CDispatcher, Message,Func>
  57. HandleMessage(string describe_, string clas_,string state_, Func&& func)
  58. {
  59. return CTemplateDispatcher<CDispatcher, Message, Func>(m_Queue, this, describe_, clas_,state_, std::forward<Func>(func));
  60. }
  61. ~CDispatcher() noexcept(false)
  62. {
  63. if (!m_bChained)
  64. {
  65. WaitAndDispatch();
  66. }
  67. }
  68. };
  69. }