【发布时间】:2021-02-15 03:17:03
【问题描述】:
这里是 boost sml C++ 库的 hello world 示例:https://boost-ext.github.io/sml/examples.html#hello-world
// $CXX -std=c++14 hello_world.cpp
#include <boost/sml.hpp>
#include <cassert>
namespace sml = boost::sml;
namespace {
struct release {};
struct ack {};
struct fin {};
struct timeout {};
const auto is_ack_valid = [](const ack&) { return true; };
const auto is_fin_valid = [](const fin&) { return true; };
const auto send_fin = [] {};
const auto send_ack = [] {};
#if !defined(_MSC_VER)
struct hello_world {
auto operator()() const {
using namespace sml;
return make_transition_table(
*"established"_s + event<release> / send_fin = "fin wait 1"_s,
"fin wait 1"_s + event<ack> [ is_ack_valid ] = "fin wait 2"_s,
"fin wait 2"_s + event<fin> [ is_fin_valid ] / send_ack = "timed wait"_s,
"timed wait"_s + event<timeout> / send_ack = X
);
}
};
}
int main() {
using namespace sml;
sm<hello_world> sm;
static_assert(1 == sizeof(sm), "sizeof(sm) != 1b");
assert(sm.is("established"_s));
sm.process_event(release{});
assert(sm.is("fin wait 1"_s));
sm.process_event(ack{});
assert(sm.is("fin wait 2"_s));
sm.process_event(fin{});
assert(sm.is("timed wait"_s));
sm.process_event(timeout{});
assert(sm.is(X)); // released
}
#else
class established;
class fin_wait_1;
class fin_wait_2;
class timed_wait;
struct hello_world {
auto operator()() const {
using namespace sml;
return make_transition_table(
*state<established> + event<release> / send_fin = state<fin_wait_1>,
state<fin_wait_1> + event<ack> [ is_ack_valid ] = state<fin_wait_2>,
state<fin_wait_2> + event<fin> [ is_fin_valid ] / send_ack = state<timed_wait>,
state<timed_wait> + event<timeout> / send_ack = X
);
}
};
}
int main() {
using namespace sml;
sm<hello_world> sm;
assert(sm.is(state<established>));
sm.process_event(release{});
assert(sm.is(state<fin_wait_1>));
sm.process_event(ack{});
assert(sm.is(state<fin_wait_2>));
sm.process_event(fin{});
assert(sm.is(state<timed_wait>));
sm.process_event(timeout{});
assert(sm.is(X)); // released
}
#endif
我了解_s 创建一个带有名称的状态,并且状态上可能发生事件,从而将状态机发送到另一个状态。
让我们看看hello_world状态机:
struct hello_world {
auto operator()() const {
using namespace sml;
return make_transition_table(
*"established"_s + event<release> / send_fin = "fin wait 1"_s,
"fin wait 1"_s + event<ack> [ is_ack_valid ] = "fin wait 2"_s,
"fin wait 2"_s + event<fin> [ is_fin_valid ] / send_ack = "timed wait"_s,
"timed wait"_s + event<timeout> / send_ack = X
);
}
};
如果我理解正确的话,这意味着当状态机处于状态established并接收到一个事件release时,它会进入状态fin wait 1。 send_fin 是什么? *state<established> + event<release> / send_fin = state<fin_wait_1> 中的 * 是什么?这个疯狂的语法是什么?我认为+、/ 和= 只是简单的重写运算符,可以轻松创建转换表。还有,is_ack_valid是什么?
我对@987654336@ 的猜测是它指定了状态机的开始状态。
事件是发生的事情。
【问题讨论】:
-
is_ack_valid是验证 ack 事件的 lambda。
标签: c++ state-machine automata