====== AlWorker ステートマシン ====== require "al_worker" ---- ステートマシンを直接サポートします。\\ 各動作を state_STATE_event_EVENT 形式の名前を付けたメソッドとして定義しておき、フレームワークがステート(状態)とイベントによって、適宜選択して呼び出しながら、全体の動作を行うように構成できます。\\ ====== サンプル ====== require "al_worker_tcp" require "al_worker_timer" class Worker1 < AlWorker def initialize2() set_state( "EN" ) @count = 0 @tcp = Tcp.new() @tcp.run( self ) @timer = Timer.periodic( 10 ) @timer.run() { change_state() } end def tcp_say( sock, param ) trigger_event( "SAY", sock ) # イベント "SAY" を発生させる。 return true end def change_state() # 10秒ごとに、ステートを変更する。 case @state when "EN"; set_state( "JP" ) when "JP"; set_state( "DE" ) when "DE"; set_state( "EN" ) end end # ステートが"EN"の時に、"SAY"イベントが発生した時の処理。 def state_EN_event_SAY( sock ) a = ["one","two","three","four","five","six","seven","eight","nine","ten"] sock.puts a[@count] @count = 0 if (@count += 1) > 9 end # ステートが"JP"の時に、"SAY"イベントが発生した時の処理。 def state_JP_event_SAY( sock ) a = ["ichi","ni","san","shi","go","roku","shichi","hachi","kyu","jyu"] sock.puts a[@count] @count = 0 if (@count += 1) > 9 end # ステートが"DE"の時に、"SAY"イベントが発生した時の処理。 def state_DE_event_SAY( sock ) a = ["eins","zwei","drei","vier","fünf","sechs","sieben","acht","neun","zehn"] sock.puts a[@count] @count = 0 if (@count += 1) > 9 end end server = Worker1.new server.daemon ===== 解説 ===== TCPで接続しsayを送るごとに、カウントアップします。\\ カウントは、10秒ごとに英語、日本語、ドイツ語を切り替えます。\\ ====== 個別機能 ====== ===== ステートを宣言する ===== set_state( "STATE" ) # この2つは同じメソッドのaliasです。 next_state( "STATE" ) ===== イベントを発生させる ===== trigger_event( "EVENT", 任意パラメータ ) ===== ハンドラ選択の優先度 ===== ^優先度^ハンドラメソッド名^ |大|from_STATE_event_EVENT()| |↑|state_STATE_event_EVENT()| |↓|event_EVENT()| |小|state_STATE()| 条件が重なるハンドラが定義されている場合、上記優先度に従って呼ばれるハンドラが一つ選択されます。 ===== 無視するイベントの記述 ===== クラス定義中に、na :state_XXX_event_YYY の様に記述します。 Class Worker1 < AlWorker na :state_STATE1_event_EVENT1 end ====== ステート表のリバース生成 ====== 簡易的にですが、Rubyコードからステート表をリバース生成できるスクリプトを提供しています。\\ 上記サンプルプログラムをパースした例です。 $./make_state_chart.rb state_machine.rb EN JP DE SAY full full full スクリプト、make_state_chart.rb に、対象プログラムを引数として実行すると、ステートを横軸に、イベントを縦軸にした表を生成します。 表の見方 ^表示^意味^ |full|ステート、イベントとも指定されたハンドラが定義されている| |event|イベントのみ指定されたハンドラが定義されている| |state|ステートのみ指定されたハンドラが定義されている| |/|無視 (na) するように指定されている| |空欄|ハンドラが定義されていない|