ユーザ用ツール

サイト用ツール


prog_worker:ステートマシン

ステートマシン

組込みソフトウェアでは、ステートマシンを使って上位設計(モデルベース設計)を行い、それをコードに落とすという設計手法を採用する場合があります。
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)を使います。

  • 1行入力されたらハンドラが動作を開始します。
  • 入力文字列の先頭文字が "1"ならば、ステートを St1 に変更します。"2"の場合も同様です。
  • 入力文字列の先頭文字が "A"ならば、イベント EvA を発生させ、その時のステートに合致するハンドラが呼び出されます。"B"の場合も同様です。

イベントが発生した場合の各動作は、state_STATE_event_EVENT 形式の名前を付けたメソッドとして定義します。Aloneは、イベントの発生があると、ステート(状態)とイベント種類に応じて適宜選択して呼び出します。

イベントという言葉が、文脈によって2パターンに使い分けられていますので注意してください。

最初の「イベントハンドラ」の場合は、システム(OS)によって発生したイベントの事で、イベントハンドラはブロックとして記述しステートに関係なく呼び出されます。

ステートマシンの「イベント」と言った場合は、イベントは trigger_event()メソッドによって生成され、ハンドラはメソッドとして記述します。

prog_worker/ステートマシン.txt · 最終更新: 2019/03/19 17:41 by hirohito