boost::sml
最近接触了一些状态机的东西,发现这个确实蛮方便的,已经在boost库里写好了,记录一下。
举个例子先
#include <iostream>
#include <boost/sml.hpp>
namespace sml = boost::sml;
struct state1 {
void operator()() const { std::cout << "Entering state1\n"; }
void on_exit() const { std::cout << "Exiting state1\n"; }
};
struct state2 {
void operator()() const { std::cout << "Entering state2\n"; }
void on_exit() const { std::cout << "Exiting state2\n"; }
};
struct event1 {};
struct event2 {};
auto transition_table = sml::make_transition_table(
sml::state<state1> + sml::on_entry<_> / [] { std::cout << "Entering state1 with any event\n"; } = sml::state<state2>,
sml::state<state2> + sml::on_entry<_> / [] { std::cout << "Entering state2 with any event\n"; } = sml::state<state1>
);
int main() {
sml::sm<decltype(transition_table)> sm; // 声明一个状态机,使用上文所写的transition table作为依据
sm.process_event(event1{});
sm.process_event(event2{});
}
以上涉及了on_exit()和on_entry(),意思分别是刚进入/刚离开该状态时会采用的action。
在此补充一个概念:
state – 是一个类,系统处于某一特定的状态下。
event – 是一个结构体,是一个信号触发器,代表状态发生改变。
guard – 用于确定是否发生状态转换。
action – 转换发生时所执行的函数或方法。
上述代码所描述的状态机有两个状态:state1和state2,有两个event:event1和event2。
流程如下:
在main()
中,使用sm.process_event(event1{});
,将event1作为参数并以此为依据进行状态转换。
在transition table中,从state1这个状态,由event1触发,开始转换到state2状态。当转移发生时,执行on_entry这个action,这个action内联了一个lambda表达式,输出"Entering state1 with any event\n"。
就先写到这里,回头再补充