-
Notifications
You must be signed in to change notification settings - Fork 68
Open
Description
Hello! This is a great project I'm a huge fan of.
My use case is vehicle control. Having a state machine for this is key. While not a hard requirement, it would be useful to decouple "state entry" logic (the on* callbacks) from my "do certain things while in state continuously on loop" callbacks. Something like:
local machine = require('statemachine')
local fsm = machine.create({
initial = 'startup',
events = {
{ name = 'startup2safe', from = 'startup', to = 'safe' },
{ name = 'normalOps2safe', from = 'normalOps', to = 'safe' },
{ name = 'diagnostic2safe', from = 'diagnostic', to = 'safe' },
{ name = 'startup2diagnostic', from = 'startup', to = 'diagnostic' }
{ name = 'diagnostic2normalOps', from = 'diagnostic', to = 'normalOps' }
{ name = 'safe2normalOps', from = 'safe', to = 'normalOps' }
{ name = 'startup2normalOps', from = 'startup', to = 'normalOps' }
},
callbacks = {
-- on-state-entry callbacks
onstartup2safe = function(self, event, from, to) print('transitioned from startup to safe') end,
onnormalOps2safe = function(self, event, from, to) print('transitioned from normalops to safe') end,
ondiagnostic2safe = function(self, event, from, to) print('transitioned from diagnostic to safe') end,
onstartup2diagnostic = function(self, event, from, to) print('transitioned from startup to diagnostic') end,
ondiagnostic2normalOps = function(self, event, from, to) print('transitioned from diagnostic to normalOps') end,
onsafe2normalOps = function(self, event, from, to) print('transitioned from safe to normalOps') end,
onstartup2normalOps = function(self, event, from, to) print('transitioned from startup to normalOps') end,
-- DESIRE: while-in-state callbacks
whileinstartup = function(self, event, from, to) print('still in startup state') end,
whileinsafe = function(self, event, from, to) print('still in safe state') end,
whileindiagnostic = function(self, event, from, to) print('still in diagnostic state') end,
whileinnormalops = function(self, event, from, to) print('still in normalops state') end,
}
})
-- On startup, we'd just see 'still in startup state' print over and over until we transition elsewhere.
This is essentially roughly equivalent to something like:
local machine = require('statemachine')
-- ============================ --
-- === State Loop Functions === --
-- ============================ --
local function whileInSafe()
while true do
print('still in safe state')
end
end
local function whileInStartup()
while true do
print('still in startup state')
end
end
local function whileInDiagnostic()
while true do
print('still in diagnostic state')
end
end
local function whileInNormalOps()
while true do
print('still in normalOps state')
end
end
-- ================================== --
-- === Event Transition Functions === --
-- ================================== --
local function startup2safe()
print('transitioned from startup to safe')
whileInSafe()
end
local function normalOps2safe()
print('transitioned from normalOps to safe')
whileInSafe()
end
local function diagnostic2safe()
print('transitioned from diagnostic to safe')
whileInSafe()
end
local function startup2diagnostic()
print('transitioned from startup to diagnostic')
whileInDiagnostic()
end
local function diagnostic2normalOps()
print('transitioned from diagnostic to normalOps')
whileInNormalops()
end
local function safe2normalOps()
print('transitioned from safe to normalOps')
whileInNormalops()
end
local function startup2normalOps()
print('transitioned from startup to normalOps')
whileInNormalops()
end
-- =========== --
-- === FSM === --
-- =========== --
local fsm = machine.create({
initial = 'startup',
events = {
{ name = 'startup2safe', from = 'startup', to = 'safe' },
{ name = 'normalOps2safe', from = 'normalOps', to = 'safe' },
{ name = 'diagnostic2safe', from = 'diagnostic', to = 'safe' },
{ name = 'startup2diagnostic', from = 'startup', to = 'diagnostic' }
{ name = 'diagnostic2normalOps', from = 'diagnostic', to = 'normalOps' }
{ name = 'safe2normalOps', from = 'safe', to = 'normalOps' }
{ name = 'startup2normalOps', from = 'startup', to = 'normalOps' }
},
callbacks = {
onstartup2safe = function(self, event, from, to) startup2safe() end,
onnormalOps2safe = function(self, event, from, to) normalOps2safe() end,
ondiagnostic2safe = function(self, event, from, to) diagnostic2safe() end,
onstartup2diagnostic = function(self, event, from, to) startup2diagnostic() end,
ondiagnostic2normalOps = function(self, event, from, to) diagnostic2normalOps() end,
onsafe2normalOps = function(self, event, from, to) safe2normalOps() end,
onstartup2normalOps = function(self, event, from, to) startup2normalOps() end,
}
})
-- On startup, we'd just see 'still in startup state' print over and over until we transition elsewhere.
Not exactly sure how this would work to detect "transition out, abort the while-in-state callback". Maybe a global that each callback refers to as a check condition for the while loop continuing?
Happy to learn more about how to do this as-is in the framework.
Metadata
Metadata
Assignees
Labels
No labels