362 lines
10 KiB
Lua
362 lines
10 KiB
Lua
--region *.lua
|
||
--Date
|
||
--此文件由[BabeLua]插件自动生成
|
||
PoolManager = quick_class("PoolManager")
|
||
|
||
PoolManager.AssetType = {
|
||
MediaUI = 1,
|
||
MediaBg = 2,
|
||
Texture = 3,
|
||
GameObject = 4,
|
||
Other = 5,
|
||
}
|
||
|
||
PoolManager.mClearTime_Idle = 100
|
||
PoolManager.mClearTime_Busy = 10
|
||
PoolManager.mMaxPoolSize = 30
|
||
PoolManager.enableRecycle = true
|
||
|
||
function PoolManager:ctor()
|
||
self:init()
|
||
end
|
||
|
||
function PoolManager:Update()
|
||
self.mFrameTimer = self.mFrameTimer + 1
|
||
if PoolManager.enableRecycle
|
||
and self.mFrameTimer % self.mClearTime == 0 then
|
||
self:RemoveEarliesItem()
|
||
end
|
||
end
|
||
|
||
function PoolManager:init()
|
||
self.mPoolTable = {}
|
||
self.mLiveTable = {}
|
||
self.mPoolNode = GameObject("PoolNode")
|
||
GameObject.DontDestroyOnLoad(self.mPoolNode)
|
||
self.mPoolTrans = self.mPoolNode.transform
|
||
self.mPoolNode:SetActive(false)
|
||
self.mFrameTimer = 0
|
||
--清理间隔
|
||
self.mClearTime = PoolManager.mClearTime_Idle
|
||
self.mPoolSize = PoolManager.mMaxPoolSize
|
||
|
||
LateUpdateBeat:Add(self.Update,self)
|
||
end
|
||
|
||
function PoolManager:onDestroy()
|
||
for outIndex,gameData in pairs(self.mPoolTable) do
|
||
if gameData.resList then
|
||
for _,data in ipairs(gameData.resList) do
|
||
if gameData.useInstantiate then
|
||
GameObject.DestroyImmediate(data)
|
||
end
|
||
end
|
||
gameData.resList = {}
|
||
end
|
||
resMgr:UnLoadAsset(outIndex)
|
||
gameData.refCount = 0
|
||
end
|
||
self.mPoolTable = {}
|
||
GameObject.DestroyImmediate(self.mPoolNode)
|
||
end
|
||
|
||
function PoolManager:SetRecycleState( state)
|
||
|
||
PoolManager.enableRecycle = state
|
||
end
|
||
|
||
--[[
|
||
预加载资源
|
||
|
||
]]
|
||
function PoolManager:PreLoadAsset(resName,num, assetType, func)
|
||
local tempTable = self.mPoolTable[resName]
|
||
if tempTable == nil then
|
||
tempTable = {}
|
||
tempTable.resList = {}
|
||
tempTable.useFrame = 0
|
||
tempTable.refCount = 0
|
||
tempTable.useInstantiate = false
|
||
self.mPoolTable[resName] = tempTable
|
||
end
|
||
|
||
resMgr:LoadAssetAsync(resName,function(name,Obj)
|
||
if Obj ~= nil then
|
||
local index = 1
|
||
local resObj = nil
|
||
|
||
if assetType == PoolManager.AssetType.GameObject then
|
||
while index <= num do
|
||
|
||
resObj = GameObject.Instantiate(Obj)
|
||
resObj:SetActive(true)
|
||
resObj.transform:SetParent(self.mPoolTrans)
|
||
tempTable.useInstantiate = true
|
||
|
||
table.insert(tempTable.resList,resObj)
|
||
index = index + 1
|
||
tempTable.refCount = tempTable.refCount + 1
|
||
end
|
||
else
|
||
table.insert(tempTable.resList,Obj)
|
||
tempTable.refCount = tempTable.refCount + 1
|
||
end
|
||
tempTable.activeTime = self.mFrameTimer
|
||
end
|
||
if func then
|
||
func()
|
||
end
|
||
end)
|
||
|
||
end
|
||
|
||
function PoolManager:LoadAsset(resName, assetType)
|
||
local tempTable = self.mPoolTable[resName]
|
||
if tempTable == nil then
|
||
tempTable = {}
|
||
tempTable.resList = {}
|
||
tempTable.preLoadCount = 0
|
||
tempTable.usedFrame = 0
|
||
tempTable.useInstantiate = false
|
||
tempTable.refCount = 0
|
||
self.mPoolTable[resName] = tempTable
|
||
end
|
||
local resObj = nil
|
||
if #tempTable.resList > 0 then
|
||
resObj = tempTable.resList[#tempTable.resList]
|
||
--只有GameObject需要被回收,其他类型的资源只用缓存
|
||
if assetType == PoolManager.AssetType.GameObject then
|
||
table.remove(tempTable.resList,#tempTable.resList)
|
||
end
|
||
else
|
||
local _obj = resMgr:LoadAsset(resName)
|
||
if _obj == nil then
|
||
Log("resource is nil! error:"..resName)
|
||
resMgr:UnLoadAsset(resName)
|
||
return nil
|
||
end
|
||
|
||
if assetType == PoolManager.AssetType.GameObject then
|
||
resObj = GameObject.Instantiate(_obj)
|
||
resObj:SetActive(true)
|
||
tempTable.useInstantiate = true
|
||
else
|
||
resObj = _obj
|
||
--缓存非GameObject资源
|
||
table.insert(tempTable.resList,resObj)
|
||
end
|
||
|
||
end
|
||
tempTable.refCount = tempTable.refCount + 1
|
||
tempTable.activeTime = self.mFrameTimer
|
||
return resObj
|
||
end
|
||
|
||
function PoolManager:LoadAssetAsync(resName, assetType, callBack)
|
||
local tempTable = self.mPoolTable[resName]
|
||
if tempTable == nil then
|
||
tempTable = {}
|
||
tempTable.resList = {}
|
||
tempTable.preLoadCount = 0
|
||
tempTable.usedFrame = 0
|
||
tempTable.useInstantiate = false
|
||
tempTable.refCount = 0
|
||
self.mPoolTable[resName] = tempTable
|
||
end
|
||
|
||
resMgr:LoadAssetAsync(resName, function(name,Obj)
|
||
if Obj ~= nil then
|
||
local resObj = nil
|
||
|
||
if assetType == PoolManager.AssetType.GameObject then
|
||
resObj = GameObject.Instantiate(Obj)
|
||
resObj:SetActive(true)
|
||
tempTable.useInstantiate = true
|
||
else
|
||
resObj = Obj
|
||
--缓存非GameObject资源
|
||
table.insert(tempTable.resList,resObj)
|
||
end
|
||
|
||
tempTable.refCount = tempTable.refCount + 1
|
||
tempTable.activeTime = self.mFrameTimer
|
||
end
|
||
if callBack then
|
||
callBack(Obj)
|
||
end
|
||
end)
|
||
end
|
||
|
||
--[[
|
||
resName
|
||
res:real res Object
|
||
]]
|
||
function PoolManager:UnLoadAsset(resName,res, assetType)
|
||
local pool = self.mPoolTable[resName]
|
||
if pool == nil or pool.resList == nil then
|
||
return
|
||
end
|
||
|
||
--if assetType ~= PoolManager.AssetType.Texture
|
||
-- and assetType ~= PoolManager.AssetType.MediaBg
|
||
-- and assetType ~= PoolManager.AssetType.MediaUI
|
||
--then
|
||
if assetType == PoolManager.AssetType.GameObject
|
||
and res
|
||
and tostring(res) ~= "null"
|
||
and not IsNull(res) then
|
||
res.transform:SetParent(self.mPoolTrans)
|
||
if #pool.resList <= 5 then
|
||
table.insert(pool.resList,res)
|
||
else
|
||
GameObject.DestroyImmediate(res)
|
||
end
|
||
end
|
||
pool.refCount = pool.refCount -1
|
||
end
|
||
|
||
function PoolManager:RemoveEarliesItem()
|
||
local poolCount = table.nums(self.mPoolTable)
|
||
if poolCount < self.mPoolSize then
|
||
self.mClearTime = PoolManager.mClearTime_Idle
|
||
return
|
||
end
|
||
self.mClearTime = PoolManager.mClearTime_Busy
|
||
--logWarn("Pool Update --" .. poolCount .. " -- " .. self.mFrameTimer)
|
||
|
||
local earliestTime = 2147483647
|
||
local removedResName = nil
|
||
local removedIndex = -1
|
||
local index = 1
|
||
local pool = nil
|
||
for k,v in pairs(self.mPoolTable) do
|
||
|
||
if v.refCount < 1 then
|
||
if v.activeTime ~= nil
|
||
and v.activeTime < earliestTime
|
||
then
|
||
earliestTime = v.activeTime
|
||
removedResName = k
|
||
removedIndex = index
|
||
pool = v
|
||
end
|
||
end
|
||
index = index +1
|
||
end
|
||
|
||
if removedResName == nil or pool == nil then
|
||
if self.mPoolSize < PoolManager.mMaxPoolSize then
|
||
self.mPoolSize = PoolManager.mMaxPoolSize
|
||
end
|
||
return
|
||
end
|
||
|
||
if pool.useInstantiate then
|
||
if pool.useInstantiate
|
||
and pool.resList ~= nil
|
||
and table.nums( pool.resList ) > 0
|
||
then
|
||
for _,data in ipairs(pool.resList) do
|
||
if data ~= nil then
|
||
GameObject.DestroyImmediate(data)
|
||
end
|
||
end
|
||
end
|
||
pool.resList = nil
|
||
end
|
||
--table.remove(self.mPoolTable)
|
||
self.mPoolTable[removedResName] = nil
|
||
resMgr:UnLoadAsset(removedResName)
|
||
--logWarn("Remove Pool item:" .. removedResName)
|
||
--logWarn("Objects in Pool!!!" .. table.nums(self.mPoolTable))
|
||
end
|
||
|
||
function PoolManager:ClearPool()
|
||
self.mPoolSize = 0
|
||
self.mClearTime = 1
|
||
end
|
||
|
||
function PoolManager:LoadLive(liveName, parent, scaleV3, posV3, onClear)
|
||
local testLive = self:LoadAsset(liveName, PoolManager.AssetType.GameObject)
|
||
if testLive then
|
||
testLive.transform:SetParent(parent)
|
||
testLive.transform.localScale = scaleV3
|
||
testLive.transform.localPosition = posV3
|
||
testLive.name = liveName
|
||
testLive:SetActive(true)
|
||
local SkeletonGraphic = testLive:GetComponent("SkeletonGraphic")
|
||
SkeletonGraphic.color = Color.New(1,1,1,1)
|
||
end
|
||
if not self.mLiveTable[liveName] then
|
||
self.mLiveTable[liveName] = {}
|
||
end
|
||
table.insert(self.mLiveTable[liveName], {live = testLive, call = onClear})
|
||
return testLive
|
||
end
|
||
|
||
--设置清理回调,当live对象被回收到对象池中,触发清理回调
|
||
function PoolManager:SetLiveClearCall(resName, res, onClear)
|
||
if self.mLiveTable[resName] then
|
||
local item
|
||
for i=1, #self.mLiveTable[resName] do
|
||
item = self.mLiveTable[resName][i]
|
||
if item.live == res then
|
||
item.call = onClear
|
||
break
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function PoolManager:UnLoadLive(resName, res)
|
||
self:UnLoadAsset(resName, res, PoolManager.AssetType.GameObject)
|
||
if self.mLiveTable[resName] then
|
||
local item
|
||
for i=1, #self.mLiveTable[resName] do
|
||
item = self.mLiveTable[resName][i]
|
||
if item.live == res then
|
||
if item.call then
|
||
item.call()
|
||
end
|
||
table.remove(self.mLiveTable[resName], i)
|
||
break
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
--卸载对应游戏内存池的资源
|
||
--[[
|
||
resName: 可选
|
||
]]
|
||
function PoolManager:UnLoadGameAsset(resName)
|
||
for outIndex, gameData in pairs(self.mPoolTable) do
|
||
local tempIndex = 1
|
||
for index, assetData in pairs(gameData) do
|
||
if not resName or resName == index then
|
||
if assetData.resList then
|
||
for _,data in ipairs(assetData.resList) do
|
||
if assetData.useInstantiate then
|
||
GameObject.DestroyImmediate(data)
|
||
end
|
||
end
|
||
end
|
||
if assetData.game then
|
||
for i = 1, assetData.refCount do
|
||
resMgr:UnLoadAsset(assetData.game, index)
|
||
end
|
||
end
|
||
|
||
assetData.refCount = 0
|
||
assetData.resList = {}
|
||
-- deleteTable[#deleteTable + 1] = tempIndex
|
||
end
|
||
tempIndex = tempIndex + 1
|
||
end
|
||
end
|
||
|
||
end
|
||
|
||
|
||
--endregion
|