有限状态机

lua-users home
wiki

本文介绍了一种在 Lua 中实现有限状态机 (FSM) 的设计模式。

这最初是在邮件列表中提出的

 > From: romeo kalebic <romeo.kalebic@k...>
 >
 > I'm learning lua with small fsm machine built in C and all actions are
 > built in lua.
 > FSM is described with: old_state, event, new_state and action.
 >
 >  state1, event1, state2, action1
 >  state1, event2, state3, action2
 >  etc..
 >
 > Now, I like to describe fsm in lua, maybe in lua table or ?.

在 Lua 中实现这一点的一种简单方法是创建一个完全按照上述形式创建的表

fsm = FSM{ 
  {state1, event1, state2, action1},
  {state1, event2, state3, action2},
  ...
}

其中 FSM 是一个即将介绍的函数。

然后,要运行该机器,可以在循环中执行类似如下的操作

local a = fsm[state][event]
a.action()
state = a.new

如果需要,还可以添加一些错误检查(例如,如果 anil,则表示转换(state, event)无效)。此外,如果操作可以使用此信息,您可能还想执行 a.action(state, event, a.new)

函数 FSM 接受上述简单语法,并为 (state, event) 对创建具有 (action, new) 字段的表

function FSM(t)
  local a = {}
  for _,v in ipairs(t) do
    local old, event, new, action = v[1], v[2], v[3], v[4]
    if a[old] == nil then a[old] = {} end
    a[old][event] = {new = new, action = action}
  end
  return a
end

请注意,此方案适用于任何类型的状态和事件:数字、字符串、函数、表,任何东西。关联数组的力量就在于此。

玩得开心。--LuizHenriqueDeFigueiredo

运行版本


function action1()
 print("action1")
end

function action2()
 print("action2")
end


function FSM(t)
  local a = {}
  for _,v in ipairs(t) do
    local old, event, new, action = v[1], v[2], v[3], v[4]
    if a[old] == nil then a[old] = {} end
    a[old][event] = {new = new, action = action}
  end
  return a
end

fsm = FSM{
  {"state1", "event1", "state2", action1},
  {"state1", "event2", "state3", action2},
}

local a = fsm["state1"]["event1"]
a.action()
state = a.new

注意:以上代码兼容 Lua 5.0 和 5.1。


RecentChanges · preferences
编辑 · 历史
最后编辑于 2010 年 8 月 8 日 上午 11:24 GMT (差异)