#pragma once #include "CEventBase.h" #include "SystemResources.h" namespace ns_mess { class __declspec(dllexport) bond_stop_key {}; // ����ֹͣ�̾�����Ϣ class __declspec(dllexport) step_run_error {}; // ����Stepִ�г����׳���Ϣ template<typename PreviousDispatcher, typename Msg, typename Func> class __declspec(dllexport) CTemplateDispatcher { CMyQueue* m_Queue; PreviousDispatcher* prev; string m_chDescribe; Func func; string m_chClass; string m_chState; bool m_bChained; CTemplateDispatcher(CTemplateDispatcher const&) = delete; CTemplateDispatcher& operator=(CTemplateDispatcher const&) = delete; template<typename Dispatcher, typename OtherMsg, typename OtherFunc> friend class CTemplateDispatcher; // �����ػ���TemplateDispatcher����ʵ��������Ԫ�� std::string GetClassName(std::string cls) { std::string className = cls; int firstSpaceIndex = (int)className.find_first_of(" ") + 1; int lastSpaceIndex = (int)className.find_last_of(" "); int nameLength = lastSpaceIndex - firstSpaceIndex - 2; return className.substr(firstSpaceIndex, nameLength); } void WaitAndDispatch() { for (;;) { auto msg = m_Queue->WaitMessage(); if (DispatchMessage(msg)) break; } } template<typename step> long LocalFunctionRun(wrapped_message<Msg>* wm) { auto f1 = [&](step const& msg)->bool { string n = GetClassName(typeid(msg).name()); return wm->contents.EventRun(m_chDescribe, m_chClass,m_chState,n); }; return f1(wm->contents); } bool DispatchMessage(std::shared_ptr<MESSAGE_BASE> const& msg) { if (dynamic_cast<wrapped_message<bond_stop_key>*>(msg.get())) { throw bond_stop_key(); } else { wrapped_message<Msg>* wrapper = dynamic_cast<wrapped_message<Msg>*>(msg.get()); if (wrapper) { long re = LocalFunctionRun<Msg>(wrapper); if (OK == re) { func(wrapper->contents); } else if(FSM_NOT_EXECUTE != re) { throw step_run_error(); } return (re == OK ? true : false); } else { return prev->DispatchMessage(msg); } } } public: CTemplateDispatcher(CTemplateDispatcher&& other) : m_Queue(other.m_Queue), prev(other.prev), m_chDescribe(other.m_chDescribe), m_chClass(other.m_chClass), m_chState(other.m_chState), func(std::move(other.func)),m_bChained(other.m_bChained) { other.m_bChained = true; } CTemplateDispatcher(CMyQueue* q_, PreviousDispatcher* prev_,string describe_, string clas_,string state_,Func&& f_) : m_Queue(q_), prev(prev_), m_chDescribe(describe_), m_chClass(clas_),m_chState(state_), func(std::forward<Func>(f_)), m_bChained(false) { prev_->m_bChained = true; } template<typename OtherMsg, typename OtherFunc> CTemplateDispatcher<CTemplateDispatcher, OtherMsg, OtherFunc> HandleMessage(string sStepDescribe, string sClas,string sState,OtherFunc&& of) { return CTemplateDispatcher<CTemplateDispatcher, OtherMsg,OtherFunc>( m_Queue, this, sStepDescribe, sClas,sState, std::forward<OtherFunc>(of)); } ~CTemplateDispatcher() noexcept(false) { if (!m_bChained) { WaitAndDispatch(); } } }; }