Finite State Machine

lua-users home
wiki

This article provides a design pattern for doing finite state machines (FSMs) in Lua.

This was originally asked for on the mailing list:


 > 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 ?.

One easy way to do this in Lua would be to create a table in exactly the form above:

fsm = FSM{ 

  {state1, event1, state2, action1},

  {state1, event2, state3, action2},

  ...

}

where FSM is a function to be described soon.

Then, to run the machine, do something like this in a loop:

local a = fsm[state][event]

a.action()

state = a.new

plus some error checking if needed (eg, if a is nil, then the transition (state, event) is invalid). Also, you might want to do a.action(state, event, a.new)} if the action can use this info.

The function FSM takes the simple syntax above and creates tables for (state, event) pairs with fields (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

Note that this scheme works for states and events of any type: number, string, functions, tables, anything. Such is the power of associate arrays.

Have fun. --LuizHenriqueDeFigueiredo

running version:






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



Note: above code is Lua 5.0 and 5.1 compatible.


RecentChanges · preferences
edit · history
Last edited August 8, 2010 4:24 pm GMT (diff)