C++ C++;用于多线程、甚至受驱动的状态模式实现的基类

C++ C++;用于多线程、甚至受驱动的状态模式实现的基类,c++,c++11,state-machine,state-pattern,C++,C++11,State Machine,State Pattern,我正在用C++11启动一个项目 在这个项目中,将有许多对象根据它们的状态彼此交互;另一方面,软件需要异步处理来自不同接口(UART、internet、Bluetooth…)的大量消息,因此每个对象都应该拥有自己的线程来执行消息/事件处理 我正试图为我的项目构造一个状态模式基类(state、StateMachine、Event),具有以下约束: 每个状态机都有自己的线程来处理事件 派生类可以定义自己的事件和状态 以下是我目前的执行情况: //statemachine.hpp 结构事件库 { Ev

我正在用C++11启动一个项目

在这个项目中,将有许多对象根据它们的状态彼此交互;另一方面,软件需要异步处理来自不同接口(UART、internet、Bluetooth…)的大量消息,因此每个对象都应该拥有自己的线程来执行消息/事件处理

我正试图为我的项目构造一个状态模式基类(state、StateMachine、Event),具有以下约束:

  • 每个状态机都有自己的线程来处理事件
  • 派生类可以定义自己的事件和状态
  • 以下是我目前的执行情况:

    
    //statemachine.hpp
    结构事件库
    {
    EventBase(const std::string name):ev_name(name){}
    virtual~EventBase()=默认值;
    const std::字符串ev_name;
    };
    使用EventBasePtr=std::shared\u ptr;
    模板
    类国库
    {
    公众:
    StateBase(const std::string name):st_name(name){}
    virtual~StateBase()=默认值;
    std::string GetName()常量{return st_name;}
    虚拟void OnEvent(EventBasePtr ev)=0;
    虚拟void ActionEntry()=0;
    虚拟void ActionExit()=0;
    虚拟上下文类型&GetContext()=0;
    私人:
    const std::字符串stu name;
    };
    模板
    类StateMachineBase{
    公众:
    StateMachineBase(std::shared_ptr st):st_uu(st)
    {
    线程运行=真;
    ev_proc_thread_uu=std::make_shared(&StateMachineBase::EventProcLoop,this);
    }
    虚拟~StateMachineBase()
    {
    线程运行=false;
    如果(ev_进程线程){
    ev_进程线程->连接();
    ev_进程线程重置();
    }
    }
    //注:
    //应始终在中调用DispatchEvent()
    //1.回调函数
    //2.消息处理函数
    无效调度事件(EventBasePtr ev){
    电动汽车排队推送(ev);
    cv_uu.notify_uone();
    }
    //注意:TransitTo()应始终在中调用
    //1.OnEvent()
    //2.StateBase::ActionEntry()(如果状态库是转换状态)
    无效传输(标准:共享)
    {
    如果(st->GetName()==st->GetName())
    {
    记录(警告)ActionExit();
    st=st;
    st_->ActionEntry();
    }
    std::共享ptr st;
    私人:
    void ProcessEvent(EventBasePtr ev)
    {
    st_u2;OnEvent(ev);
    }
    void EventProcLoop()
    {
    while(线程运行)
    {
    标准:唯一锁定lk(mtx\U cv);
    等一下(lk,[这个]{
    return!thread_run_124;|ev_queue_124;.size()!=0;
    });
    lk.unlock();
    //线程\u运行\u可能由另一个线程切换
    如果(!线程运行)
    打破
    EventBasePtr ev=nullptr;
    mtx_ev_queue_u.lock();
    如果(!ev_queue_uu.empty()){
    ev=ev_队列前();
    ev_队列_uu.pop();
    }
    mtx_ev_队列_uu.unlock();
    if(ev){
    过程事件(ev);
    }
    }
    }
    布尔线程\u运行\u;
    std::条件变量cv;
    std::互斥mtx\u cv;
    std::共享线程;
    std::互斥mtx_ev_queue_;
    std::队列ev\u队列;
    };
    //wificontroller.hpp
    类WifiController:公共状态机数据库
    {
    公众:
    静态WifiController&GetInstance()
    {
    静态线路控制器仪表;
    返回仪表;
    }
    私人:
    WifiController();
    虚拟WifiController()=默认值;
    // =======================================================================
    //状态和事件声明
    // =======================================================================
    结构事件:公共事件库{
    枚举类类型
    {
    连接命令,
    连接结果,
    };
    常数型ev_型;
    事件(类型t,std::string n):ev_类型(t),EventBase(n){
    virtual~Event()=默认值;
    };
    使用EventPtr=std::shared\u ptr;
    结构ConnCmdEvent:公共事件
    {
    int命令;//开始(1),停止(0)
    字符串ssid;
    字符串密码;
    ConnCmdEvent(int cmd,string id,string pw):事件(类型::CONNECT_cmd,“CONNECT_cmd”)、命令(cmd)、ssid(id)、密码(pw){}
    };
    结构ConnResEvent:公共事件{
    成功;
    ConnReseEvent(bool-succ):事件(类型::CONNECT\u-RESULT,“CONNECT\u-RESULT”),成功(success){
    };
    类状态:公共状态库
    {
    公众:
    枚举类类型
    {
    断开的,
    连接,
    有联系的
    };
    State(Type id,std::string name):StateBase(name),st_Type(id){}
    类型GetType()常量{return st_Type}
    WifiController&GetContext()重写{返回WifiController::GetInstance();}
    私人:
    常量类型st_类型u;
    };
    使用StatePtr=std::shared\u ptr;
    类DisconnectedState:公共状态
    {
    公众:
    DisconnectedState()=默认值;
    virtual~DisconnectedState()=默认值;
    无效OneEvent(EventBasePtr ev)覆盖
    {   
    EventPtr事件=动态指针投射(ev);
    开关(事件->电动汽车类型)
    {
    案例事件::类型::连接命令:{
    共享\u ptr conn\u cmd\u ev=动态\u指针\u投射(事件);
    如果(conn_cmd_ev->cmd==1){
    GetContext().TransitTo(使共享(conn_cmd_ev->ssid,conn_cmd_ev->password));
    }
    打破
    }
    违约:
    日志(警告)成功){
    GetContext().TransitTo(使_共享());
    }否则{
    GetContext().TransitTo(使_共享());
    }
    打破
    }
    违约:
    日志(警告)