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