#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 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 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 long LocalFunctionRun(wrapped_message* 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 const& msg) { if (dynamic_cast*>(msg.get())) { throw bond_stop_key(); } else { wrapped_message* wrapper = dynamic_cast*>(msg.get()); if (wrapper) { long re = LocalFunctionRun(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(f_)), m_bChained(false) { prev_->m_bChained = true; } template CTemplateDispatcher HandleMessage(string sStepDescribe, string sClas,string sState,OtherFunc&& of) { return CTemplateDispatcher( m_Queue, this, sStepDescribe, sClas,sState, std::forward(of)); } ~CTemplateDispatcher() noexcept(false) { if (!m_bChained) { WaitAndDispatch(); } } }; }