有限状态机

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 兼容。


最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2010 年 8 月 8 日下午 5:24 GMT (差异)