简体   繁体   English

C++ Boost SML 库

[英]C++ Boost SML Library

I am trying to understand the library, and I am confused by what the high level idea of certain event types are.我试图了解该库,但我对某些事件类型的高级概念感到困惑。 I have been reading the tutorial guide here: Boost Experimental Documentation.我一直在阅读这里的教程指南: Boost 实验文档。 . . It is often using types like on_exit, on_entry and _, which I do not understand.它经常使用像 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.

My end goal is that I want to be able to have a generic event handler.我的最终目标是我希望能够拥有一个通用的事件处理程序。 A src_state might have a specific handler for E1, but for E2, E3, and so on, I want there to be a generic handler. src_state 可能有针对 E1 的特定处理程序,但对于 E2、E3 等,我希望有一个通用处理程序。 I have the code below to list what I want to happen, but obviously it does not work.我有下面的代码来列出我想要发生的事情,但显然它不起作用。

#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));
}

Is it even possible to have a generic event handler for ALL events, including expected and unexpected events.甚至可以为所有事件(包括预期和意外事件)提供通用事件处理程序。 The state machine does expect e1/e2/e3/e4 to happen at times.状态机确实希望 e1/e2/e3/e4 有时会发生。

This is rather old now, but in case someone else stumbles upon this looking for an answer:这现在已经很老了,但以防万一其他人偶然发现这个寻找答案:

Generic Handler通用处理器

In the documentation at time of writing this, what you want to achieve can be done via unexpected event handlers.在撰写本文时的文档中,您想要实现的目标可以通过意外事件处理程序来完成。 These will perform the action and you're free to cause a transition to another state, but you don't need to.这些将执行操作,您可以自由地转换到另一个状态,但您不需要这样做。

The _(underscore) _(下划线)

I'm very reluctant to say anything about this as it is all my own interpretation and I'd rather hear it from someone that has spent more time in the code and understands it better.我非常不愿意对此发表任何意见,因为这完全是我自己的解释,我更愿意从在代码中花费更多时间并更好地理解它的人那里听到它。

From what I see in the link above and my experiments, it can be used to "match" all events that haven't been declared with specific handlers.从我在上面的链接和我的实验中看到的,它可以用来“匹配”所有没有用特定处理程序声明的事件。

Entry/Exit events进入/退出事件

#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;
}

Unexpected events意外事件

I believe the code in the link to the documentation above is clear enough and I don't need to post a working example.我相信上面文档链接中的代码足够清楚,我不需要发布一个工作示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM