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

362 lines
10 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

--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