增加事件和状态重用的msm问题

时间:2012-07-10 20:37:27

标签: c++ boost boost-msm

我的转换表和事件出现问题。 让我解释说明问题的虚假设计:

我有一个状态机(myStateMachine),包含2个状态(s0和s1)和1个子状态机(subm1)。

substatemachine subm1包含一个初始状态'sub0'和s1(与myStateMachine中的状态相同)。

这是主要的过渡表:

事件'ES1'

上的

s0-> s1 事件'ES2'上的

s0-> s2

事件'ESUB'上的

s0-> subm1

这是冲锋转换表:

事件'ES1'

上的

sub0-> s1

现在,假设状态s1正在使用触发它的事件来提取一些信息,即

struct s1 : public msm::front::state<>
{
   template <class Event,class FSM>
   void on_entry(Event const& evt,FSM& fsm)
   { 
      evt.getEventData();
   }
}

所以每个可以转换到s1的事件都需要实现getEventData()方法。

- &gt;这是正常的!

现在我的问题是ESUB没有实现getEventData()但显然它应该(编译器给出错误)。我不明白为什么。

我没有使用ESUB转换到s1,但是我使用ESUB转换到subm1,而subm1包含s1但是我当时没有访问它。

我希望这很清楚。

1 个答案:

答案 0 :(得分:1)

我收到了BOOST MSM Christophe Henry设计师的回答:

“嗨,

这是msm(对于复合材料)的一个不幸的限制,我有 我的问题列表尽快解决。问题是虽然事件esub是 不习惯过渡到s1,对于编译器来说也是如此。无论如何,这是我的 错,加上我忘了它在doc :(

解决方案是通过启用on_entry来帮助编译器 evt.getEventData()仅适用于具有特殊属性的事件,例如es1。 例如:

BOOST_MPL_HAS_XXX_TRAIT_DEF(get_event_data) 

// this event supports getEventData 
struct es1 
{ 
   typedef int get_event_data; 
   void getEventData(){...} 
 }; 

然后在你的州使用它:

 struct s1 : public msm::front::state<> 
 { 
   template <class Event,class FSM> 
   typename boost::enable_if<typename 
   has_get_event_data<Event>::type,void>::type 
   on_entry(Event const& evt,FSM& fsm) 
   { 
      evt.getEventData(); 
   } 
   // for events not supporting getEventData like esub 
   template <class Event,class FSM> 
   typename boost::disable_if<typename 
   has_get_event_data<Event>::type,void>::type 
   on_entry(Event const& ,FSM& ) 
   {    } 
   };