diff options
author | chai <chaifix@163.com> | 2018-12-22 14:05:34 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-12-22 14:05:34 +0800 |
commit | fc1b6e2b85b3c2d333b8a9b6b830bf511971da80 (patch) | |
tree | a73062dee3348e7fac35b3435b69583a6ce553a1 /src/libjin-lua/scripts/ai/state_machine.lua | |
parent | df70a616f58aa51ff6375a824fc18cbbc369e43b (diff) |
*format
Diffstat (limited to 'src/libjin-lua/scripts/ai/state_machine.lua')
-rw-r--r-- | src/libjin-lua/scripts/ai/state_machine.lua | 222 |
1 files changed, 111 insertions, 111 deletions
diff --git a/src/libjin-lua/scripts/ai/state_machine.lua b/src/libjin-lua/scripts/ai/state_machine.lua index 296296f..dbf655b 100644 --- a/src/libjin-lua/scripts/ai/state_machine.lua +++ b/src/libjin-lua/scripts/ai/state_machine.lua @@ -32,149 +32,149 @@ local NONE = "none" local ASYNC = "async" local function call_handler(handler, params) - if handler then - return handler(unpack(params)) - end + if handler then + return handler(unpack(params)) + end end local function create_transition(name) - local can, to, from, params - - local function transition(self, ...) - if self.asyncState == NONE then - can, to = self:can(name) - from = self.current - params = { self, name, from, to, ...} - - if not can then return false end - self.currentTransitioningEvent = name - - local beforeReturn = call_handler(self["onbefore" .. name], params) - local leaveReturn = call_handler(self["onleave" .. from], params) - - if beforeReturn == false or leaveReturn == false then + local can, to, from, params + + local function transition(self, ...) + if self.asyncState == NONE then + can, to = self:can(name) + from = self.current + params = { self, name, from, to, ...} + + if not can then return false end + self.currentTransitioningEvent = name + + local beforeReturn = call_handler(self["onbefore" .. name], params) + local leaveReturn = call_handler(self["onleave" .. from], params) + + if beforeReturn == false or leaveReturn == false then + return false + end + + self.asyncState = name .. "WaitingOnLeave" + + if leaveReturn ~= ASYNC then + transition(self, ...) + end + + return true + elseif self.asyncState == name .. "WaitingOnLeave" then + self.current = to + + local enterReturn = call_handler(self["onenter" .. to] or self["on" .. to], params) + + self.asyncState = name .. "WaitingOnEnter" + + if enterReturn ~= ASYNC then + transition(self, ...) + end + + return true + elseif self.asyncState == name .. "WaitingOnEnter" then + call_handler(self["onafter" .. name] or self["on" .. name], params) + call_handler(self["onstatechange"], params) + self.asyncState = NONE + self.currentTransitioningEvent = nil + return true + else + if string.find(self.asyncState, "WaitingOnLeave") or string.find(self.asyncState, "WaitingOnEnter") then + self.asyncState = NONE + transition(self, ...) + return true + end + end + + self.currentTransitioningEvent = nil return false - end - - self.asyncState = name .. "WaitingOnLeave" - - if leaveReturn ~= ASYNC then - transition(self, ...) - end - - return true - elseif self.asyncState == name .. "WaitingOnLeave" then - self.current = to - - local enterReturn = call_handler(self["onenter" .. to] or self["on" .. to], params) - - self.asyncState = name .. "WaitingOnEnter" - - if enterReturn ~= ASYNC then - transition(self, ...) - end - - return true - elseif self.asyncState == name .. "WaitingOnEnter" then - call_handler(self["onafter" .. name] or self["on" .. name], params) - call_handler(self["onstatechange"], params) - self.asyncState = NONE - self.currentTransitioningEvent = nil - return true - else - if string.find(self.asyncState, "WaitingOnLeave") or string.find(self.asyncState, "WaitingOnEnter") then - self.asyncState = NONE - transition(self, ...) - return true - end end - self.currentTransitioningEvent = nil - return false - end - - return transition + return transition end local function add_to_map(map, event) - if type(event.from) == 'string' then - map[event.from] = event.to - else - for _, from in ipairs(event.from) do - map[from] = event.to + if type(event.from) == 'string' then + map[event.from] = event.to + else + for _, from in ipairs(event.from) do + map[from] = event.to + end end - end end function machine.create(options) - assert(options.events) - - local fsm = {} - setmetatable(fsm, machine) - - fsm.options = options - fsm.current = options.initial or 'none' - fsm.asyncState = NONE - fsm.events = {} - - for _, event in ipairs(options.events or {}) do - local name = event.name - fsm[name] = fsm[name] or create_transition(name) - fsm.events[name] = fsm.events[name] or { map = {} } - add_to_map(fsm.events[name].map, event) - end - - for name, callback in pairs(options.callbacks or {}) do - fsm[name] = callback - end - - return fsm + assert(options.events) + + local fsm = {} + setmetatable(fsm, machine) + + fsm.options = options + fsm.current = options.initial or 'none' + fsm.asyncState = NONE + fsm.events = {} + + for _, event in ipairs(options.events or {}) do + local name = event.name + fsm[name] = fsm[name] or create_transition(name) + fsm.events[name] = fsm.events[name] or { map = {} } + add_to_map(fsm.events[name].map, event) + end + + for name, callback in pairs(options.callbacks or {}) do + fsm[name] = callback + end + + return fsm end function machine:is(state) - return self.current == state + return self.current == state end function machine:can(e) - local event = self.events[e] - local to = event and event.map[self.current] or event.map['*'] - return to ~= nil, to + local event = self.events[e] + local to = event and event.map[self.current] or event.map['*'] + return to ~= nil, to end function machine:cannot(e) - return not self:can(e) + return not self:can(e) end function machine:todot(filename) - local dotfile = io.open(filename,'w') - dotfile:write('digraph {\n') - local transition = function(event,from,to) - dotfile:write(string.format('%s -> %s [label=%s];\n',from,to,event)) - end - for _, event in pairs(self.options.events) do - if type(event.from) == 'table' then - for _, from in ipairs(event.from) do - transition(event.name,from,event.to) - end - else - transition(event.name,event.from,event.to) + local dotfile = io.open(filename,'w') + dotfile:write('digraph {\n') + local transition = function(event,from,to) + dotfile:write(string.format('%s -> %s [label=%s];\n',from,to,event)) + end + for _, event in pairs(self.options.events) do + if type(event.from) == 'table' then + for _, from in ipairs(event.from) do + transition(event.name,from,event.to) + end + else + transition(event.name,event.from,event.to) + end end - end - dotfile:write('}\n') - dotfile:close() + dotfile:write('}\n') + dotfile:close() end function machine:transition(event) - if self.currentTransitioningEvent == event then - return self[self.currentTransitioningEvent](self) - end + if self.currentTransitioningEvent == event then + return self[self.currentTransitioningEvent](self) + end end function machine:cancelTransition(event) - if self.currentTransitioningEvent == event then - self.asyncState = NONE - self.currentTransitioningEvent = nil - end + if self.currentTransitioningEvent == event then + self.asyncState = NONE + self.currentTransitioningEvent = nil + end end machine.NONE = NONE |