基于 tinyfsm 的状态机
基于tinyfsm 框架的状态机,来对软件架构进行重构。
一,地址
框架地址如下,这是一个单文件项目,只需要include进去即可。
https://github.com/digint/tinyfsm
二,关于状态机的 知识 可以参考这篇文章
万物皆可状态机:解密状态机 (FSM),轻松驾驭复杂系统
三,tinyfsm 实践
#pragma once
#include <iostream>
#include "tinyfsm.hpp"#include <base/MqttClient.hpp>
#include <base/GstreamerEncoder.h>
#include <base/esdk/ESDKManager.h>using namespace Base;// --------- 事件定义 ----------
struct EvExit : tinyfsm::Event
{
};//--------- 上下文 用于不用状态传递指针 ----------
struct FsmContext
{// MQTT 客户端std::shared_ptr<MqttClient> mqttClientPtr;// 编码std::shared_ptr<Encoder> encoderPtr;// 解码std::shared_ptr<ESDKManager> decoderPtr;
};// 状态机
class Controller : public tinyfsm::Fsm<Controller>
{
public:void react(tinyfsm::Event const &) {};void react(EvExit const &);virtual void entry(void) = 0;void exit(void) {};static void set_context(FsmContext *ctx){context = ctx;}protected:static FsmContext *context;
};
#include "Controller.hpp"
#include <Util/logger.h>
#include <iostream>using namespace toolkit;class IdleState;
class InitState;
class RunState;
class ExitState;FsmContext* Controller::context = nullptr;//空闲状态
class IdleState : public Controller
{void entry() override{// 日志Logger::Instance().add(std::make_shared<ConsoleChannel>());auto fileChannel = std::make_shared<FileChannel>("FileChannel", exeDir() + "/logs/");fileChannel->setMaxDay(7);Logger::Instance().add(fileChannel);Logger::Instance().setWriter(std::make_shared<AsyncLogWriter>());// gstreamergst_init(nullptr, nullptr);gst_debug_set_default_threshold(GST_LEVEL_ERROR);transit<InitState>();};
};//初始状态
class InitState : public Controller
{void entry() override{InfoL << "[初始状态]----------------------------开始初始化";bool ret{false};context->mqttClientPtr = std::make_shared<MqttClient>();context->encoderPtr = std::make_shared<Encoder>();context->decoderPtr = std::make_shared<ESDKManager>();ret = context->encoderPtr->Init();if (!ret){return;}ret = context->decoderPtr->Init();if (!ret){return;}ret = context->mqttClientPtr->Init();if (!ret){return;}InfoL << "[初始状态]----------------------------初始化完成";transit<RunState>();};
};//运行状态
class RunState : public Controller
{void entry() override{InfoL << "[运行状态]----------------------------开始运行";context->encoderPtr->Start();};
};//退出状态
class ExitState : public Controller
{void entry() override{InfoL << "[退出状态]----------------------------开始清理资源";context->mqttClientPtr->DeInit();context->encoderPtr->DeInit();context->decoderPtr->DeInit();};
};void Controller::react(EvExit const &)
{transit<ExitState>();
}// 初始状态定义
FSM_INITIAL_STATE(Controller, IdleState)
四,main 函数里调用
#include <iostream>
#include <Thread/semaphore.h>
#include <signal.h>
#include "core/Controller.hpp"
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
#include <base/ImageProcessor.h>using namespace toolkit;
using namespace cv;
using namespace std;int main()
{FsmContext ctx;Controller::set_context(&ctx);Controller::start();static semaphore sem;signal(SIGINT, [](int){signal(SIGINT, SIG_IGN); sem.post(); });sem.wait();Controller::dispatch(EvExit());
}