====== 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) するように指定されている|
|空欄|ハンドラが定義されていない|