我希望在状态和SM之间共享数据和访问权限以及客户端代码(即SM外部的代码)。
基于我在网上提出的内容,最好的方法是从基类继承所有状态。
添加基类并制作所有状态&从中继承的SM很简单,但是如何将处理程序作为此基类的成员添加到SM的后端/前端?如何初始化它?
此sample code编译,但在访问SubState中设置的fsmHandler时崩溃(SubState通常无法访问root fsm)!
问题:
如何在SM层次结构深处的子机器中访问root-SM及其数据?
Q1)如何解决运行时错误?
Q2)我如何将数据从客户端代码(SM外部)传递给SM感觉不对!有没有更好的方法呢?它是线程安全吗?
Q3)如何进行 typedef StateBase_<MyFsm_> StateBase
编译。
如果你能提供一份工作样本我真的很感激。 谢谢你的时间和提前帮忙。
代码:
的main.cpp
int main()
{
std::cout << "Testing boost::msm ..." << std::endl;
MyFsm fsm;
fsm.start();
MyFsm::State1& tempState = fsm.get_state<MyFsm::State1&>();
fsm.m_outerSMData=77;
tempState.m_fsmHandler = &fsm;
fsm.process_event(Event1());
fsm.process_event(Event2());
}
myfsm.h
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
struct Event1{};
struct Event2{};
template<class Fsm>
struct StateBase_{
//StateBase(Fsm *fsm):m_fsm(fsm){}
StateBase_(){}
~StateBase_(){}
Fsm *m_fsmHandler;
};
//typedef StateBase_<MyFsm_> StateBase;//How can I make this typedef work?
struct MyFsm_ : msmf::state_machine_def<MyFsm_, StateBase_<MyFsm_> >
{
struct State1 : msmf::state<StateBase_<MyFsm_>>{
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_, StateBase_>{
template<class Event, class Fsm> void on_entry(const Event&, Fsm&) const {std::cout << "State2::on_entry()" << std::endl;}
template<class Event, class Fsm> void on_exit(const Event&, Fsm&) const {std::cout << "State2::on_exit()" << std::endl;}
struct SubState21 : msmf::state<StateBase_>{
template<class Event, class Fsm>
void on_entry(const Event&, Fsm&) const {
std::cout << "SubState21::on_entry()"
<<"OuterSMData= "<<m_fsmHandler->m_outerSMData <<std::endl;
}
template<class Event, class Fsm>
void on_exit(const Event&, Fsm&) const {
std::cout << "SubState21::on_exit()" << std::endl;
}
};
typedef mpl::vector<SubState21> initial_state;
};
typedef msm::back::state_machine<State2_> State2;
// Set initial state
typedef State1 initial_state;
// Transition table
struct transition_table:mpl::vector<
msmf::Row < State1, Event1, State2, msmf::none, msmf::none >,
msmf::Row < State2, Event2, State1, msmf::none, 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;
}
//void setPtr(int data/*MyFsm_ &fsm*/){State1::m_baseData=10;}
int m_outerSMData=44;
};
// Pick a back-end
typedef msm::back::state_machine<MyFsm_> MyFsm;
答案 0 :(得分:1)
您可以从子状态访问外部状态机。 这是基于您的代码的状态机图。
+-------+--------------------------------------------------------+
| Fsm_ | member variable: m_outerSMData |
+-------+ |
| |
| * |
| | |
| V |
| +----------+ +-----------------------------------+ |
| | State1 | | State2 | |
| +----------+Event1+-----------------------------------+ |
| | |----->| on_entry/rootFsm=&f | |
| | | | member variable: rootFsm | |
| | | | +---------------------------+ | |
| | |Event2| | SubState21 | | |
| | |<-----| | | | |
| | | | | on_entry/ | | |
| | | | | access | | |
| | | | | f.rootFsm->m_outerSMData | | |
| | | | +---------------------------+ | |
| +----------+ +-----------------------------------+ |
+----------------------------------------------------------------+
为了访问外部状态机,State2__
必须具有指针MyFsm_
。因此,我添加了rootFsm
作为State2__
的成员变量,并在Stete2__::on_entry()
上将外部状态机的指针分配给它。
如果要在Stete2__::on_entry()
访问外部状态机的成员,则需要MyFsm_
的定义。因此,您需要将成员函数State2__::on_entry
的定义和定义分开。
这是实现目标的关键结构:
struct MyFsm_; // forward declaration
struct State2__ .... { // class definition
// member function template declaration
template<class Event, class Fsm> void on_entry(const Event&, Fsm& f);
MyFsm_* rootFsm;
};
struct MyFsm_ ... { // class definition
// requre State2__ definition here
};
// member function template definition
template<class Event, class Fsm> void State2__::on_entry(const Event&, Fsm& f) {
// requre MyFsm_ definition here
rootFsm = &f;
std::cout << "Print OuterSMData= " << rootFsm->m_outerSMData << std::endl;
}