我已经在子状态机中定义了防护,现在我想在父级SM中使用确切的逻辑/防护(使用boost-msm)。在transition_table中使用相同的防护会导致编译错误:未知类型名称'GuardSS'。
我已经在子机中定义了防护(及其对应的值),但是如果可以帮助解决问题并允许我重用防护,则可以将其移至父级SM。
可以找到示例代码here。
如何重用防护中使用的代码?
包含代码:
#include <iostream>
#include "myfsm.h"
int main()
{
std::cout << "Testing boost::msm ..." << std::endl;
MyFsm fsm;
fsm.start();
fsm.process_event(Event12());
fsm.process_event(Event_ss12());
//guard valu changes
MyFsm_::State2 &state = fsm.get_state<MyFsm_::State2&>();
state.m_guardVal = true;
fsm.process_event(Event_ss12());
fsm.process_event(Event21());//?protect this transition using the same Guard
}
fsm.h:
#ifndef MYFSM
#define MYFSM
#include <iostream>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
struct Event12{};
struct Event21{};
struct Event_ss12{};
struct Event_ss21{};
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
struct MyFsm_ : msmf::state_machine_def<MyFsm_>
{
struct State1 : msmf::state<>{
template<class Event, class Fsm> void on_entry(const Event&, Fsm&) const {std::cout << "State1::on_entry()" << std::endl;}
template<class Event, class Fsm> void on_exit(const Event&, Fsm&) const {std::cout << "State1::on_exit()" << std::endl;}
};
struct State2_ : msmf::state_machine_def<State2_>{
template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const {std::cout << "State2::on_entry()" << std::endl;}
template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const {std::cout << "State1::on_exit()" << std::endl;}
struct SubState1 : msmf::state<> {
template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const {std::cout << "SubState1::on_entry()" << std::endl;}
template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const {std::cout << "SubState1::on_exit()" << std::endl;}
};
struct SubState2 : msmf::state<> {
template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const {std::cout << "SubState2::on_entry()" << std::endl;}
template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const {std::cout << "SubState2::on_exit()" << std::endl;}
};
// Guards
struct GuardSS {
template <class Event, class Fsm, class SourceState, class TargetState>
bool operator()(Event const&, Fsm& fsm, SourceState&, TargetState&)
{
if (fsm.m_guardVal == true){
std::cout << "Transition Approved by Guard \n";
return true;
}
std::cout << "Transition Rejected by Guard \n";
return false;
}
};
typedef SubState1 initial_state;
struct transition_table:mpl::vector<
// Start Event Next Action Guard
msmf::Row < SubState1, Event_ss12, SubState2, msmf::none, GuardSS >,
msmf::Row < SubState2, Event_ss21, SubState1, msmf::none, msmf::none >
> {};
bool m_guardVal=false;
};
typedef msm::back::state_machine<State2_> State2;
// Set initial state
typedef State1 initial_state;
// Transition table
struct transition_table:mpl::vector<
msmf::Row < State1, Event12, State2, msmf::none, msmf::none >,
msmf::Row < State2, Event21, State1, msmf::none, GuardSS/*msmf::none*/ >
>{};
template<class Event, class Fsm>
void no_transition(Event const&, Fsm&, int state){
std::cout<<"no_transiton detected from state: "<< state << std::endl;
}
};
// Pick a back-end
typedef msm::back::state_machine<MyFsm_> MyFsm;
#endif // MYFSM
答案 0 :(得分:0)
您需要将防护GuardSS
移到父状态MyFsm_
。因为MyFsm_
无法访问原始代码中的GuardSS
。
此外,您需要在bool m_guardVal=false;
中定义成员变量MyFsm_
。因为它是由GuardSS
引用的。
以下是更新的代码:
struct MyFsm_ : msmf::state_machine_def<MyFsm_>
{
// Guards (moved to parent from sub)
struct GuardSS {
template <class Event, class Fsm, class SourceState, class TargetState>
bool operator()(Event const&, Fsm& fsm, SourceState&, TargetState&)
{
if (fsm.m_guardVal == true){
std::cout << "Transition Approved by Guard \n";
return true;
}
std::cout << "Transition Rejected by Guard \n";
return false;
}
};
bool m_guardVal=false; // added
struct State1 : msmf::state<>{
// ... snip ...