組込みソフトウェアでは、ステートマシンを使って上位設計(モデルベース設計)を行い、それをコードに落とすという設計手法を採用する場合があります。
Aloneでは、ステートマシンを直接サポートし、記述性、可読性の向上を実現しています。
ここでは簡単に、2種類のステート (1 or 2)と2種類のイベント (A or B) の、合計4つの場合があることを想定したサンプルを示します。
St 1 | St 2 | |
---|---|---|
Ev A | handler St1 EvA | handler St2 EvA |
Ev B | handler St1 EvB | handler St2 EvB |
require "al_worker_tcp" require "al_worker_fd" class Worker1 < AlWorker def initialize2() set_state( :St1 ) @fd = Fd.new(STDIN) @fd.ready_read() { # STDINの行入力イベントハンドラ txt = @fd.file.gets case txt[0] when "1" set_state( :St1 ) puts "DEBUG: change state to :St1" when "2" set_state( :St2 ) puts "DEBUG: change state to :St2" when "A", "a" trigger_event( :EvA ) when "B", "b" trigger_event( :EvB ) end } end # ステートマシンのハンドラ群 def state_St1_event_EvA() puts "state_St1_event_EvA called." end def state_St1_event_EvB() puts "state_St1_event_EvB called." end def state_St2_event_EvA() puts "state_St2_event_EvA called." end def state_St2_event_EvB() puts "state_St2_event_EvB called." end end worker = Worker1.new() puts "Hit 1, 2, A, B (and Enter)" worker.run()
初期化では、初期状態のステート St1 を宣言しています。
そして、キー入力を使い状態の遷移とイベントの発生を模擬するために、イベントハンドラとして標準入力(STDIN)を使います。
イベントが発生した場合の各動作は、state_STATE_event_EVENT 形式の名前を付けたメソッドとして定義します。Aloneは、イベントの発生があると、ステート(状態)とイベント種類に応じて適宜選択して呼び出します。
イベントという言葉が、文脈によって2パターンに使い分けられていますので注意してください。
最初の「イベントハンドラ」の場合は、システム(OS)によって発生したイベントの事で、イベントハンドラはブロックとして記述しステートに関係なく呼び出されます。
ステートマシンの「イベント」と言った場合は、イベントは trigger_event()メソッドによって生成され、ハンドラはメソッドとして記述します。