C++ Boost SML 库

问题描述 投票:0回答:1

我正在尝试了解该库,但我对某些事件类型的高级概念感到困惑。我一直在这里阅读教程指南:Boost 实验文档。。它经常使用像 on_exit、on_entry 和 _ 这样的类型,我不明白。

struct _ {}; // I don't understand how to use this

template <class T, class TEvent = T>
struct on_entry : internal_event, entry_exit { // A setup function that runs before the actual event
    // ...

template <class T, class TEvent = T>
struct on_exit : internal_event, entry_exit { // Will run after the event has completed.
    // ...

struct anonymous : internal_event { // Not sure, I think this is for any unknown type that you have not defined.

我的最终目标是我希望能够拥有一个通用的事件处理程序。 src_state 可能有一个针对 E1 的特定处理程序,但对于 E2、E3 等,我希望有一个通用处理程序。我有下面的代码来列出我想要发生的事情,但显然它不起作用。

#include <boost/sml.hpp>
#include <cassert>
#include <iostream>

namespace sml = boost::sml;

namespace {
struct e1 {};
struct e2 {};
struct e3 {};
struct e4 {};

struct transitions {
    auto operator()() const noexcept {
    using namespace sml;
    return make_transition_table(
        *"idle"_s                  / [] { std::cout << "anonymous transition" << std::endl; } = "s1"_s
        , "s1"_s + event<e1>        / [] { std::cout << "internal s1 transition" << std::endl; }
        , "s1"_s + event<e2>        / [] { std::cout << "self transition" << std::endl; } = "s2"_s
        , "s1"_s + event<_>         / [] { std::cout << "s1 Handle all other events here" << std::endl; } = "s1"_s
        , "s2"_s + event<e2>        / [] {std::cout << "internal s2 transition" << std::endl; }
        , "s2"_s + event<_>         / [] { std::cout << "s2 Handle all other events here" << std::endl; } = "s2"_s
        , "s2"_s + event<e3>        / [] { std::cout << "external transition" << std::endl; } = X
);
    }
};
}

int main() {
    sml::sm<transitions> sm;
    sm.process_event(e1{}); // Basic
    sm.process_event(e3{}); // The underscore should handle the event now...
    sm.process_event(e2{}); // Transition to s2
    sm.process_event(e1{}); // The _ should handle this.
    sm.process_event(e4{}); // The _ should handle this.
    sm.process_event(e3{}); // X

    assert(sm.is(sml::X));
}

是否有可能为所有事件(包括预期事件和意外事件)提供通用事件处理程序。状态机确实期望 e1/e2/e3/e4 有时会发生。

c++ boost state-machine boost-sml
1个回答
4
投票

这现在已经相当老了,但万一其他人偶然发现这个问题来寻找答案:

通用处理程序

在撰写本文时的文档中,您想要实现的目标可以通过意外事件处理程序来完成。这些将执行操作,您可以自由地转换到另一个状态,但您不需要这样做。

_(下划线)

我非常不愿意对此说任何话,因为这都是我自己的解释,我宁愿从在代码上花费更多时间并更好地理解它的人那里听到它。

从我在上面的链接和我的实验中看到的,它可以用于“匹配”所有尚未使用特定处理程序声明的事件。

进入/退出事件

#include <boost/sml.hpp>
#include <iostream>

struct state_machine {
public:
  // Transition table
  auto operator() () const {
    using namespace boost::sml;
    return make_transition_table(
      *"state_a"_s + event<event_1> = "state_b"_s,
      "state_a"_s + event<event_2> = "state_b"_s,
      "state_b"_s + on_entry<event_1> / ActionOne{},
      "state_b"_s + on_entry<_> / ActionTwo{}
    );
  }

  // Events
  struct event_1 {};
  struct event_2 {};

  // Actions
  struct ActionOne {
    void operator()() {
      std::cout << "Transition due to event_1" << std::endl;
    };
  };

  struct ActionTwo {
    void operator()() {
      std::cout << "Transition due to event_2" << std::endl;
    };
  };
};

int main () {
  boost::sml::sm<state_machine> fsm_one, fsm_two;

  // Will invoke ActionOne
  fsm_one.process_event(state_machine::event_1{});

  // Will invoke ActionTwo
  fsm_two.process_event(state_machine::event_2{});

  return 0;
}

意外事件

我相信上面文档链接中的代码足够清晰,我不需要发布工作示例。

© www.soinside.com 2019 - 2024. All rights reserved.