サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]
「State Map Compiler」という記事の例をBoost.Statechartで書いてみました。
「お金を入れたら一人だけ通過できる門」を実装しましょうというお題で… 門には「通過してOK(Unlocked)」な状態と「通過しちゃだめ(Locked)」の2つの状態があります。 Locked状態でお金を入れる(Coin)とUnlocked状態に移って、逆に、Unlocked状態で人が一人通る(Pass)と、 Locked状態に移ります。Locked状態なのに強行突破するバカ者がいる(Pass)と、Alarmアクションを実行。 Unlocked状態でさらにお金を入れてくれる人がいたら感謝します(Thankyou)。
#include <iostream>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/in_state_reaction.hpp>
#include <boost/mpl/list.hpp>
using namespace std;
using namespace boost::statechart;
// 状態
struct Locked;
struct Unlocked;
// イベント
struct Coin : event<Coin> {};
struct Pass : event<Pass> {};
// 状態マシン "Gate" : 初期状態はLocked
struct Gate : state_machine<Gate, Locked> {};
// Locked状態の定義
struct Locked : simple_state<Locked, Gate>
{
void Alarm( const Pass& ) { cout << "ALARM!!!" << endl; }
// Coinイベントが発生したらUnlock状態に遷移
// Passイベントが発生したらAlarmアクションを実行
typedef boost::mpl::list<
transition < Coin, Unlocked >,
in_state_reaction< Pass, Locked, &Locked::Alarm >
> reactions;
};
// Unlocked状態の定義
struct Unlocked : simple_state<Unlocked, Gate>
{
void Thankyou( const Coin& ) { cout << "Thank you :)" << endl; }
// Coinイベントが発生したらThankyouアクションを実行
// Passイベントが発生したらLocked状態に遷移
typedef boost::mpl::list<
in_state_reaction< Coin, Unlocked, &Unlocked::Thankyou >,
transition < Pass, Locked >
> reactions;
};
// てすと
int main()
{
Gate g;
g.initiate();
g.process_event( Coin() );
g.process_event( Pass() );
g.process_event( Pass() ); // ALARM!!!
g.process_event( Coin() );
g.process_event( Coin() ); // Thank you :)
}
とまあ、こんな雰囲気で状態マシンを実装するライブラリです。 状態空間の階層化や、状態ローカルの変数を持たせるなど、色々できます。
boostライブラリによるSEMIスタンダードの実装 に実際の使用例などが紹介されています。