1 投食型状态机
1 有限状态机官方测试小demo, 投食型状态机
//
// Created by xhome on 2020/9/7.
// 一个简单的有限状态机测试
//
#include "tinyfsm.hpp"
#include <iostream>
//1. 事件的声明,可以携带参数
struct Toggle : tinyfsm::Event{};
//2.定义状态机基类, 投食型状态机
struct Switch : tinyfsm::MealyMachine<Switch>
{
//纯虚反射,需要在每个状态机中实现.
virtual void react(Toggle const &) = 0;
//转换操作,开路
static void OpenCircuit(){
std::cout << "开路(light goes OFF)" << std::endl;
}
static void CloseCircuit(){
std::cout << "关路(light goes ON)" << std::endl;
}
};
//3.状态机申明
struct Off;
struct On : Switch{
void react(Toggle const &) override {
transit<Off>(OpenCircuit); //有限状态机状态切换到off
}
};
struct Off :Switch{
void react(Toggle const &) override {
transit<On>(CloseCircuit); //状态切换到on
}
};
//初始化状态机的状态.
FSM_INITIAL_STATE(Switch, Off)
int main()
{
//开启状态机
Switch::start();
std::cout << "> You are facing a light switch..." << std::endl;
while(1)
{
char c;
std::cout << std::endl << "t=Toggle, q=Quit ? ";
std::cin >> c;
switch(c) {
case 't':
std::cout << "> Toggling switch..." << std::endl;
Switch::dispatch(Toggle());
break;
case 'q':
return 0;
default:
std::cout << "> Invalid input" << std::endl;
};
}
return 0;
}
2 摩尔型状态机
2 摩尔型状态机
//
// Created by xhome on 2020/9/7.
// 摩尔类型状态机
//
#include "tinyfsm.hpp"
#include <iostream>
//1. 事件的声明,可以携带参数
struct Toggle : tinyfsm::Event{};
//2.定义状态机基类, 投食型状态机
struct Switch : tinyfsm::MooreMachine<Switch>
{
//纯虚反射,需要在每个状态机中实现.
virtual void react(Toggle const &) = 0;
};
//3.状态机申明
struct Off;
struct On : Switch{
void entry() override {
std::cout << "* Closing ciruit (light goes ON)" << std::endl;
};
void react(Toggle const &) override {
transit<Off>(); //有限状态机状态切换到off
}
};
struct Off :Switch{
void entry() override {
std::cout << "* Opening ciruit (light goes OFF)" << std::endl;
};
void react(Toggle const &) override {
transit<On>(); //状态切换到on
}
};
//初始化状态机的状态.
FSM_INITIAL_STATE(Switch, Off)
int main()
{
Switch::start();
std::cout << "> You are facing a light switch..." << std::endl;
while(1)
{
char c;
std::cout << std::endl << "t=Toggle, q=Quit ? ";
std::cin >> c;
switch(c) {
case 't':
std::cout << "> Toggling switch..." << std::endl;
Switch::dispatch(Toggle());
break;
case 'q':
return 0;
default:
std::cout << "> Invalid input" << std::endl;
};
}
}
3 多状态机
//
// Created by xhome on 2020/9/7.
// 本例展示故障开关,多重次
//
// DumpState 转储状态.
#include "tinyfsm.hpp"
#include <iostream>
#include <stdlib.h> /* rand */
//模板类申明.
template <int inum>
class Off;
//状态转储
static void DumpState(int inum, const char * state, int on_counter, int defect_level){
std::cout << "* Switch[" << inum << "] is " << state << " (on_counter=" << on_counter << ", defect_level=" << defect_level << ")" << std::endl;
}
//1.事件定义
struct Toggle:tinyfsm::Event{};
//2.状态机基类定义
template <int inum>
class DefectiveSwitch : public tinyfsm::Fsm<DefectiveSwitch<inum>>
{
public:
static constexpr unsigned int defect_level = (inum*2);
static void reset(void ){
on_counter = 0;
}
void react(tinyfsm::Event const &){};
virtual void react(Toggle const &){};
virtual void entry(void){};
void exit(){};
protected:
static unsigned int on_counter;
};
template <int inum>
unsigned int DefectiveSwitch<inum>::on_counter{0};
//状态变量的定义
template <int inum>
class On : public DefectiveSwitch<inum>
{
using base = DefectiveSwitch<inum>;
void entry()override {
base::on_counter++;
DumpState(inum, "ON ", base::on_counter, base::defect_level);
}
void react(Toggle const &) override {
base::template transit<Off<inum>>();
}
};
template <int inum>
class Off : public DefectiveSwitch<inum>
{
using base = DefectiveSwitch<inum>;
void entry() override {
DumpState(inum, "OFF", base::on_counter , base::defect_level);
}
void react(Toggle const &) override {
if((rand()%(base::defect_level +1)) == 0){
base::template transit<On<inum>>();
}else{
std::cout << "* Kzzz kzzzzzz" << std::endl;
base::template transit< Off<inum> >();
}
}
};
FSM_INITIAL_STATE(DefectiveSwitch<0>, Off<0>)
FSM_INITIAL_STATE(DefectiveSwitch<1>, Off<1>)
FSM_INITIAL_STATE(DefectiveSwitch<2>, Off<2>)
//4.状态机列表申明
using fsm_handle = tinyfsm::FsmList<DefectiveSwitch<0>, DefectiveSwitch<1>, DefectiveSwitch<2>>;
template <int inum>
void ToggleSingle(){
std::cout << "> Toggling switch " << inum << "..." << std::endl;
DefectiveSwitch<inum>::dispatch(Toggle());
}
int main()
{
fsm_handle::start();
while(1)
{
char c;
std::cout << std::endl << "0,1,2=Toggle single, a=Toggle all, r=Restart, q=Quit ? ";
std::cin >> c;
switch(c) {
case '0': ToggleSingle<0>(); break;
case '1': ToggleSingle<1>(); break;
case '2': ToggleSingle<2>(); break;
case 'a':
std::cout << "> Toggling all switches..." << std::endl;
fsm_handle::dispatch(Toggle());
break;
case 'r':
fsm_handle::reset();
fsm_handle::start();
break;
case 'q':
return 0;
default:
std::cout << "> Invalid input" << std::endl;
};
}
return 0;
}