-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathStateMgr.lua
More file actions
163 lines (133 loc) · 3.58 KB
/
StateMgr.lua
File metadata and controls
163 lines (133 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
StateMgr = class("StateMgr")
function StateMgr:initialize(name)
self.name = name
self.states = {}
self.current = nil
self.thread_id = nil
self.params = {}
end
function StateMgr:getName()
return self.name
end
function StateMgr:addState(state)
self.states[state:getName()] = state
end
function StateMgr:removeStateByName(stateName)
if stateName == self.current:getName() then
return
end
self.states[stateName] = nil
end
function StateMgr:findStateByName(name)
return self.states[name]
end
function StateMgr:getCurrentState()
return self.current
end
function StateMgr:isState(stateName)
if not self.current then
return false
end
return self.current:getName() == stateName
end
function StateMgr:isStateMgrCountOut(maxCount, forState)
assert(type(maxCount) == "number", "maxCount must be a number")
forState = forState or "_Null_State_"
local state = "_StateMgrCount_"..forState
local count = self.params[state]
if type(count) == "number" then
if count >= maxCount then
return true
end
self.params[state] = count + 1
else
self.params[state] = 1
end
return false
end
function StateMgr:setTimeout(timeout)
thread.setTimeout(timeout, self.thread_id)
end
function StateMgr:clearTimeout()
thread.clearTimeout(self.thread_id)
end
function StateMgr:stop()
thread.stop(self.thread_id)
end
function StateMgr:start(params)
params = params or {}
local stateStatus = nil
assert(type(gc.taskFlow) == "table", "gc.taskFlow must be a table")
local flow = gc.taskFlow[self.name]
assert(flow, "no configuration task flow: "..self.name)
if type(gc.taskFlow.BeforeStartState) == "function" then
gc.taskFlow.BeforeStartState(params)
end
if type(flow.BeforeStartState) == "function" then
flow.BeforeStartState(params)
end
self.params = params
self.params.flow = flow
local stateName = params.stateName or flow.StartState
self.thread_id = thread.create(function()
if type(params.timeout) == "number" then
thread.setTimeout(params.timeout)
elseif type(flow.Timeout) == "number" then
thread.setTimeout(flow.Timeout)
end
while(true) do
if not self.current then
stateStatus = self:nextState(stateName)
else
local nextStateName = nil
if type(stateStatus) == "string" then
local cur = flow[self.current:getName()]
nextStateName = cur[stateStatus]
elseif type(stateStatus) == "table" and type(stateStatus._nextState) == "string" then
nextStateName = stateStatus._nextState
end
if not nextStateName then
return stateStatus
end
stateStatus = self:nextState(nextStateName)
end
end
end, {
catchBack = function(exp)
if exp.msg == "timeout" then
if State.static.stateLog then
ilog(self.name.." has been timeout!")
end
if type(params.timeoutHandler) == "function" then
stateStatus = params.timeoutHandler(self)
end
end
end
})
State.static.threadWait(thread, self.thread_id)
return stateStatus
end
function StateMgr:nextState(stateName, ...)
local nextState = self.states[stateName]
if not nextState then
nextState = State.static.createState(stateName)
nextState:setMgr(self)
self.states[stateName] = nextState
if self.current then
nextState.cache = self.current.cache
end
end
ilog("------------------------------------", false)
if not self.current then
self.current = nextState
return self.current:start(self.current.enteredState)
else
if self.current == nextState then
return self.current:start(self.current.reenteredState)
else
self.current:exitedState(...)
self.current = nextState
return self.current:start(self.current.enteredState)
end
end
end