boostsapporomsmpre 111030054504-phpapp02
TRANSCRIPT
自己紹介
近藤 貴俊
BLOG http://d.hatena.ne.jp/redboltz/
twitter @redboltz
C++標準化委員会メンバ
技術士(情報工学部門)
GCJJ Tシャツ圏内
Copyright 2011 Takatoshi Kondo All rights reserved
2/95
目次
• StateMachineとは
• Boost Meta State Machine Library
• ATMを題材としたケーススタディ
• StateMachineDiagram(UML2.x)への対応状況
Copyright 2011 Takatoshi Kondo All rights reserved
4/95
StateMachineとは
State Machine
Event [Output]
Event Driven Outputは、あったりなかったり
EventA EventA
Outupt1
Outupt2
同じEventでも Outputが変わったり
中身は、 と
Copyright 2011 Takatoshi Kondo All rights reserved
5/95
StateMachineの構成要素
State1
event [ guard ] / action
entry / action do / action exit / action event [ guard ] / action
Copyright 2011 Takatoshi Kondo All rights reserved
6/95
StateMachineの構成要素
State1
event [ guard ] / action
状態 遷移
entry / action do / action exit / action event [ guard ] / action
Copyright 2011 Takatoshi Kondo All rights reserved
7/95
StateMachineの構成要素
State1
event [ guard ] / action
Output
Event
entry / action do / action exit / action event [ guard ] / action
Copyright 2011 Takatoshi Kondo All rights reserved
8/95
遷移 Transition State1 State2 event [ guard ] / action
遷移元状態(State1)において、eventが発生した際、 guardが成立していれば、遷移先状態(State2)に遷移する。 遷移の際、actionを実行する。
event guard action は、いずれもoptional
• guard記述がなければ、eventが発生した際、無条件に 遷移先状態に遷移する。
• action記述がなければ、遷移の際、特に何も実行しない。
• event記述が無い場合の意味論は後述
Copyright 2011 Takatoshi Kondo All rights reserved
9/95
内部遷移 Internal Transition State1
event [ guard ] / action
遷移先状態を指定しない遷移。状態遷移は発生しない。 状態の内部に記述する(UMLの表記法) あるEvent発生時、guardに応じてactionを実行することを 目的として記述される。
遷移しない遷移なんだから、actionを書かないと意味がない
Copyright 2011 Takatoshi Kondo All rights reserved
10/95
遷移 Transition State1 State2 event [ guard ] / action
event記述がなければ、 トリガとなったevent処理のなかで本遷移が評価される。
State1 State2
Guardが成立するまで待って、 成立したら遷移ではないので注意
Event1
Event1の発生でState2まで遷移する
State1 State2 Event1 [G1]
E2/G1=true
G1がfalseならState1まで遷移して待ち状態になる その後、eventによらず、G1がtrueになっても遷移は発生しない
E2が発生したらState2に遷移する
Copyright 2011 Takatoshi Kondo All rights reserved
11/95
状態 State
状態名
entry/action1 do/action2 exit/action3 event[guard]/action4
(普通の)状態 Composite State
この状態に遷移する際に実行されるentry action
この状態から遷移する際に実行されるexit action
その状態の間常に実行されるdo action Event Drivenなソフトウェアではあまり使わない サブマシン状態を持つという記号
include / 他の状態マシン
内部に持つサブマシン名
内部遷移(前述)
Boost.Msmでもサポートしない
Copyright 2011 Takatoshi Kondo All rights reserved
12/95
その他の構成要素 初期疑似状態 Initial Pseudo State
終了状態 Final State
ジャンクション疑似状態 Junction Pseudo State 見た目が初期疑似状態と一緒って。。。
選択疑似状態 Choice Pseudo State
State entry point疑似状態 Entry Point Pseudo State
exit point疑似状態 Exit Point Pseudo State
State
State
State
fork join H
H *
shallow history
deep history
本プレゼンでは ちょっと小さめに書きます
Copyright 2011 Takatoshi Kondo All rights reserved
13/95
参考文献
http://www.wisdom.weizmann.ac.il/~dharel/reactive_systems.html
絶版だが、以下のご本人サイトから PDFダウンロード可能
元々のStatechart
http://www.uml.org/
Current version: 2.4 (Beta)
UML2.xのStateMachineDiagramとして拡張
Copyright 2011 Takatoshi Kondo All rights reserved
14/95
Boost.Msmとは?
State
状態遷移を司るライブラリです
外部からのeventをキューイングしたり
スレッドでイベントループを実現したり
しません
内部のeventはキューイング されるけど
Copyright 2011 Takatoshi Kondo All rights reserved
15/95
Boost.Msmとは?
• そういう外回り?のことは、 Boost.AsioやBoost.Threadなんかで やってください
• 逆にいえば、Threadなしの周期モデル (組み込み開発などでよくある) でも使うことができます
Copyright 2011 Takatoshi Kondo All rights reserved
16/95
Boost.Msm
#include <boost/msm/back/state_machine.hpp> #include <boost/msm/front/state_machine_def.hpp> #include <boost/msm/front/functor_row.hpp>
namespace msm = boost::msm; namespace msmf = boost::msm::front; namespace mpl = boost::mpl;
struct Event1 {}; struct Event2 { int param1; int param2; };
eventはクラスで表現
パラメタはメンバとして
Copyright 2011 Takatoshi Kondo All rights reserved
17/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm StateMachineの定義
状態の定義
guardの定義
actionの定義 初期状態の定義(必須)
遷移の定義
eventに対応する遷移がないときの処理
Copyright 2011 Takatoshi Kondo All rights reserved
18/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm StateMachineの定義
Copyright 2011 Takatoshi Kondo All rights reserved
19/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm
状態の定義
State1
entry/on_entry exit/on_exit
名前は予約されている
名前は予約されている
Copyright 2011 Takatoshi Kondo All rights reserved
20/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm
State1
entry/on_entry exit/on_exit
遷移トリガとなったeventの参照
状態マシンSm_の参照
Copyright 2011 Takatoshi Kondo All rights reserved
21/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm
boolをreturn
guardの定義
Copyright 2011 Takatoshi Kondo All rights reserved
22/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm
guardの定義
boolをreturn
event, 状態マシン, 遷移元state, 遷移先state にアクセス可能
Copyright 2011 Takatoshi Kondo All rights reserved
23/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm
actionの定義
event, 状態マシン, 遷移元state, 遷移先state にアクセス可能
Copyright 2011 Takatoshi Kondo All rights reserved
24/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm
初期状態の定義(必須)
State1
Copyright 2011 Takatoshi Kondo All rights reserved
25/95
initial_stateの役割 State1
State1A
State1B
folk
join
State1C
E1
E1 E2
リージョン0
リージョン1 リージョンとは、状態を持つ単位 この例では、State1AかつState1Bといった状態が存在する
Copyright 2011 Takatoshi Kondo All rights reserved
26/95
initial_stateの役割 State1
State1A
State1B
folk
join
State1C
E1
E1 E2
リージョン0
リージョン1 リージョンとは、状態を持つ単位 この例では、State1AかつState1Bといった状態が存在する
typedef mpl::vector<State1A, State1B> initial_state;
Boost.MSMでは、initial_stateのtypedefをリージョンの表現に(も)利用する
1個の場合mpl::vectorじゃなくてもいい
この並びがリージョン番号
Copyright 2011 Takatoshi Kondo All rights reserved
27/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm
遷移の定義
State1 State2 Event1 [ Guard1 ] / Action1
Copyright 2011 Takatoshi Kondo All rights reserved
28/95
state番号と評価順序
struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 >, msmf::Row < State2, Event2, State1, Action1, Guard1 >, msmf::Row < State2, Event2, State3, Action1, Guard1 >, msmf::Row < State5, Event3, State6, Action1, Guard1 >, msmf::Row < State4, Event4, State2, Action1, Guard1 > > {};
0
1
2
3
4
5
State番号の振られ方 遷移の評価順序
Copyright 2011 Takatoshi Kondo All rights reserved
29/95
state番号と評価順序
struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 >, msmf::Row < State2, Event2, State1, Action1, Guard1 >, msmf::Row < State2, Event2, State3, Action1, Guard1 >, msmf::Row < State5, Event3, State6, Action1, Guard1 >, msmf::Row < State4, Event4, State2, Action1, Guard1 > > {};
State番号の振られ方 遷移の評価順序
State2においてEvent2が発生した際 2つの遷移条件が成立するが、下の方が
評価順序の結果、優先される
Copyright 2011 Takatoshi Kondo All rights reserved
30/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm
eventに対応する遷移がないときの処理
定義しないとassertion fail
State番号 Copyright 2011 Takatoshi Kondo All rights reserved
31/95
struct Sm_:msm::front::state_machine_def<Sm_> { struct State1:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) {} template <class Event,class Fsm> void on_exit(Event const&, Fsm&) {} }; struct State2:msm::front::state<> { }; struct Guard1 { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; struct Action1 { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {} }; typedef State1 initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, Action1, Guard1 > > {}; template <class Fsm,class Event> void no_transition(Event const& e, Fsm& ,int state) {} };
Boost.Msm StateMachineの定義
状態の定義
guardの定義
actionの定義 初期状態の定義(必須)
遷移の定義
eventに対応する遷移がないときの処理
Copyright 2011 Takatoshi Kondo All rights reserved
32/95
ATMを題材としたケーススタディ
• StateMachineの階層化
• StateMachineのインターフェースと 実装の分離
• 複数の entry point疑似状態の使い分け
• サブStateMachineから親StateMachineへのEventの伝搬
• guardによるif/else分岐
Copyright 2011 Takatoshi Kondo All rights reserved
34/95
1.ATM(全体)
接客中 待機中
entry/画面消去 人物感知
人物離脱感知
include / 取引
全体
Copyright 2011 Takatoshi Kondo All rights reserved
36/95
1.ATM(全体)
接客中 待機中
entry/画面消去 人物感知
人物離脱感知
include / 取引
全体
内部がサブStateMachineであることを示す記号
サブStateMachine
ちなみに、UML的にはサブマシン状態という
Copyright 2011 Takatoshi Kondo All rights reserved
37/95
1.ATM(全体)
接客中 待機中
entry/画面消去 人物感知
人物離脱感知
include / 取引
全体
内部状態に手を加えずにキャンセル系処理を実現
この中がどんな状態でも脱出できるということ Copyright 2011 Takatoshi Kondo All rights reserved
38/95
2.ATM(取引)
引き出し選択 include / 引き出し
取引選択中
entry/取引選択画面提示
引き出し中
entry exit
取引
カード挿入 entry_by_card
その他選択 省略
Copyright 2011 Takatoshi Kondo All rights reserved
39/95
2.ATM(取引)
引き出し選択 include / 引き出し
取引選択中
entry/取引選択画面提示
引き出し中
entry exit
取引
カード挿入 entry_by_card
その他選択 省略
取引単位などで、階層化、モジュール化
Copyright 2011 Takatoshi Kondo All rights reserved
40/95
2.ATM(取引)
引き出し選択 include / 引き出し
取引選択中
entry/取引選択画面提示
引き出し中
entry exit
取引
カード挿入 entry_by_card
その他選択 省略
複数のentry point
Copyright 2011 Takatoshi Kondo All rights reserved
41/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
Copyright 2011 Takatoshi Kondo All rights reserved
42/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
カード挿入済みの場合
Copyright 2011 Takatoshi Kondo All rights reserved
43/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
引き出し以外の取引でも 利用可能(振り込みとか)
Copyright 2011 Takatoshi Kondo All rights reserved
44/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
生体認証で実現
認証というインターフェース
Copyright 2011 Takatoshi Kondo All rights reserved
45/95
3.ATM(引き出し)
include / パスワード認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
実現方法の差し替え
Copyright 2011 Takatoshi Kondo All rights reserved
46/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
ジャンクション疑似状態による if / else 分岐
Copyright 2011 Takatoshi Kondo All rights reserved
47/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報 内部遷移
Copyright 2011 Takatoshi Kondo All rights reserved
48/95
4.ATM(認証) entry
exit_success
exit_fail
指検出
認証失敗
認証成功(アカウント情報)
生体認証
認証中
entry/認証中画面提示, 認証開始
指待ち
entry/指要求画面提示
タイムアウト
アカウント情報
Copyright 2011 Takatoshi Kondo All rights reserved
49/95
4.ATM(認証) entry
exit_success
exit_fail
指検出
認証失敗
認証成功(アカウント情報)
生体認証
認証中
entry/認証中画面提示, 認証開始
指待ち
entry/指要求画面提示
タイムアウト
アカウント情報
合流にも使える ジャンクション疑似状態
Copyright 2011 Takatoshi Kondo All rights reserved
50/95
4.ATM(認証) entry
exit_success
exit_fail
指検出
認証失敗
認証成功(アカウント情報)
生体認証
認証中
entry/認証中画面提示, 認証開始
指待ち
entry/指要求画面提示
タイムアウト
アカウント情報
アカウント情報を ステートマシン外部へ渡す
Copyright 2011 Takatoshi Kondo All rights reserved
51/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
イベントは存在しないが、 Boost.Msmでは伝搬用イベントを定義可能
Copyright 2011 Takatoshi Kondo All rights reserved
52/95
1.ATM(全体)
接客中 待機中
entry/画面消去 人物感知
人物離脱感知
include / 取引
全体
Copyright 2011 Takatoshi Kondo All rights reserved
54/95
2.ATM(取引)
引き出し選択 include / 引き出し
取引選択中
entry/取引選択画面提示
引き出し中
entry exit
取引
カード挿入 entry_by_card
その他選択 省略
Copyright 2011 Takatoshi Kondo All rights reserved
55/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
Copyright 2011 Takatoshi Kondo All rights reserved
56/95
4.ATM(認証) entry
exit_success
exit_fail
指検出
認証失敗
認証成功(アカウント情報)
生体認証
認証中
entry/認証中画面提示, 認証開始
指待ち
entry/指要求画面提示
タイムアウト
アカウント情報
Copyright 2011 Takatoshi Kondo All rights reserved
57/95
3.ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
Copyright 2011 Takatoshi Kondo All rights reserved
58/95
2.ATM(取引)
引き出し選択 include / 引き出し
取引選択中
entry/取引選択画面提示
引き出し中
entry exit
取引
カード挿入 entry_by_card
その他選択 省略
Copyright 2011 Takatoshi Kondo All rights reserved
59/95
ATM(全体)
接客中 待機中
entry/画面消去 人物感知
人物離脱感知
include / 取引
全体
Copyright 2011 Takatoshi Kondo All rights reserved
61/95
ATM(全体) #include "atm_trade.hpp" namespace Atm { struct HumanDetect {}; struct HumanAway {}; struct All_:msm::front::state_machine_def<All_> { struct Waiting:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Clear Screen" << std::endl; } }; struct InService:Trade {}; typedef Waiting initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Waiting, HumanDetect, InService, msmf::none, msmf::none >, msmf::Row < InService, HumanAway, Waiting, msmf::none, msmf::none > > {}; }; typedef msm::back::state_machine<All_> All; }
Copyright 2011 Takatoshi Kondo All rights reserved
62/95
ATM(全体) #include "atm_trade.hpp" namespace Atm { struct HumanDetect {}; struct HumanAway {}; struct All_:msm::front::state_machine_def<All_> { struct Waiting:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Clear Screen" << std::endl; } }; struct InService:Trade {}; typedef Waiting initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Waiting, HumanDetect, InService, msmf::none, msmf::none >, msmf::Row < InService, HumanAway, Waiting, msmf::none, msmf::none > > {}; }; typedef msm::back::state_machine<All_> All; }
サブStateMachineは継承
Copyright 2011 Takatoshi Kondo All rights reserved
63/95
ATM(全体) #include "atm_trade.hpp" namespace Atm { struct HumanDetect {}; struct HumanAway {}; struct All_:msm::front::state_machine_def<All_> { struct Waiting:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Clear Screen" << std::endl; } }; struct InService:Trade {}; typedef Waiting initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Waiting, HumanDetect, InService, msmf::none, msmf::none >, msmf::Row < InService, HumanAway, Waiting, msmf::none, msmf::none > > {}; }; typedef msm::back::state_machine<All_> All; }
front_endとの対応付け
back_endとの対応付け
Copyright 2011 Takatoshi Kondo All rights reserved
64/95
ATM(全体) namespace Atm { struct HumanDetect {}; struct HumanAway {}; template <class AuthMethod> struct All_:msm::front::state_machine_def<All_<AuthMethod> > { // States struct Waiting:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Clear Screen" << std::endl; } }; struct InService:Trade<AuthMethod> {}; typedef Waiting initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Waiting, HumanDetect, InService, msmf::none, msmf::none >, msmf::Row < InService, HumanAway, Waiting, msmf::none, msmf::none > > {}; }; template <class AuthMethod> struct All:msm::back::state_machine<All_<AuthMethod> > {}; }
C++11なら template <class AuthMethod> using All = msm::back::state_machine<All_<AuthMethod>>;
認証の実装を差し替えるためにテンプレート化する
struct All_:msm::front::state_machine_def<All_>
typedef msm::back::state_machine<All_> All;
Copyright 2011 Takatoshi Kondo All rights reserved
65/95
ATM(取引)
引き出し選択 include / 引き出し
取引選択中
entry/取引選択画面提示
引き出し中
entry exit
取引
カード挿入 entry_by_card
その他選択 省略
Copyright 2011 Takatoshi Kondo All rights reserved
66/95
#include "atm_withdraw.hpp" #include "atm_card_detect.hpp" namespace Atm { struct ChooseWithdraw {}; template <class AuthMethod> struct Trade_:msm::front::state_machine_def<Trade_<AuthMethod> > { struct Choosing:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "1.Withdraw, 2.N/A, 3.N/A ..." << std::endl; } }; struct Withdrawing:Withdraw<AuthMethod> {}; typedef Choosing initial_state;
ATM(取引)
続く
Copyright 2011 Takatoshi Kondo All rights reserved
67/95
#include "atm_withdraw.hpp" #include "atm_card_detect.hpp" namespace Atm { struct ChooseWithdraw {}; template <class AuthMethod> struct Trade_:msm::front::state_machine_def<Trade_<AuthMethod> > { struct Choosing:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "1.Withdraw, 2.N/A, 3.N/A ..." << std::endl; } }; struct Withdrawing:Withdraw<AuthMethod> {}; typedef Choosing initial_state;
ATM(取引)
続く
認証を実現するテンプレート引数を伝搬
Copyright 2011 Takatoshi Kondo All rights reserved
68/95
ATM(取引)
typedef typename Withdrawing::template entry_pt<typename Withdraw_<AuthMethod>::Entry> WithdrawEntry; typedef typename Withdrawing::template entry_pt<typename Withdraw_<AuthMethod>::EntryByCard> WithdrawEntryByCard; typedef typename Withdrawing::template exit_pt <typename Withdraw_<AuthMethod>::Exit> WithdrawExit; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Choosing, ChooseWithdraw, WithdrawEntry, msmf::none, msmf::none >, msmf::Row < Choosing, CardDetect, WithdrawEntryByCard, msmf::none, msmf::none >, msmf::Row < WithdrawExit, msmf::none, Choosing, msmf::none, msmf::none > > {}; }; template <class AuthMethod> struct Trade:msm::back::state_machine<Trade_<AuthMethod> > {}; }
Copyright 2011 Takatoshi Kondo All rights reserved
69/95
ATM(取引)
typedef typename Withdrawing::template entry_pt<typename Withdraw_<AuthMethod>::Entry> WithdrawEntry; typedef typename Withdrawing::template entry_pt<typename Withdraw_<AuthMethod>::EntryByCard> WithdrawEntryByCard; typedef typename Withdrawing::template exit_pt <typename Withdraw_<AuthMethod>::Exit> WithdrawExit; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Choosing, ChooseWithdraw, WithdrawEntry, msmf::none, msmf::none >, msmf::Row < Choosing, CardDetect, WithdrawEntryByCard, msmf::none, msmf::none >, msmf::Row < WithdrawExit, msmf::none, Choosing, msmf::none, msmf::none > > {}; }; template <class AuthMethod> struct Trade:msm::back::state_machine<Trade_<AuthMethod> > {}; }
認証を実現するテンプレート引数を伝搬
Copyright 2011 Takatoshi Kondo All rights reserved
70/95
ATM(取引)
typedef typename Withdrawing::template entry_pt<typename Withdraw_<AuthMethod>::Entry> WithdrawEntry; typedef typename Withdrawing::template entry_pt<typename Withdraw_<AuthMethod>::EntryByCard> WithdrawEntryByCard; typedef typename Withdrawing::template exit_pt <typename Withdraw_<AuthMethod>::Exit> WithdrawExit; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Choosing, ChooseWithdraw, WithdrawEntry, msmf::none, msmf::none >, msmf::Row < Choosing, CardDetect, WithdrawEntryByCard, msmf::none, msmf::none >, msmf::Row < WithdrawExit, msmf::none, Choosing, msmf::none, msmf::none > > {}; }; template <class AuthMethod> struct Trade:msm::back::state_machine<Trade_<AuthMethod> > {}; }
Copyright 2011 Takatoshi Kondo All rights reserved
71/95
ATM(取引)
typedef typename Withdrawing::template entry_pt<typename Withdraw_<AuthMethod>::Entry> WithdrawEntry; typedef typename Withdrawing::template entry_pt<typename Withdraw_<AuthMethod>::EntryByCard> WithdrawEntryByCard; typedef typename Withdrawing::template exit_pt <typename Withdraw_<AuthMethod>::Exit> WithdrawExit; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Choosing, ChooseWithdraw, WithdrawEntry, msmf::none, msmf::none >, msmf::Row < Choosing, CardDetect, WithdrawEntryByCard, msmf::none, msmf::none >, msmf::Row < WithdrawExit, msmf::none, Choosing, msmf::none, msmf::none > > {}; }; template <class AuthMethod> struct Trade:msm::back::state_machine<Trade_<AuthMethod> > {}; }
Copyright 2011 Takatoshi Kondo All rights reserved
72/95
ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
Copyright 2011 Takatoshi Kondo All rights reserved
73/95
ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
struct Entry :msm::front::entry_pseudo_state<> {}; struct EntryByCard:msm::front::entry_pseudo_state<> {};
カード未挿入の場合
カード挿入済みの場合
entry point 疑似状態の実装
state
Copyright 2011 Takatoshi Kondo All rights reserved
74/95
参考 entry point疑似状態と並行状態
State1 entryA
struct EntryA:msm::front::entry_pseudo_state<> {}; struct EntryB:msm::front::entry_pseudo_state<> {}; struct EntryC:msm::front::entry_pseudo_state<> {}; struct EntryD:msm::front::entry_pseudo_state<1> {}; typedef mpl::vector<State1, entryC> initial_state;
entry point 疑似状態の実装
entryC
State0
State3
State4 entryD
リージョン番号
リージョン0 リージョン1
省略したらinitial_stateからの 到達で判断
entryB
State2 E1
initial_stateをentryに
することも可能
Copyright 2011 Takatoshi Kondo All rights reserved
75/95
参考 entry point疑似状態と並行状態
State1 entryA
struct EntryA:msm::front::entry_pseudo_state<> {}; struct EntryB:msm::front::entry_pseudo_state<> {}; struct EntryC:msm::front::entry_pseudo_state<> {}; struct EntryD:msm::front::entry_pseudo_state<1> {}; typedef mpl::vector<State1, entryC> initial_state;
entry point 疑似状態の実装
entryC
State0
State3
State4 entryD
リージョン番号
リージョン0
省略したらinitial_stateからの 到達で判断
entryB
State2 E1
Copyright 2011 Takatoshi Kondo All rights reserved
76/95
参考 entry point疑似状態と並行状態
State1 entryA
struct EntryA:msm::front::entry_pseudo_state<> {}; struct EntryB:msm::front::entry_pseudo_state<> {}; struct EntryC:msm::front::entry_pseudo_state<> {}; struct EntryD:msm::front::entry_pseudo_state<1> {}; typedef mpl::vector<State1, entryC> initial_state;
entry point 疑似状態の実装
entryC
State0
State3
State4 entryD
リージョン番号
省略したらinitial_stateからの 到達で判断
entryB
State2 E1
リージョン1
Copyright 2011 Takatoshi Kondo All rights reserved
77/95
参考 entry point疑似状態と並行状態
State1 entryA
struct EntryA:msm::front::entry_pseudo_state<> {}; struct EntryB:msm::front::entry_pseudo_state<> {}; struct EntryC:msm::front::entry_pseudo_state<> {}; struct EntryD:msm::front::entry_pseudo_state<1> {}; typedef mpl::vector<State1, entryC> initial_state;
entry point 疑似状態の実装
entryC
State0
State3
State4 entryD
リージョン番号
リージョン0 リージョン1
省略したらinitial_stateからの 到達で判断
entryB
State2 E1
initial_stateから 到達不可の場合、 リージョン番号の 指定が必須
Copyright 2011 Takatoshi Kondo All rights reserved
78/95
ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
template <class AuthMethod> struct Withdraw_:msm::front::state_machine_def<Withdraw_<AuthMethod> > { struct WithdrawAuth:AuthMethod {};
パラメータ化された実装の状態への反映
state
int main() { Atm::All<Atm::BioAuth> t;
client
ここで認証方式を差し替えられる
StateMachine
最上階層から伝搬させてきた template parameter
Copyright 2011 Takatoshi Kondo All rights reserved
79/95
ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
struct Exit :msm::front::exit_pseudo_state<msmf::none> {};
exit point疑似状態
exit point 疑似状態の実装
伝搬イベント無し
state
Copyright 2011 Takatoshi Kondo All rights reserved
80/95
ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
struct AccountInfo { AccountInfo(int amount_):balance(amount_) {} int balance; };
サブStateMachineからの情報の伝搬
伝搬する情報
event
struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < AuthExitSuccess, AccountInfo, EnteringAmount, SetAccountInfo, msmf::none >,
遷移
struct SetAccountInfo { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const& e, Fsm&, SourceState&, TargetState& t) const { t.info = e; } };
action
eventは無いが
eventとして記述
サブStateMachineからexit_successする際に自動でイベントが発生する
struct EnteringAmount:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Input amount of money" << std::endl; } EnteringAmount():amount(0), info(0) {} int amount; AccountInfo info; };
state
stateに口座情報を持たせる
口座情報を設定する
Copyright 2011 Takatoshi Kondo All rights reserved
81/95
ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < EnteringAmount, EnterAmount, msmf::none, SetAmount, msmf::none >,
内部遷移
内部遷移の実装
struct SetAmount { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const& e, Fsm&, SourceState&, TargetState& t) const { t.amount = e.amount; } };
struct EnterAmount { EnterAmount(int amount_):amount(amount_) {} int amount; };
struct EnteringAmount:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Input amount of money" << std::endl; } EnteringAmount():amount(0), info(0) {} int amount; AccountInfo info; };
Nextをnoneに設定すれば内部遷移となる
state
event
遷移
action
stateが持つ情報を更新
stateに引き出し金額情報を持たせる
Copyright 2011 Takatoshi Kondo All rights reserved
82/95
ATM(引き出し)
include / 生体認証
金額入力中
entry/ 金額入力画面表示, 金額初期化 数字ボタン押下/ 金額更新
認証中
entry
exit_success
exit_fail
キャンセルボタン押下
[金額 <= アカウント情報.残高] / 支払い, 残高更新 [else]
確認ボタン押下
残高不足提示中
entry/ 残高不足画面表示
確認ボタン押下
引き出し
カード挿入待ち
entry / カード要求画面提示 カード挿入
entry
entry_by_card
残高提示中
entry/ 残高画面表示
確認ボタン押下
exit
アカウント情報
struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < EnteringAmount, Ok, InsufficientFunds, msmf::none, msmf::none >, /*else*/ msmf::Row < EnteringAmount, Ok, DisplayingBalance, Pay, CheckAmount >, msmf::Row < EnteringAmount, EnterAmount, msmf::none, SetAmount, msmf::none >,
if/else分岐
if/else分岐の実装
遷移
struct CheckAmount { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState& s, TargetState&) const { return s.amount <= s.info.balance; } };
guard
遷移評価順序が下から上であることを利用
サブStateMachineから伝搬させて設定済み
Copyright 2011 Takatoshi Kondo All rights reserved
83/95
#include "atm_account_info.hpp" #include "atm_card_detect.hpp" namespace Atm { struct Cancel {}; struct Ok {}; struct EnterAmount { EnterAmount(int amount_):amount(amount_) {} int amount; }; template <class AuthMethod> struct Withdraw_:msm::front::state_machine_def<Withdraw_<AuthMethod> > { struct Entry :msm::front::entry_pseudo_state<> {}; struct EntryByCard:msm::front::entry_pseudo_state<> {}; struct Exit :msm::front::exit_pseudo_state<msmf::none> {}; struct WaitingCard:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Please insert your card" << std::endl; } }; struct WithdrawAuth:AuthMethod {}; struct EnteringAmount:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Input amount of money" << std::endl; } EnteringAmount():amount(0), info(0) {} int amount; AccountInfo info; };
ATM(引き出し)
Copyright 2011 Takatoshi Kondo All rights reserved
84/95
struct InsufficientFunds:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Insufficient Funds" << std::endl; } }; struct DisplayingBalance:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Your balance:" << balance << std::endl; } void setBalance(int balance_) { balance = balance_; } int balance; }; struct CheckAmount { template <class Event, class Fsm, class SourceState, class TargetState> bool operator()(Event const&, Fsm&, SourceState& s, TargetState&) const { return s.amount <= s.info.balance; } }; struct SetAccountInfo { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const& e, Fsm&, SourceState&, TargetState& t) const { t.info = e; } };
ATM(引き出し)
Copyright 2011 Takatoshi Kondo All rights reserved
85/95
struct SetAmount { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const& e, Fsm&, SourceState&, TargetState& t) const { t.amount = e.amount; } }; struct Pay { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState& s, TargetState& t) const { t.setBalance(s.info.balance - s.amount); } }; typedef Entry initial_state; typedef typename WithdrawAuth::template entry_pt<typename AuthMethod::Derived::Entry> AuthEntry; typedef typename WithdrawAuth::template exit_pt <typename AuthMethod::Derived::ExitFail> AuthExitFail; typedef typename WithdrawAuth::template exit_pt <typename AuthMethod::Derived::ExitSuccess> AuthExitSuccess; // Transition table struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < AuthExitSuccess, AccountInfo, EnteringAmount, SetAccountInfo, msmf::none >, msmf::Row < EnteringAmount, Ok, InsufficientFunds, msmf::none, msmf::none >, /*else*/ msmf::Row < EnteringAmount, Ok, DisplayingBalance, Pay, CheckAmount >, msmf::Row < EnteringAmount, EnterAmount, msmf::none, SetAmount, msmf::none >, msmf::Row < InsufficientFunds, Ok, EnteringAmount, msmf::none, msmf::none >, msmf::Row < DisplayingBalance, Ok, Exit, msmf::none, msmf::none > > {}; }; template <class AuthMethod> struct Withdraw:msm::back::state_machine<Withdraw_<AuthMethod> > {}; }
ATM(引き出し)
Copyright 2011 Takatoshi Kondo All rights reserved
86/95
ATM(認証) entry
exit_success
exit_fail
指検出
認証失敗
認証成功(アカウント情報)
生体認証
認証中
entry/認証中画面提示, 認証開始
指待ち
entry/指要求画面提示
タイムアウト
アカウント情報
Copyright 2011 Takatoshi Kondo All rights reserved
87/95
ATM(認証) entry
exit_success
exit_fail
指検出
認証失敗
認証成功(アカウント情報)
生体認証
認証中
entry/認証中画面提示, 認証開始
指待ち
entry/指要求画面提示
タイムアウト
アカウント情報
struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Checking, AuthSuccess, ExitSuccess, msmf::none, msmf::none >,
struct ExitSuccess :msm::front::exit_pseudo_state<AccountInfo> {}; state
遷移
伝搬させたい情報
struct AuthSuccess:AccountInfo { AuthSuccess(AccountInfo const& info):AccountInfo(info) {} };
event
struct AccountInfo { AccountInfo(int amount_):balance(amount_) {} int balance; };
event
Copyright 2011 Takatoshi Kondo All rights reserved
88/95
ATM (認証)
#include "atm_account_info.hpp" namespace Atm { struct AuthSuccess; struct AuthSuccess:AccountInfo { AuthSuccess(AccountInfo const& info):AccountInfo(info) {} }; struct AuthFail {}; struct AuthTimeout {}; struct FingerDetect {}; struct BioAuth_:msm::front::state_machine_def<BioAuth_> { struct Entry :msm::front::entry_pseudo_state<> {}; struct ExitSuccess :msm::front::exit_pseudo_state<AccountInfo> {}; struct ExitFail :msm::front::exit_pseudo_state<msmf::none> {}; struct WaitingFinger:msm::front::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Please place your finger on the sensor" << std::endl; } }; struct Checking:msm::front::state<> { // Entry action template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { std::cout << "Now checking" << std::endl; } }; typedef Entry initial_state; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < Entry, msmf::none, WaitingFinger, msmf::none, msmf::none >, msmf::Row < WaitingFinger, FingerDetect, Checking, msmf::none, msmf::none >, msmf::Row < WaitingFinger, AuthTimeout, ExitFail, msmf::none, msmf::none >, msmf::Row < Checking, AuthSuccess, ExitSuccess, msmf::none, msmf::none >, msmf::Row < Checking, AuthFail, ExitFail, msmf::none, msmf::none > > {}; }; typedef msm::back::state_machine<BioAuth_> BioAuth; }
Copyright 2011 Takatoshi Kondo All rights reserved
89/95
Client – int main() #include "atm_all.hpp" #include "atm_bio_auth.hpp" int main() { Atm::All<Atm::BioAuth> t; t.start(); t.process_event(Atm::HumanDetect()); t.process_event(Atm::ChooseWithdraw()); t.process_event(Atm::CardDetect()); t.process_event(Atm::FingerDetect()); t.process_event(Atm::AuthSuccess(Atm::AccountInfo(100))); t.process_event(Atm::EnterAmount(50)); t.process_event(Atm::Ok()); t.process_event(Atm::Ok()); }
StateMachineのインスタンス宣言・定義
StateMachineの開始
eventの発行
initial_stateのentry actionは ここで実行される
Copyright 2011 Takatoshi Kondo All rights reserved
90/95
Client StateMachine 共通event
依存関係 ~include関係
main.cpp
atm_account_info.hpp
atm_all.hpp
atm_bio_auth.hpp
atm_card_detect.hpp
atm_trade.hpp
atm_withdraw.hpp
withdrawのサブStateMachine としてbio_authを利用しているが
includeは不要
Copyright 2011 Takatoshi Kondo All rights reserved
91/95
Client StateMachine 共通event
依存関係
main.cpp
atm_account_info.hpp
atm_all.hpp
atm_bio_auth.hpp
atm_card_detect.hpp
atm_trade.hpp
atm_withdraw.hpp
親StateMachineを意識しない
親StateMachineを意識しない
暗黙の依存 インターフェースを意識するが、 ファイルはincludeしない
状態マシンを部品としてライブラリ的に再利用可能 フレームワークとしての利用も可能
Copyright 2011 Takatoshi Kondo All rights reserved
92/95
Boost.MSMのUML2.x要素対応
初期疑似状態 Initial Pseudo State
終了状態 Final State
ジャンクション疑似状態 Junction Pseudo State
選択疑似状態 Choice Pseudo State
State entry point疑似状態 Entry Point Pseudo State
exit point疑似状態 Exit Point Pseudo State
H
H *
shallow history
deep history
initial_state の typedef
terminate_state または、 exit_pseudo_state
手作業で等価変換することで対応
(普通の)state と anonymous transition + guardで対応
entry_pseudo_state
exit_pseudo_state (event伝搬拡張あり)
AlwaysHistoryで対応(event限定拡張あり)
対応予定無し UMLでの並行状態における意味が曖昧
StateMachine図(UML2.x)要素 Boost.MSMでの対応
Sub Machine State state_machine_def で対応
Copyright 2011 Takatoshi Kondo All rights reserved
93/95
Boost.MSMのUML2.x要素対応 StateMachine図(UML2.x)要素 Boost.MSMでの対応
並行状態 State
initial_state の typedef を mpl::vectorとすることで対応
fork
forkノード entry_pseudo_state にインデックスを指定することで対応 explicit_entryによっても対応可能
join
joinノード 待ち合わせ状態を作り、StateMachineにカウンタなどを 持たせることで対応可能
eventのdefer (延期) activate_deferred_events typedefの 遷移アクション Deferで対応可能
Actionでの自身へのeventを発行 fsm.proccess_event(event)を呼び出すことで対応 ※キューイング処理され、再帰が連鎖することはない
Copyright 2011 Takatoshi Kondo All rights reserved
94/95