miduo_client/Assets/ManagedResources/~Lua/Framework/Manager/PoolManager.lua

361 lines
10 KiB
Lua
Raw Normal View History

2020-05-09 13:31:21 +08:00
--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" then
2020-05-09 13:31:21 +08:00
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