状態遷移のsmcは、使ってみればわかるだろう、と思っていたのだが、いきなり詰まった。
やりたいのは、A/D変換の結果によって遷移先を変えたいというもの。
ただ、その条件は状態によって違うのだ。
ありがちだと思うのだが、どこまでsmcでできるのだろうか?
状態に遷移するイベントを作って置いて、自分で状態ごとに値を判断してイベントを呼ぶ、というのは無しにしたい。
それだったら、普通に組んだ方がわかりやすいだろうし。
smcのページを見ていくと、タイトルとしてはこれが近いような気がする。
http://smc.sourceforge.net/SmcManSec2.htm#TransGuards
UMLのガードって、条件みたいなものではないか。
だから、条件による遷移、みたいな意味だったらよいと思ったのだ。
日本語だと「守る」って感じがしてしまうんだけどね。
ガードにはif文に書けるような条件を書いておけ、というように読める。
ただ、私がやりたいのは静的な条件では無く、状態によって変わる条件なのだ。
そういうのはどう表すのだろう?
コンテキストクラスのメソッドを呼びたいなら、ctxtを自分で付けろ、とある。
でも、Cだしなぁ。
というよりも、ctxtってなんだ?
thisみたいなものなら、引数にして渡してやれば同じことができるかもしれない。
どうやら、ctxtはコンテキストクラスを表す変数のようだ。
Cでのサンプルを見る限りでは、%classにつけた構造体名がそれに当たりそうだ。
では、試してみよう。
extern int AppClass_IsAcceptable(struct AppClass *this);
こんなヘッダをAppClass.hに書き、ソースにはこう。
int AppClass_IsAcceptable(struct AppClass *this){return this->isAcceptable;
}
特に意味はない関数なのだけど、サンプルソースで使えそうなのを入れてみただけだ。
そして、smファイルは
Zero [AppClass_IsAcceptable(ctxt)] Zeros {}
遷移条件なので、遷移先の前に書くのだろう。
これは、Start状態のZeroイベントに書いたのだが、AppClass_sm.cにはこう反映されていた。
static void Map1_Start_Zero(struct AppClassContext *const fsm){struct AppClass *ctxt = getOwner(fsm);
if (AppClass_IsAcceptable(ctxt)) {
/* No actions. */
setState(fsm, &Map1_Zeros);}else {
Map1_DefaultState_Zero(fsm);}}
AppClass_IsAcceptable()が真ならばZerosに遷移するし、そうでなければ・・・デフォルト状態?に遷移するようだ。
なので、Context Classを表す構造体のメンバに、判断する材料を全部突っ込んでおけばよいということになるか。
でも、C++みたいにvirtualで持つわけではないので、もうちょっとうまいことやらないと作業が楽にならないな。
状態を表すint型の0から始まる変数があって、それを添字にして関数を用意する、みたいなのが楽なんだけど、そういう感じでもなさそうだ。
そもそも、AppClassState構造体は状態ごとに別の実装を持てるようになっていそうだから、間借りさせてくれるとよいのだが。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。