如何解决[Boost :: ext] .SML:是否可以存储回调以稍后处理事件?
我来自Boost MSM,现在正在尝试使用SML 1.1.3实现相同的状态机。
使用SML,我无权访问状态机本身,而我不得不处理注入的依赖项。我也大量使用D-Bus,现在在进行异步D-Bus调用时遇到问题。异步D-Bus调用是在注入依赖项的方法中进行的。 D-Bus调用完成后,将调用依赖项中的回调。在那里,我需要一种向状态机发出事件的方法。
存储 PASS src/stackoverflow/64386858/app.spec.js
64386858
✓ should pass (17ms)
console.log node_modules/jest-environment-jsdom/node_modules/jest-mock/build/index.js:866
verified successfully. Implement next logic
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 50 | 100 | 100 | |
app.js | 100 | 50 | 100 | 100 | 13 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed,1 total
Tests: 1 passed,1 total
Snapshots: 0 total
Time: 5.087s,estimated 11s
无效,我不知道异步D-Bus调用结束后它是否仍然有效。
示例:
sml::back::process
...
auto queryDBusAction = []( Dep& dep,sml::back::process<Ev_Result> processEvent ) {
dep.makeAsyncDBusCall( SomeCallback );
};
解决方法
为了访问状态机本身,您需要将应用程序类分为基类和子类。 基类具有纯虚拟成员函数声明。 您可以从sml过渡表操作中调用成员函数。
您需要在过渡表定义之后定义子类。
现在,子类可以访问过渡表的整个定义。
这意味着您可以包含sml::sm
作为子类的成员。
因此,您可以从成员函数中调用sml后端的process_event()
函数。参见memfun1()
。
#include <iostream>
#include <cassert>
#include <boost/sml.hpp>
#include <boost/asio.hpp>
namespace sml = boost::sml;
struct e1 {};
struct e2 {};
// Separate member function declarations as the base class
struct app_base {
virtual void memfun1() = 0;
virtual void memfun2(int) const = 0;
virtual ~app_base() = default;
};
struct app_table {
auto operator()() const noexcept {
using namespace sml;
// I can write member function call in action thanks to base class app_base
return make_transition_table(
// source event guard action target
*"s1"_s + event<e1> [([] { return true; })] / [](app_base& appb) { appb.memfun1(); } = "s2"_s,"s2"_s + event<e2> / [](app_base& appb) { appb.memfun2(42); } = "s1"_s
);
}
};
struct app : app_base {
app(boost::asio::io_context& ioc):ioc { ioc } {}
// post asynchronous callback function that calls process_event()
void memfun1() override {
std::cout << __PRETTY_FUNCTION__ << std::endl;
boost::asio::post(
ioc,[this] {
std::cout << "async callback is called. call process_event()" << std::endl;
sm_.process_event(e2{});
using namespace sml;
assert(sm_.is("s1"_s));
}
);
}
void memfun2(int v) const override {
std::cout << __PRETTY_FUNCTION__ << ":" << v << std::endl;
}
// state machine backend can be a member of application class
sml::sm<app_table> sm_ { static_cast<app_base&>(*this) };
boost::asio::io_context& ioc;
};
int main() {
using namespace sml;
boost::asio::io_context ioc; // for async operation example
app a { ioc };
assert(a.sm_.is("s1"_s));
a.sm_.process_event(e1{});
assert(a.sm_.is("s2"_s));
ioc.run(); // async loop start until async event will become empty
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。