-
Notifications
You must be signed in to change notification settings - Fork 2
/
pool.lua
231 lines (203 loc) · 5.08 KB
/
pool.lua
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
---
---Table pool for lua
---
---@class Pool
---@field public DEFAULT_TAG string @default object tag for pool
---@field private _ctorHandle table<string, function>
---@field private _pools table<string, table[]>
local Pool = {}
local DEFAULT_TAG = "__"
Pool.DEFAULT_TAG = DEFAULT_TAG
Pool.__index = Pool
setmetatable(
Pool,
{
__call = function(class, opt)
local instance = {}
setmetatable(instance, Pool)
instance:new(opt)
return instance
end
}
)
---@param pool Pool
---@param tag string
---@param create boolean
local function getPoolArr(pool, tag, create)
local poolArr = pool._pools[tag]
if not poolArr and create then
poolArr = {}
pool._pools[tag] = poolArr
end
return poolArr
end
---@param pool Pool
---@param tag string
local function createInstance(pool, tag)
tag = tag or DEFAULT_TAG
local ctorHandle = pool._ctorHandle[tag]
if ctorHandle then
return ctorHandle()
else
return {}
end
end
---@param pool Pool
---@param tag string
---@vararg any
local function getFromPool(pool, tag, ...)
local ins = nil
if pool._pools[tag] then
local poolArr = pool._pools[tag]
if #poolArr > 0 then
ins = poolArr[#poolArr]
poolArr[#poolArr] = nil
end
end
if not ins then
ins = createInstance(pool, tag)
end
if ins.awakeFromPool then
ins:awakeFromPool(...)
end
return ins
end
---@param pool Pool
---@param tag string
---@param t string
---@vararg any
local function recycleToPool(pool, tag, t, ...)
local poolArr = getPoolArr(pool, tag, true)
poolArr[#poolArr + 1] = t
if t.recycleToPool then
t:recycleToPool(...)
end
end
---@param pool Pool
---@param tag string
---@param clearCtorHandle boolean
local function clearPool(pool, tag, clearCtorHandle)
pool._pools[tag] = nil
if clearCtorHandle then
pool._ctorHandle[tag] = nil
end
end
---@private
function Pool:new(opt)
self._ctorHandle = {}
self._pools = {}
if opt then
if opt.ctor then
for k, v in pairs(opt.ctor) do
self._ctorHandle[k] = v
end
end
if opt.presize then
for k, v in pairs(opt.presize) do
self:presize(v, k)
end
end
end
end
---
---Set table constructor handle for object
---when get a table from pool, if there isn't a table in pool,
---will use this constructor handle to create new one and return it.
---@public
---@param handle function @create object handle
---@param tag string @[option] object tag
function Pool:setCtorHandle(handle, tag)
tag = tag or DEFAULT_TAG
self._ctorHandle[tag] = handle
end
---
---Get table from pool
---if table has a awakeFromPool function,
---will call this function with parameters by pass.
---@public
---@vararg any
---@return table
function Pool:get(...)
return getFromPool(self, DEFAULT_TAG, ...)
end
---
---Get table from pool with object tag
---if table has a awakeFromPool function,
---will call taht function with parameters by pass.
---@public
---@param tag string
---@vararg any
---@return table
function Pool:getWithTag(tag, ...)
return getFromPool(self, tag, ...)
end
---
---Recycle table to pool
---if table has a recycleToPool function,
---will call that function with parameters by pass.
---@public
---@param t table
---@vararg any
function Pool:recycle(t, ...)
recycleToPool(self, DEFAULT_TAG, t, ...)
end
---
---Recycle table to pool with object tag
---if table has a recycleToPool function,
---will call that function with parameters by pass.
---@public
---@param t table
---@param tag string
---@vararg any
function Pool:recycleWithTag(t, tag, ...)
recycleToPool(self, tag, t, ...)
end
---
---Pre create some table with an option object tag.
---@public
---@param count number
---@param tag string @[option] object tag
---@return boolean
function Pool:presize(count, tag)
local poolArr = getPoolArr(self, tag or DEFAULT_TAG, true)
if #poolArr >= count then
return false
end
local needCreateSize = count - #poolArr
local ctorHandle = self._ctorHandle[tag]
local createFunction = ctorHandle and function()
return ctorHandle()
end or function()
return {}
end
for i = 1, needCreateSize do
poolArr[#poolArr + 1] = createFunction()
end
return true
end
---
---Clear objects in pool
---@public
---@param clearCtorHandle boolean @default false
function Pool:clear(clearCtorHandle)
clearCtorHandle = clearCtorHandle or false
clearPool(self, DEFAULT_TAG, clearCtorHandle)
end
---
---Clear all objects in pool
---@public
---@param clearCtorHandle boolean @default false
function Pool:clearAll(clearCtorHandle)
self._pools = {}
self._ctorHandle = {}
end
---
---Clear all objects with an object tag in pool
---@public
---@param tag string
---@param clearCtorHandle boolean @default false
function Pool:clearTag(tag, clearCtorHandle)
clearCtorHandle = clearCtorHandle or false
clearPool(self, tag, clearCtorHandle)
end
return Pool