Skip to content

Instantly share code, notes, and snippets.

@kikito
Last active October 13, 2025 08:55
Show Gist options
  • Select an option

  • Save kikito/2f17263cfc8745a32a905dbb0ee40937 to your computer and use it in GitHub Desktop.

Select an option

Save kikito/2f17263cfc8745a32a905dbb0ee40937 to your computer and use it in GitHub Desktop.
fsm.p8
do
local function doevent(m,c,e, ...)
local dst=(c[m.state] and c[m.state][e])
or (c["*"] and c["*"][e])
dst = type(dst)=="function" and dst(...) or dst
if dst then
m.state=dst
return dst
end
end
local function clone(m,init)
local m2={}
for e,f in pairs(m) do
m2[e]=f
end
m2.state=init
return m2
end
_ENV.fsm=function(init,spec)
local m,c={state=init},{}
m.clone=function() return clone(m,init) end
for e,es in pairs(spec) do
for src,dst in pairs(es) do
src=split(src)
for i=1,#src do
local s=src[i]
c[s]=c[s] or {}
c[s][e]=dst
end
end
m[e]=function(sm,...)
return doevent(sm,c,e,...)
end
end
return m
end
end
local m=fsm("off", {
turn_on={ off = "red" },
turn_off={ ["red,green,amber"]= "off" },
change={ red="green", green="amber", amber="red" },
set = { ["*"] = function(s) return s end },
})
print(m.state) -- off
print(m:turn_off())-- nil (still off)
print(m:change()) -- nil (still off)
print(m:turn_on()) -- red
print(m:change()) -- green
print(m:change()) -- amber
print(m:change()) -- red
print(m:turn_on()) -- nil (still amber)
print(m:turn_off())-- off
print(m:change()) -- nil (still off)
print(m:set("green")) -- "green" (jump to state without transition)
print(m:set("blue")) -- "blue" (made-up state)
local m2=m:clone()
print(m2.state) -- off
print(m2:turn_on()) -- red
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment