下面是boost sml C++库的hello示例: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?
我对*的猜测是,它指定了状态机的乞讨状态。
事件是会发生的事情。
发布于 2022-02-02 03:54:27
--如果我理解正确,这意味着当状态机处于已建立并接收事件释放的状态时,它将进入状态fin等待1。
真的
,send_fin是什么?
在州内接收释放时触发的一种动作。在这个例子中,它是一个绝对什么都不做的lambda。*耸耸肩:
* in *state + event / send_fin = state是什么?这种疯狂的语法是什么?我认为+,/ and =是简单的覆盖运算符,可以轻松地创建转换表。
*是初始状态,您是正确的。值得注意的是,一个复杂的转换表实际上可以跟踪多个子计算机,因此每个部分都有多个*。
我非常怀疑您是正确的,操作符重载驱动了语法。说到设计,它也是通过TMP优化的编译时间。
也是,is_ack_valid是什么?
在事件后封装在括号中的表达式称为守护。评估为false的保护将防止任何操作或转换发生,即使接收到了该事件。
在这个简单的例子中,lambda总是返回true,所以它在编写时是无用的。一个更完整的示例将实际检查ack上的某些内容。
我猜*是它指定了状态机的开始状态。
真的
事件是会发生的事情。
好的。没有任何价值,它们是强类型的,并且被有意地发送到状态机。
不请自来的评论如下.
我已经在工作中大量使用了SML。一开始,这是一件需要学习的事情,因为我已经在用消防水管喝水了。
在经历了一段时间之后,我要说的积极的事情是,它可以非常简洁地表示复杂的流控制,而且它是非常有效的。
如果您有机会观看克里斯的2019年c++现在谈话,他的TCP连接状态管理是一个很好的例子,从这一点。
https://stackoverflow.com/questions/66202301
复制相似问题