DONE! Prototype of hierarchical state machine is works!!!

This commit is contained in:
FlightControl 2016-07-02 09:06:29 +02:00
parent d668b0a0f7
commit ae1aeac6ce
4 changed files with 33 additions and 13 deletions

View File

@ -56,7 +56,7 @@ function STATEMACHINE:New( options )
end
for name, endstate in pairs( options.endstates or {} ) do
self.endstates[name] = endstate
self.endstates[endstate] = endstate
end
return self
@ -64,11 +64,12 @@ end
function STATEMACHINE:_submap( subs, sub, name )
self:E( { subs = subs, sub = sub, name = name } )
self:E( { sub = sub, name = name } )
subs[sub.onstateparent] = subs[sub.onstateparent] or {}
subs[sub.onstateparent][sub.oneventparent] = subs[sub.onstateparent][sub.oneventparent] or {}
subs[sub.onstateparent][sub.oneventparent].fsm = sub.fsm
subs[sub.onstateparent][sub.oneventparent].event = sub.event
subs[sub.onstateparent][sub.oneventparent].returnevents = sub.returnevents -- these events need to be given to find the correct continue event ... if none given, the processing will stop.
subs[sub.onstateparent][sub.oneventparent].name = name
subs[sub.onstateparent][sub.oneventparent].fsmparent = self
end
@ -83,8 +84,8 @@ end
function STATEMACHINE:_create_transition(name)
self:E( { name = name } )
return function(self, ...)
self:E(name)
local can, to = self:can(name)
self:E( { name, can, to } )
if can then
local from = self.current
@ -101,12 +102,12 @@ function STATEMACHINE:_create_transition(name)
if fsm and fsm[event] then
self:E( "calling sub: " .. event )
fsm.fsmparent = self
fsm.from = to
fsm.returnevents = self:_returnevents( to, name )
fsm[event]( fsm )
else
local fsmparent, event = self:_isendstate( to )
if fsmparent then
if fsmparent and event then
fsmparent[event]( fsmparent )
else
self:_call_handler(self["onenter" .. to] or self["on" .. to], params)
@ -130,13 +131,32 @@ function STATEMACHINE:_gosub( parentstate, parentevent )
end
end
function STATEMACHINE:_isendstate( state )
if self.fsmparent then
return self.fsmparent,
function STATEMACHINE:_returnevents( parentstate, parentevent )
if self.subs[parentstate] and self.subs[parentstate][parentevent] then
self:E(self.subs[parentstate][parentevent].returnevents)
return self.subs[parentstate][parentevent].returnevents
else
return nil
end
end
function STATEMACHINE:_isendstate( state )
local fsmparent = self.fsmparent
if fsmparent and self.endstates[state] then
self:E( { state = state, endstates = self.endstates, endstate = self.endstates[state] } )
local returnevent = nil
local fromstate = fsmparent.current
for _, eventname in pairs( self.returnevents ) do
local event = fsmparent.events[eventname]
self:E( event )
local to = event and event.map[fromstate] or event.map['*']
if to then
return fsmparent, eventname
end
end
end
return nil
end
function STATEMACHINE:_add_to_map(map, event)

View File

@ -35,7 +35,7 @@ function TASK2_CLIENT_MENU:New( Client, Mission, MenuText )
onMenu = self.OnMenu,
onAssign = self.OnAssign,
},
finals = {
endstates = {
'Assigned'
},
} )

View File

@ -18,15 +18,15 @@ local Task_Sead = STATEMACHINE:New( {
initial = 'None',
events = {
{ name = 'Start', from = 'None', to = 'Unassigned' },
{ name = 'Assign', from = 'Unassigned', to = 'Assigned' },
{ name = 'Next', from = 'Unassigned', to = 'Assigned' },
-- { name = 'Route', from = 'Assigned', to = 'Arrived' },
{ name = 'Sead', from = 'Assigned', to = 'Seading' },
{ name = 'Next', from = 'Assigned', to = 'Seading' },
{ name = 'Destroyed', from = 'Destroy', to = 'Success' },
},
subs = {
Menu = { onstateparent = 'Unassigned', oneventparent = 'Start', fsm = Task_Menu.Fsm, event = 'Menu' },
Menu = { onstateparent = 'Unassigned', oneventparent = 'Start', fsm = Task_Menu.Fsm, event = 'Menu', returnevents = { 'Next' } },
--Assigned = { onstateparent = 'Assigned', oneventparent = 'Assign', fsm = Task_Route.Fsm, event = 'Route' },
Sead = { onstateparent = 'Assigned', oneventparent = 'Assign', fsm = Task_Client_Sead.Fsm, event = 'Await' }
Sead = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = Task_Client_Sead.Fsm, event = 'Await', returnevents = { 'Next' } }
}
} )