4

ステートマシンを作成し、次のようなインターフェイスを使用したい場合:

AddState ( state1, state2, Key_UP );
AddEvent ( Key_UP );
AddEventFunction ( Key_UP, &UP_Function);
AddStateFunction ( state1, &State1_In_Function, &State1_Out_Function);
AddStateFunction ( state2, &State2_In_Function, &State2_Out_Function);

State1_In_Function  ( void ) { printf ( "In #1 \n" ); }
State1_Out_Function ( void ) { printf ( "Out #1 \n" ); }
State2_In_Function  ( void ) { printf ( "In #2 \n" ); }
State2_Out_Function ( void ) { printf ( "Out #2 \n" ); }
UP_Function         ( void ) { printf ( "Goin UP \n" ); }

そうすれば、私がstate1にいて、FSMがKey_UPを受信すると、プログラムは次のように出力します。

Out #1
Goin UP
In #2

問題は、プログラマーが配列サイズを変更する必要なしに、状態と遷移情報をクラス内に格納する方法です。2D配列を使用して、通常のように状態テーブルにし、移植性を高めるために、必要に応じてベクトル型を使用してサイズを変更することで、イベントと状態の追加を処理できると考えていました。ベクトルの問題は、多くの組み込みデバイスがメモリ割り当て呼び出しを使用できないことです。2番目のオプションは、ステートマシンでコンストラクターを呼び出し、テーブルに必要なサイズを渡すことですが、新しい状態やイベントを追加する場合は、これらの値も変更する必要があります...

では、状態、イベント、関数ポインタをどのように保存すればよいのでしょうか。

4

3 に答える 3

3

少し難しいですが、単にスタックに保存することもできます:)

それでも、それは面白い解決策なので、ここに行きます。基本的な原則は、デコレータと可変性で遊ぶことです。コードの例:

State state1, state2; // creates a state
Event KEY_UP;
Event KEY_DOWN;

Transition t0(state1, KEY_UP, state2);
Transition t1(state2, KEY_DOWN, state1);

それはどのように機能しますか?

「単純な」オブジェクトではなくstate1、少し複雑になります。何かのようなもの:

struct State;

struct StateImpl {
  StateImpl(char const* n): name(n) {}
  char const* name;
};

struct StateNode {
  StateNode(Event e, State const& s, StateNode const* n):
    event(e), state(s), next(n) {}

  Event event;
  State const& destination;
  StateNode const* next;
};

struct State {
  State(char const* name):
    me(0), impl(name) {}

  StateNode const* me;
  StateImpl impl;
};

そして、:を定義しますTransition

struct Transition {
  Transition(State& origin, Event e, State const& destination):
    node(e, destination, origin.me)
  {
    origin.me = node;
  }
  StateNode node;
};

非公式には、頭をに置いた単一リンクリストを作成していStateます。トランジションを追加するたびにヘッドを更新します。

イベントが発生すると、イベントが発生して適切にディスパッチされるか、nullポインターに到達して、この状態でイベントが受信されていないことを示すまで、このリストをたどる必要があります。

于 2011-07-22T06:55:53.233 に答える
0

Boost.StateChartを確認し、必要に応じて、必要なAPIを使用してその周りに薄いレイヤーを構築することをお勧めします。

これで、適切なデータ構造を設計する必要がなくなります。

于 2011-07-22T06:30:01.360 に答える
0

ちなみに、あなたはかわいくなり、このようにすることができます。

于 2011-07-22T12:22:03.517 に答える