1

遷移テーブルとイベントに問題があります。問題を説明する偽のデザインを説明しましょう。

2 つのステート (s0 と s1) と 1 つのサブステートマシン (subm1) を含むステート マシン (myStateMachine) があります。

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() メソッドを実装する必要があります。

→これが当たり前!

今私の問題は、ESUB が getEventData() を実装していないことですが、明らかにそうすべきです (コンパイラがエラーを出します)。理由がわかりません。

ESUB を使用して s1 に移行していませんが、ESUB を使用して subm1 に移行しており、subm1 には s1 が含まれていますが、その時点ではアクセスしていません。

これが明確であることを願っています。

4

1 に答える 1

2

BOOST MSM Christophe Henry のデザイナーから回答を受け取りました。

"やあ、

これは、msm (コンポジットの場合) の残念な制限であり、できるだけ早く解決する必要があるもののリストに含まれています。問題は、イベント esub は s1 への遷移に使用されませんが、コンパイラーにとっては可能であるということです。とにかく、それは私のせいです。さらに、ドキュメントで忘れてしまいました:(

解決策は、es1 のような特別なプロパティを持つイベントに対してのみ evt.getEventData() で on_entry を有効にすることにより、コンパイラを少し支援することです。例えば:

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

"

于 2012-09-28T16:26:30.807 に答える