boost::msm 用法:如何设置目标状态的属性
boost::msm usage: how to set properties of target states
我的FSM中的状态具有不同的属性。我定义了一个事件,该事件将调用到目标状态的转换。我想按事件数据设置目标的属性。我的选择是:1. 在操作或防护中设置属性:但它仍处于源状态。如果我在当时设置目标状态属性,我填写不好2.在目标条目中设置属性:但是属性的值已在收到事件时进行了保护,因此我应该再次重新计算:(
任何人都可以给我更多的想法。谢谢!
我不确定您的情况,但我认为您有两个不同的问题。一个是设置目标状态属性的最佳位置。另一个是如何避免重新计算。
让我们考虑前一个问题。正如你提到的,有两个候选人。它们是转换操作和目标状态的进入操作。我认为两者都可以。如果使用目标状态的条目操作,则需要关注事件类型。如果按如下方式编写处理程序,则处理程序将捕获所有事件。
template <class Event, class Fsm>
void on_entry(Event const& e, Fsm&) {
std::cout << "State2::on_entry()" << std::endl;
std::cout << "You can also set the property here." << std::endl;
property = e.data;
}
您可以按如下方式指定事件:
template <class Fsm>
void on_entry(Event1 const& e, Fsm&) {
std::cout << "State2::on_entry()" << std::endl;
std::cout << "You can also set the property here." << std::endl;
property = e.data;
}
为了解决后一个问题,如何避免重新计算,你需要在事件中将成员变量声明为可变的,如下所示:
struct Event1 {
mutable int data; // mutable is required because Event is passed as const&.
};
因为 Boost.MSM 将事件参数作为常量引用传递。
下面是描述如何在不重新计算的情况下设置目标状态属性的代码:
#include <iostream>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/static_assert.hpp>
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
// StateMachine [Sm]
//
// (initial)
// |
// V
// State1 --Event1[Guard1]/Action1--> State2
//
// ----- Events
struct Event1 {
mutable int data; // mutable is required because Event is passed as const&.
};
struct Sm_:msmf::state_machine_def<Sm_>
{
// States
struct State1:msmf::state<>
{
template <class Event,class Fsm>
void on_entry(Event const&, Fsm&) const {
std::cout << "State1::on_entry()" << std::endl;
}
template <class Event,class Fsm>
void on_exit(Event const&, Fsm&) const {
std::cout << "State1::on_exit()" << std::endl;
}
};
struct State2:msmf::state<>
{
template <class Event,class Fsm>
void on_entry(Event const& e, Fsm&) {
std::cout << "State2::on_entry()" << std::endl;
std::cout << "You can also set the property here." << std::endl;
property = e.data;
}
template <class Event,class Fsm>
void on_exit(Event const&, Fsm&) const {
std::cout << "State2::on_exit()" << std::endl;
}
int property;
};
// Set initial state
typedef State1 initial_state;
// Guards
struct Guard1 {
template <class Event, class Fsm, class Source, class Target>
bool operator()(Event const& e, Fsm&, Source&, Target&) const {
e.data *= 2; // calc
std::cout << "In Guard1, e.data *= 2. e.data=" << e.data << std::endl;
return true;
}
};
// Actions
struct Action1 {
template <class Event, class Fsm, class Source, class Target>
void operator()(Event const& e, Fsm&, Source&, Target& t) const {
std::cout << "In Action1, set target state property based on event data that is calculated in Guard1." << std::endl;
t.property = e.data;
}
};
// Transition table
struct transition_table:mpl::vector<
// Start Event Next Action Guard
msmf::Row < State1, Event1, State2, Action1, Guard1 >
> {};
};
// Pick a back-end
typedef msm::back::state_machine<Sm_> Sm;
void test()
{
Sm sm;
sm.start();
std::cout << "> Send Event1()" << std::endl;
Event1 e1;
e1.data = 12;
sm.process_event(e1);
}
int main()
{
test();
}
您可以使用在线编译器 Wandbox 编译、运行和修改代码。http://melpon.org/wandbox/permlink/L1HAjIiLU091906u
相关文章:
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++A*算法并不总是在路径中具有目标节点
- 基于树莓pi的tensorflow lite量化ssd目标检测
- 为测试目标创建具有不同源文件夹的文件
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- OSX MetalKit CVMetalTextureCacheCreateTextureFromImage失败,状态:
- 使用源向量作为目标
- 是否可以用C++/WinRT将windows 10.0.14393作为目标
- std::future_error:无关联状态
- 在 CMake 中为每个目标设置编译器/链接器标志
- qmake:检测目标位宽(32 位或 64 位)
- 如何避免LED在循环状态变化中闪烁?
- 如何在 CMake 中对目标依赖项进行分组?
- boost 是否有按特殊类型值编码状态"compact optional"?
- 我的目标是编写一个程序来计算和存储字符串在字符数组中出现的位置
- 如何为包含头文件的目标编写生成文件?
- 为什么系统函数总是在C++中返回已转移的退出状态?
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- boost::msm 用法:如何设置目标状态的属性