-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStateMachine.lua
More file actions
156 lines (126 loc) · 4.18 KB
/
StateMachine.lua
File metadata and controls
156 lines (126 loc) · 4.18 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
-- @author: yangfch3
-- @date: 2021/04/27 11:06
------------------------------------------
local StateMachine = BaseClass("StateMachine")
function StateMachine:ctor(fsmName, config, isCacheState)
self._state_machine_name = fsmName
self._dict_states = config.DictState -- StateName -> StateClass
self._dict_state_cache = {} -- State 缓存的对象 Map
self._cur_state = nil
self._cur_state_name = "Any"
self._is_cache_state = isCacheState -- 是否缓存各个 State
self._dict_transfer = {} -- 结构 {AName = {BName = st}}
self._dict_transfer_data = {} -- 各个 st
self._transfer_dirty = false -- transfer 数据是否为脏,是否要重新运行 Transfer 判断逻辑
self:LayoutTransfer(config.StateTransferLayout)
end
-- 批量设置各个 Transfer 的判断数据
function StateMachine:SetValueDict(dict, apply)
for k, v in pairs(dict) do
self:SetValue(k, v, false)
end
if apply then
self:StateTransfer()
end
end
-- Trigger 类型的 Transfer 设置
function StateMachine:SetTrigger(key)
print("StateMachine: SetTrigger - " .. key)
self._dict_transfer_data[key] = true
self._transfer_dirty = true
self:StateTransfer()
self._dict_transfer_data[key] = false
end
-- 设置 Transfer 判断用到的值
function StateMachine:SetValue(key, value, forceApply)
self._dict_transfer_data[key] = value
self._transfer_dirty = true
if forceApply then
self:StateTransfer()
end
end
-- 关闭状态机
function StateMachine:PowerOff()
if self._cur_state then
self._cur_state:LeaveState()
self._cur_state = nil
self._cur_state_name = "Any"
end
end
----------------- ↑ 以上为核心对外方法 ---------------------
function StateMachine:LayoutTransfer(layout)
for _, transfer in ipairs(layout) do
self:AddTransfer(transfer.from, transfer.st, transfer.to)
end
end
function StateMachine:AddTransfer(from, st, to)
local dict_trans = self._dict_transfer[from] or {}
self._dict_transfer[from] = dict_trans
assert(from ~= to)
if dict_trans[to] then
error("StateMachine:AddTransfer: exist state transfer " .. from .. "->" .. to)
end
dict_trans[to] = st
end
-- 执行状态转移
function StateMachine:EvalTransfer(from)
local dict_trans = self._dict_transfer[from]
if dict_trans then
for to, st in pairs(dict_trans) do
if st(self._dict_transfer_data) then
print("StateMachine:EvalTransfer - from " .. from .. " to " .. to)
self:ChangeStateByName(to)
break
end
end
end
end
function StateMachine:StateTransfer()
if not self._transfer_dirty then
return
end
self:EvalTransfer(self._cur_state_name)
self._transfer_dirty = false
end
function StateMachine:ChangeState(state, ...)
if self._cur_state == state then
if self._cur_state then
self._cur_state:UpdateState()
end
return
end
if self._cur_state then
self._cur_state:LeaveState(state)
end
local prev_state = self._cur_state
self._cur_state = state or self._default_state
if self._cur_state then
self._cur_state:ResetState()
self._cur_state:EnterState(prev_state)
end
end
function StateMachine:ChangeStateByName(stateName, ...)
local state = self:FindState(stateName)
if state == nil then
error("StateMachine:ChangeStateByName - cannot find state " .. stateName)
end
self:ChangeState(state)
self._cur_state_name = stateName
return self._cur_state
end
function StateMachine:CreateState(stateName)
local StateClass = self._dict_states[stateName]
return StateClass.New(self, stateName)
end
function StateMachine:FindState(stateName)
local state = self._dict_state_cache[stateName]
if state ~= nil then
return state
end
state = self:CreateState(stateName)
if self._is_cache_state then
self._dict_state_cache[stateName] = state
end
return state
end
return StateMachine