微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

了解 hello_world boost sml 状态机库

如何解决了解 hello_world boost sml 状态机库

以下是 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,"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

我对 * 的猜测是它指定了状态机的开始状态。

事件是发生的事情。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。