You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
5.1 KiB
Lua
235 lines
5.1 KiB
Lua
local setmetatable = setmetatable
|
|
local pairs = pairs
|
|
|
|
---
|
|
---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 _ = 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(_)
|
|
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
|