popupWindowQueue_modle - woodelf-treetop/rcwiki GitHub Wiki
弹窗队列系统。
主要功能:在进入游戏的时候,会在主页强制推送一些界面。目前有“七日签到界面”、“赛季结算界面”、“广告界面”。后面看需求增加或删减。
核心逻辑写在了 HudStage.lua 里。
当时第一时间想的是栈的数据形态,但是需求需要这些界面的开启有优先级,所以在存储完所有的界面后,做了优先级排序。
这里核心的接口有三个:
function HudStage:PushPanel(_panelName, _InitData, _IsAdd)
if _panelName then
self:SetPanelData(_panelName, _InitData, _IsAdd)
end
end
function HudStage:SetPanelData(_panelName, _InitData, _IsAdd)
if not openPanelData then
openPanelData = {}
openState = false
PanelOpenCount = {}
end
if not _IsAdd then
self:SetScenceAdd(_panelName)
end
-- logError("_panelName:"..tostring(_panelName))
-- logError("_IsAdd:"..tostring(_IsAdd))
if self:CheckExistOrHasOpen(_panelName) or not _IsAdd then
-- logError("This panel has been existing Or has already opened ->[HudStage.lua]")
return
end
local data = {}
if _panelName == CtrlPanelName.SeasonAccountPanel then --结算界面
data.CtrlPanelName = CtrlPanelName.SeasonAccountPanel
data.InitData = _InitData
data.PriorityLv = 4
elseif _panelName == CtrlPanelName.DailyBonusPanel then --七日签到界面
data.CtrlPanelName = CtrlPanelName.DailyBonusPanel
data.InitData = _InitData
data.PriorityLv = 1
elseif _panelName == CtrlPanelName.PushNewsPanel then --广告界面
data.CtrlPanelName = CtrlPanelName.PushNewsPanel
data.InitData = _InitData
data.PriorityLv = 2
end
PanelOpenCount[_panelName] = false
table.insert(openPanelData, data)
--按照优先级排序
if #openPanelData > 1 then
table.sort(openPanelData, function(a,b)
return a.PriorityLv > b.PriorityLv
end)
end
self:SetScenceAdd(_panelName)
endfunction HudStage:PopPanel()
if GuideManager.isShow then
-- logError("当前处于引导中")
return
end
if openState then
-- logError("当前有弹窗界面正在开启...")
return
end
local data = self:GetPanelData()
if data then
openState = true
--这里注释的目的是:当时广告界面的代码框架是旧版的。所以这里做了判断,后来又成新的ui框架了,所以就统一了Open接口
-- if data.CtrlPanelName == CtrlNames.PushNews then
-- CtrlManager.GetCtrl(CtrlNames.PushNews).Awake()
-- else
-- CtrlPanelManager.OpenPanel(data.CtrlPanelName, data.InitData)
-- end
CtrlPanelManager.OpenPanel(data.CtrlPanelName, data.InitData)
PanelOpenCount[data.CtrlPanelName] = true
self:RemoveOnePanelData(data.CtrlPanelName)
else
-- logError("暂时没有数据了")
end
end--将开着的界面的state设置为false
function HudStage.CloseOpenState()
openState = false
end- PushPanel:这里是将初始化好的界面压入这个队列里,这里需要注意的点后面会讲到。
- PopPanel:这里是将队列里优先级最高的界面取出(显示出来)。
- CloseOpenState:每一个需要展示的界面,在关闭它的时候需要调用这个函数,用来告知下次PopPanel是可行的。
这个函数用到了三个参数,_panelName 和 _InitData 是界面open的支持参数。下面着重说一下 _IsAdd的作用。
_IsAdd:由于我们预定义的开启界面不一定都会有数据,比如,不一定每天都会有广告,赛季结算的数据只有结算后才有。但是我们这个队列开始运行是在所有的界面都准备完毕了才会运行,这时不用弹出的的我们也会告知这个队列说“这个界面已经准备完毕”,只是不会有去初始化它的openPanelData。
这里就以广告为例子。
需要判断所有的条件,去选择 _IsAdd 用true还是false,这些条件都是互斥的。所以如果有新的界面需要加入到这个队列,那么需要PushPanel所有的条件。
PopPanel的启动机制,我们在所有界面全部”准备“完毕后会在SetScenceAdd函数调用PopPanel方法,所有的弹窗队列都是基于主界面的,所以当我们关闭一个弹窗界面时,会调用到主界面的 Hud_MainPanel.ReShow方法里,会再次PopPanel,直到队列里没有数据了。
还有一种情况是,我启动游戏后直接进入战场了,那么从战场回来后是第一次创建主界面,所以不会走到上述说的Hud_MainPanel.ReShow方法里,即我们需要在Hud_MainPanel.InitPanel里做PopPanel,然后直到队列里没有数据。
- 上述说的多地方调用PopPanel,这里不会引起冲突,我们用openState参数做限制。
- 在增加或者删减界面的时候,需要 ConstNum 字段做修改,设置一个等待界面个数。另外还需要在 SetPanelData 里做数据处理。