ZMUIL5——堆栈系统
堆栈系统要做的工作
- 堆栈系统可以设置窗口弹出队列,按照设定好的顺序在特定的时机顺序弹出多个窗口
- 堆栈系统依次弹出窗口时,打开或关闭弹出队列外的窗口,不会影响堆栈系统的窗口弹出
- 堆栈系统可以在弹出窗口时,可以随时向队列内添加新的需要弹出的窗口,或者清除弹出队列,取消堆栈系统的窗口弹出
堆栈系统是任何游戏必不可少的一项功能,它可以用作诸如首次进入大厅时一些特殊或活动面板的有序自动弹出,
从而让玩家能够更好的去了解到游戏内容和新增功能。
UIModule的堆栈系统相关
堆栈系统会控制UI窗口的显示隐藏,而UIModule
负责窗口显隐的执行,因此堆栈系统主要在UIModule
内实现
堆栈系统使用队列的原因
堆栈系统实际是使用队列容器来装载要显示的窗口的,而不是栈,
因为栈是后进先出,而向堆栈系统添加要显示的面板的时间是不确定的,例如服务器发送消息的时间就不确定
如果使用后进先出的栈,假设在弹出窗口1后,窗口2和窗口3先后入栈,这会导致下一个弹出的窗口是窗口3,造成窗口弹出顺序的混乱
而队列的先进先出的顺序就很符合直觉,也不会造成弹出顺序的混乱
1 2 3
| private Queue<WindowBase> mWindowStack = new Queue<WindowBase>(); private bool mStartPopStackWindowStatus = false;
|
WindowBehaviour的堆栈系统相关
这里的PopStack
表示是否是从堆栈系统弹出的窗口,它决定隐藏该窗口时是否让堆栈系统弹出队列里的下一个窗口
PopStackListener
是窗口加入堆栈系统队列时的弹出窗口委托,当堆栈系统弹出该窗口时会执行该函数
1 2 3
| public bool PopStack { get; set; } public Action<WindowBase> PopStackListener { get; set; }
|
堆栈系统执行流程
- 使用
PushWindowToStack
方法使用泛型传入要加入队列的窗口,同时可以传入弹出窗口时执行的委托
无论界面是否已加载都先new出来,将委托赋值给这个new出来的对象的PopStackListener
,然后将它加入到队列内
- 使用
StartPopFirstStackWindow
将开启堆栈系统的窗口顺序弹出,将UIModule
的mStartPopStackWindowStatus
赋值为true
标记弹出的开始
然后调用PopStackWindow
方法
-
PopStackWindow
方法会检查队列是否拥有窗口,
如果不存在就终止堆栈系统的弹出,将mStartPopStackWindowStatus
赋值为false
如果存在,则队列弹出在PushWindowToStack
new出来的窗口,将该窗口传入堆栈系统专用PopUpWindow
方法内
之前new出来的窗口会将PopStackListener
赋值给PopUpWindow
方法弹出的窗口,将其PopStack
赋值为true
,并执行PopStackListener
的委托
- 当有窗口隐藏或销毁时,会执行
PopNextStackWindow
方法,如果关闭的这个窗口PopStack
为true
,就再次执行PopStackWindow
-
PushAndPopStackWindow
方法会在加入队列时就直接开始弹出窗口
-
ClearStackWindows
会清除队列,可以用于打断弹出队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| private WindowBase PopUpWindow(WindowBase QueuePopWindow) { System.Type type = QueuePopWindow.GetType(); string windowName = type.Name; WindowBase LoadedWindow = GetWindow(windowName); if (LoadedWindow != null) { return ShowWindow(windowName); } return InitializeWindow(QueuePopWindow, windowName); }
#region 堆栈系统相关
public void PushWindowToStack<T>(Action<WindowBase> popCallBack = null) where T : WindowBase, new() { T windowBase = new T(); windowBase.PopStackListener = popCallBack; mWindowStack.Enqueue(windowBase); }
public void StartPopFirstStackWindow() { if (mStartPopStackWindowStatus) return; mStartPopStackWindowStatus = true; PopStackWindow(); }
public void PushAndPopStackWindow<T>(Action<WindowBase> popCallBack = null) where T : WindowBase, new() { PushWindowToStack<T>(popCallBack); StartPopFirstStackWindow(); }
private void PopNextStackWindow(WindowBase windowBase) { if (windowBase != null && mStartPopStackWindowStatus && windowBase.PopStack) { windowBase.PopStack = false; PopStackWindow(); } }
public bool PopStackWindow() { if (mWindowStack.Count > 0) { WindowBase recordWindow = mWindowStack.Dequeue(); WindowBase popWindow = PopUpWindow(recordWindow); popWindow.PopStackListener = recordWindow.PopStackListener; popWindow.PopStack = true; popWindow.PopStackListener?.Invoke(popWindow); popWindow.PopStackListener = null; return true; } else { mStartPopStackWindowStatus = false; return false; } }
public void ClearStackWindows() { mWindowStack.Clear(); } #endregion
|