2015/09/12

[smc]イベント内容を定義していないとDefault

あたし一日中状態遷移のことばかり考えてる・・・と、いうわけでもないのだが、こういうのは勢いで調べておかないと。
というわけで、まだ状態遷移のsmcについてだ。

サンプルのsmファイルを見ると、各状態のイベントごとの動作が入っていないことがある。
たとえば、EX1はイベントで「Zero, One, Unknown, EOS」があるけど、OK状態のときにはどのイベントについても記述が無い。
さて、イベント内容を定義していないと何が起きるのだろう?

 

cygwinで実行させると、コアダンプした。
assertionログが出ているので、assert()が引っかかったようだ。
これは「Default」という特殊イベントが発生したのと同じことになるようである。

自動生成されたソースは、こうなっている。

static void AppClassState_Default(struct AppClassContext *const fsm)
{
    if (getDebugFlag(fsm) != 0) {
        TRACE("TRANSITION   : %s.%s\n", getName(getState(fsm)), getTransition(fsm));
    }
    State_Default(fsm);
}

そしてState_Default()は、statemap.hにあった。

#define State_Default(fsm) \
    assert(0)

あまり調べてないけど、たぶんこれが動いているのだろう。

 

では、自分で何も無いときの動作を定義したい場合はどうするかというと、2つあるようだ。
「Default状態」(Dは大文字)に遷移するか、「Defaultイベント」が発生するかだ。

じゃあ、両方書いた場合はどちらが優先されるのか?
やってみると、Default状態の方が実行された。
うーん、私のイメージでは、各状態に書かれたDefaultイベントの方が強い、だったのだが。

Zeros状態のZeroイベントを無くした状態で実行すると、こんな動きになっていた。

image

引数は"000"で、1番目の"0"でStart→Zerosに遷移後、次の"0"でZeroイベントを発行(AppClassContext_Zero())。
でも、そのときの遷移定義がないので、Map1_DefaultState_Zero()が実行されている(最後のAppClass_DefaultState()はActionとして実装した関数)。

Map1_DefaultState_Zero()はこんな感じで自動生成されていた。
赤文字が、Actionで実装した関数を呼んでいる箇所。

static void Map1_DefaultState_Zero(struct AppClassContext *const fsm)
{
    struct AppClass *ctxt = getOwner(fsm);
    const struct AppClassState* EndStateName = getState(fsm);
    if (getDebugFlag(fsm) != 0) {
        TRACE("LEAVING STATE   : Map1_DefaultState)\n");
    }
    if (getDebugFlag(fsm) != 0) {
        TRACE("ENTER TRANSITION: Map1_&Map1_DefaultState.Zero()\n");
    }
    clearState(fsm);
    AppClass_DefaultState(ctxt);
    if (getDebugFlag(fsm) != 0) {
        TRACE("EXIT TRANSITION : Map1_&Map1_DefaultState.Zero()\n");
    }
    setState(fsm, EndStateName);
}

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。