Question

I am having problems with my transition table and events. Let me explain the fake design that illustrates the problem:

I have a state machine (myStateMachine) containing 2 states (s0 and s1) and 1 substatemachine (subm1).

the substatemachine subm1 contains an initial state 'sub0' and also s1 (the same state as in myStateMachine).

this is the main transition table:

s0->s1 on event 'ES1'

s0->s2 on event 'ES2'

s0->subm1 on event 'ESUB'

this is the submachine transition table:

sub0->s1 on event 'ES1'

now, assume that state s1 is using the event that triggered it to extract some information i.e.

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

so every event that could transition to s1 needs to implement getEventData() method.

->this is normal!

now my problem is that ESUB does NOT implement getEventData() but apparently it should (compiler gives errors). And I don't get why.

I am not using ESUB to transition to s1 but I am using ESUB to transition to subm1 and subm1 contains s1 but I don't access it at that point.

I hope this is clear.

Was it helpful?

Solution

I HAVE RECEIVED AN ANSWER FROM THE DESIGNER OF BOOST MSM Christophe Henry:

"Hi,

this is an unfortunate limitation of msm (for composites), which I have on my list of stuff to solve asap. The problem is that though the event esub is not used to transition to s1, for the compiler it could. Whatever, it's my fault, plus I forgot it in the doc :(

The solution is to help the compiler a bit by enabling on_entry with evt.getEventData() only for events having a special property, like your es1. For example:

BOOST_MPL_HAS_XXX_TRAIT_DEF(get_event_data) 

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

Then use this in your state:

 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& ) 
   {    } 
   }; 

"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top