我正在尝试了解该库,但我对某些事件类型的高级概念感到困惑。我一直在这里阅读教程指南: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 有时会发生。
这现在已经相当老了,但万一其他人偶然发现这个问题来寻找答案:
在撰写本文时的文档中,您想要实现的目标可以通过意外事件处理程序来完成。这些将执行操作,您可以自由地转换到另一个状态,但您不需要这样做。
我非常不愿意对此说任何话,因为这都是我自己的解释,我宁愿从在代码上花费更多时间并更好地理解它的人那里听到它。
从我在上面的链接和我的实验中看到的,它可以用于“匹配”所有尚未使用特定处理程序声明的事件。
进入/退出事件
#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;
}
意外事件
我相信上面文档链接中的代码足够清晰,我不需要发布工作示例。