boost::msm
昨日の続きです。
実際にステートチャート図を書きながらやってみました。
#include <iostream> #include <boost/msm/back/state_machine.hpp> #include <boost/msm/front/state_machine_def.hpp> namespace msm = boost::msm; namespace mpl = boost::mpl; // 状態 namespace states{ struct opening : public msm::front::state<>{}; struct menu : public msm::front::state<>{}; struct demo : public msm::front::state<>{}; struct char_select : public msm::front::state<>{}; } // namespace state // イベント namespace event{ struct push_start_button{}; struct opening_end{}; struct menu_time_up{}; struct demo_end{}; struct game_start{}; } // namespace event // ゲームの状態を管理 struct game_ : public msm::front::state_machine_def<game_>{ // 状態遷移のリスト struct transition_table : mpl::vector< // Start Event Next _row<states::opening, event::push_start_button, states::menu>, _row<states::opening, event::opening_end, states::menu>, _row<states::menu, event::menu_time_up, states::demo>, _row<states::menu, event::game_start, states::char_select>, _row<states::demo, event::demo_end, states::opening>, _row<states::demo, event::push_start_button, states::menu> >{}; // 最初の状態 typedef states::opening initial_state; // イベントが見つからなかった時に呼ばれる template <class FSM,class Event> void no_transition(Event const& e, FSM&,int state) { std::cout << "no transition from state " << state << " on event " << typeid(e).name() << std::endl; } }; typedef msm::back::state_machine<game_> game; int main(){ game g; g.start(); g.process_event(event::opening_end()); // states::opening -> states::menu g.process_event(event::menu_time_up()); // states::menu -> states::demo g.process_event(event::demo_end()); // states::demo -> states::opening g.process_event(event::push_start_button()); // states::opening -> states::menu g.process_event(event::game_start()); // states::menu -> states::char_select return 0; }
動きとしては、ステートチャート図の流れを mpl::vector で定義して、
設定したイベントを呼んでやるとその通りに状態が変更されます。
実際にステートチャート図があるとかなり分かりやすい。
今回はやってませんが、状態が変更された時に呼ばれる関数とかも設定出来るみたいです。
ついでに no_transition を定義しておかないと 不正なイベントが呼ばれた場合に、
実行時に吹っ飛んでいくので注意。
まだ骨組みしか出来ていないので、
ここからどうやって拡張していくか悩みどころ。
まぁしかし、大体の流れはつかめたと思います。
コメント欄のアドバイスに感謝。
[boost]
ver 1.44.0
[参照]
http://botamocci.posterous.com/boost-meta-state-machine