SlideShare a Scribd company logo
1 of 95
Download to read offline
Boost.Msmの使い方
Copyright 2011 Takatoshi Kondo All rights reserved
1/95
自己紹介
近藤 貴俊
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 State2event [ 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 State2event [ guard ] / action
event記述がなければ、
トリガとなったevent処理のなかで本遷移が評価される。
State1 State2
Guardが成立するまで待って、
成立したら遷移ではないので注意
Event1
Event1の発生でState2まで遷移する
State1 State2Event1 [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 State2Event1 [ 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を題材としたケーススタディ
Copyright 2011 Takatoshi Kondo All rights reserved
33/95
ATMを題材としたケーススタディ
• StateMachineの階層化
• StateMachineのインターフェースと
実装の分離
• 複数の entry point疑似状態の使い分け
• サブStateMachineから親StateMachineへの
Eventの伝搬
• guardによるif/else分岐
Copyright 2011 Takatoshi Kondo All rights reserved
34/95
4つのStateMachine
1.全体 2.取引
3.引き出し 4.(生体)認証
Copyright 2011 Takatoshi Kondo All rights reserved
35/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
シナリオ
Copyright 2011 Takatoshi Kondo All rights reserved
53/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
実装
Copyright 2011 Takatoshi Kondo All rights reserved
60/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
Boost.Msmの使い方
Copyright 2011 Takatoshi Kondo All rights reserved
95/95

More Related Content

Similar to Boostsapporomsmpre 111030054504-phpapp02

Node.js - JavaScript Thread Programming
Node.js - JavaScript Thread ProgrammingNode.js - JavaScript Thread Programming
Node.js - JavaScript Thread Programmingtakesako
 
Flutter のリアクティブ戦略 set state 〜 redux まで
Flutter のリアクティブ戦略 set state 〜 redux までFlutter のリアクティブ戦略 set state 〜 redux まで
Flutter のリアクティブ戦略 set state 〜 redux までcch-robo
 
About GStreamer 1.0 application development for beginners
About GStreamer 1.0 application development for beginnersAbout GStreamer 1.0 application development for beginners
About GStreamer 1.0 application development for beginnersShota TAMURA
 
FMI1.0 FMI for Co-Simulation について
FMI1.0 FMI for Co-Simulation についてFMI1.0 FMI for Co-Simulation について
FMI1.0 FMI for Co-Simulation についてAmane Tanaka
 
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)Ken Morishita
 
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9Saiki Iijima
 

Similar to Boostsapporomsmpre 111030054504-phpapp02 (9)

Inside Movable Type
Inside Movable TypeInside Movable Type
Inside Movable Type
 
Node.js - JavaScript Thread Programming
Node.js - JavaScript Thread ProgrammingNode.js - JavaScript Thread Programming
Node.js - JavaScript Thread Programming
 
Apache Tapestry
Apache TapestryApache Tapestry
Apache Tapestry
 
Boost tour 1_44_0
Boost tour 1_44_0Boost tour 1_44_0
Boost tour 1_44_0
 
Flutter のリアクティブ戦略 set state 〜 redux まで
Flutter のリアクティブ戦略 set state 〜 redux までFlutter のリアクティブ戦略 set state 〜 redux まで
Flutter のリアクティブ戦略 set state 〜 redux まで
 
About GStreamer 1.0 application development for beginners
About GStreamer 1.0 application development for beginnersAbout GStreamer 1.0 application development for beginners
About GStreamer 1.0 application development for beginners
 
FMI1.0 FMI for Co-Simulation について
FMI1.0 FMI for Co-Simulation についてFMI1.0 FMI for Co-Simulation について
FMI1.0 FMI for Co-Simulation について
 
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
 
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
 

Boostsapporomsmpre 111030054504-phpapp02

  • 1. Boost.Msmの使い方 Copyright 2011 Takatoshi Kondo All rights reserved 1/95
  • 2. 自己紹介 近藤 貴俊 BLOG http://d.hatena.ne.jp/redboltz/ twitter @redboltz C++標準化委員会メンバ 技術士(情報工学部門) GCJJ Tシャツ圏内 Copyright 2011 Takatoshi Kondo All rights reserved 2/95
  • 3.
  • 4. 目次 • StateMachineとは • Boost Meta State Machine Library • ATMを題材としたケーススタディ • StateMachineDiagram(UML2.x)への対応状況 Copyright 2011 Takatoshi Kondo All rights reserved 4/95
  • 5. StateMachineとは State Machine Event [Output] Event Driven Outputは、あったりなかったり EventA EventA Outupt1 Outupt2 同じEventでも Outputが変わったり 中身は、 と Copyright 2011 Takatoshi Kondo All rights reserved 5/95
  • 6. StateMachineの構成要素 State1 event [ guard ] / action entry / action do / action exit / action event [ guard ] / action Copyright 2011 Takatoshi Kondo All rights reserved 6/95
  • 7. StateMachineの構成要素 State1 event [ guard ] / action 状態 遷移 entry / action do / action exit / action event [ guard ] / action Copyright 2011 Takatoshi Kondo All rights reserved 7/95
  • 8. 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
  • 9. 遷移 Transition State1 State2event [ guard ] / action 遷移元状態(State1)において、eventが発生した際、 guardが成立していれば、遷移先状態(State2)に遷移する。 遷移の際、actionを実行する。 event guard action は、いずれもoptional • guard記述がなければ、eventが発生した際、無条件に 遷移先状態に遷移する。 • action記述がなければ、遷移の際、特に何も実行しない。 • event記述が無い場合の意味論は後述 Copyright 2011 Takatoshi Kondo All rights reserved 9/95
  • 10. 内部遷移 Internal Transition State1 event [ guard ] / action 遷移先状態を指定しない遷移。状態遷移は発生しない。 状態の内部に記述する(UMLの表記法) あるEvent発生時、guardに応じてactionを実行することを 目的として記述される。 遷移しない遷移なんだから、actionを書かないと意味がない Copyright 2011 Takatoshi Kondo All rights reserved 10/95
  • 11. 遷移 Transition State1 State2event [ guard ] / action event記述がなければ、 トリガとなったevent処理のなかで本遷移が評価される。 State1 State2 Guardが成立するまで待って、 成立したら遷移ではないので注意 Event1 Event1の発生でState2まで遷移する State1 State2Event1 [G1] E2/G1=true G1がfalseならState1まで遷移して待ち状態になる その後、eventによらず、G1がtrueになっても遷移は発生しない E2が発生したらState2に遷移する Copyright 2011 Takatoshi Kondo All rights reserved 11/95
  • 12. 状態 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
  • 13. その他の構成要素 初期疑似状態 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
  • 17. 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
  • 18. 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
  • 19. 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
  • 20. 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
  • 21. 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
  • 22. 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
  • 23. 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
  • 24. 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
  • 25. 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
  • 27. 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
  • 28. 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 State2Event1 [ Guard1 ] / Action1 Copyright 2011 Takatoshi Kondo All rights reserved 28/95
  • 29. 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
  • 30. 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
  • 31. 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
  • 32. 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
  • 34. ATMを題材としたケーススタディ • StateMachineの階層化 • StateMachineのインターフェースと 実装の分離 • 複数の entry point疑似状態の使い分け • サブStateMachineから親StateMachineへの Eventの伝搬 • guardによるif/else分岐 Copyright 2011 Takatoshi Kondo All rights reserved 34/95
  • 39. 2.ATM(取引) 引き出し選択 include / 引き出し 取引選択中 entry/取引選択画面提示 引き出し中 entry exit 取引 カード挿入 entry_by_card その他選択 省略 Copyright 2011 Takatoshi Kondo All rights reserved 39/95
  • 40. 2.ATM(取引) 引き出し選択 include / 引き出し 取引選択中 entry/取引選択画面提示 引き出し中 entry exit 取引 カード挿入 entry_by_card その他選択 省略 取引単位などで、階層化、モジュール化 Copyright 2011 Takatoshi Kondo All rights reserved 40/95
  • 41. 2.ATM(取引) 引き出し選択 include / 引き出し 取引選択中 entry/取引選択画面提示 引き出し中 entry exit 取引 カード挿入 entry_by_card その他選択 省略 複数のentry point Copyright 2011 Takatoshi Kondo All rights reserved 41/95
  • 42. 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
  • 43. 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
  • 44. 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
  • 45. 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
  • 46. 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
  • 47. 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
  • 48. 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
  • 52. 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
  • 53. シナリオ Copyright 2011 Takatoshi Kondo All rights reserved 53/95
  • 55. 2.ATM(取引) 引き出し選択 include / 引き出し 取引選択中 entry/取引選択画面提示 引き出し中 entry exit 取引 カード挿入 entry_by_card その他選択 省略 Copyright 2011 Takatoshi Kondo All rights reserved 55/95
  • 56. 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
  • 58. 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
  • 59. 2.ATM(取引) 引き出し選択 include / 引き出し 取引選択中 entry/取引選択画面提示 引き出し中 entry exit 取引 カード挿入 entry_by_card その他選択 省略 Copyright 2011 Takatoshi Kondo All rights reserved 59/95
  • 60. 実装 Copyright 2011 Takatoshi Kondo All rights reserved 60/95
  • 62. 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
  • 63. 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
  • 64. 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
  • 65. 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
  • 66. ATM(取引) 引き出し選択 include / 引き出し 取引選択中 entry/取引選択画面提示 引き出し中 entry exit 取引 カード挿入 entry_by_card その他選択 省略 Copyright 2011 Takatoshi Kondo All rights reserved 66/95
  • 67. #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
  • 68. #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
  • 69. 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
  • 70. 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
  • 71. 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
  • 72. 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
  • 73. 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
  • 74. 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
  • 75. 参考 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
  • 76. 参考 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
  • 77. 参考 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
  • 78. 参考 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
  • 79. 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
  • 80. 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
  • 81. 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
  • 82. 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
  • 83. 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
  • 84. #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
  • 85. 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
  • 86. 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
  • 88. 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
  • 89. 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
  • 90. 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
  • 91. 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
  • 93. 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
  • 94. 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
  • 95. Boost.Msmの使い方 Copyright 2011 Takatoshi Kondo All rights reserved 95/95