C++ msm用法:如何设置目标状态的属性
我的fsm中的状态具有不同的属性。我定义了一个事件,它将调用到目标状态的转换。我想按事件数据设置目标的属性。我的选择是: 1.在操作或保护中设置属性:但仍处于源状态。如果当时设置了目标状态属性,则填充不好 2.在目标条目中设置属性:但是属性的值在收到事件时已在guard中计算,因此我应该重新计算:(C++ msm用法:如何设置目标状态的属性,c++,boost,C++,Boost,我的fsm中的状态具有不同的属性。我定义了一个事件,它将调用到目标状态的转换。我想按事件数据设置目标的属性。我的选择是: 1.在操作或保护中设置属性:但仍处于源状态。如果当时设置了目标状态属性,则填充不好 2.在目标条目中设置属性:但是属性的值在收到事件时已在guard中计算,因此我应该重新计算:( 任何人都可以给我更多的想法。谢谢!我不确定您的情况,但我认为您有两个不同的问题。一个是设置目标状态属性的最佳位置。另一个是如何避免重新计算 让我们考虑前一个问题。正如你提到的,有两个候选者。它们是一
任何人都可以给我更多的想法。谢谢!我不确定您的情况,但我认为您有两个不同的问题。一个是设置目标状态属性的最佳位置。另一个是如何避免重新计算
让我们考虑前一个问题。正如你提到的,有两个候选者。它们是一个过渡动作和一个目标状态的进入动作。我认为两者都可以。如果使用目标状态的入口动作,则需要关心事件类型。如果编写如下的处理程序,所有事件都会被处理程序捕获。
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;
}
因为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();
}
#包括
#包括
#包括
#包括
#包括
名称空间msm=boost::msm;
名称空间msmf=boost::msm::front;
名称空间mpl=boost::mpl;
//状态机[Sm]
//
//(首字母)
// |
//五
//状态1—事件1[Guard1]/Action1-->状态2
//
//----事件
结构事件1{
mutable int data;//需要mutable,因为事件作为常量传递。
};
结构Sm:msmf::状态机定义
{
//州
结构State1:msmf::state
{
模板
输入时无效(事件常量,Fsm&)常量{
std::cout我不确定您的情况,但我认为您有两个不同的问题。一个是设置目标状态属性的最佳位置。另一个是如何避免重新计算
让我们考虑前一个问题。正如你提到的,有两个候选者。它们是一个过渡动作和一个目标状态的进入动作。我认为两者都可以。如果使用目标状态的入口动作,则需要关心事件类型。如果编写如下的处理程序,所有事件都会被处理程序捕获。
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;
}
因为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();
}
#包括
#包括
#包括
#包括
#包括
名称空间msm=boost::msm;
名称空间msmf=boost::msm::front;
名称空间mpl=boost::mpl;
//状态机[Sm]
//
//(首字母)
// |
//五
//状态1—事件1[Guard1]/Action1-->状态2
//
//----事件
结构事件1{
mutable int data;//需要mutable,因为事件作为常量传递。
};
结构Sm:msmf::状态机定义
{
//州
结构State1:msmf::state
{
模板
输入时无效(事件常量,Fsm&)常量{
你的代码解决了我的问题。非常感谢。你的代码解决了我的问题。非常感谢。