using Cysharp.Threading.Tasks; using Framework; using Gameplay.FunctionLock; using PhxhSDK; using System.Collections.Generic; namespace Gameplay.PopUp { /// /// 弹窗管理器 /// public class PopUpManager : Singlenton, IInitable { /// /// 所有等待弹窗集合 /// private HashSet setPopUp; /// /// 弹窗队列字典,key:触发的UI名,value:弹窗队列 /// private Dictionary> dicPopUpQueue; /// /// 记录当前触发的弹窗UI名 /// private string curUIName; /// /// 缓存等待移除的弹窗(触发成功的弹窗缓存到这里等待移除) /// private HashSet setCacheNeedRemovePopUp; public void Init() { setPopUp = new HashSet(); dicPopUpQueue = new Dictionary>(); setCacheNeedRemovePopUp = new HashSet(); EventManager.Instance.Register(EventManager.EventName.UIOpenByAnimComplete, OnUIOpenByaAnimComplte); EventManager.Instance.Register(EventManager.EventName.UIClose, OnUIClose); } public void Release() { EventManager.Instance.Unregister(EventManager.EventName.UIClose, OnUIClose); EventManager.Instance.Unregister(EventManager.EventName.UIOpenByAnimComplete, OnUIOpenByaAnimComplte); if (null != dicPopUpQueue) { foreach (var i in dicPopUpQueue.Values) { i.Clear(); } dicPopUpQueue.Clear(); } setPopUp?.Clear(); setCacheNeedRemovePopUp?.Clear(); } /// /// 添加弹窗 /// public void AddPopUp(IPopUp newPopUp) { if (null == newPopUp) return; if (setPopUp.Contains(newPopUp)) return; setPopUp.Add(newPopUp); foreach (string triggerUIName in newPopUp.TriggerUINames) { AddPopUpByUIName(triggerUIName, newPopUp); } if (UIManager.Instance.IsWindowOpening(UINameConst.UI_MainPanel)) TriggerPopUp(UINameConst.UI_MainPanel); } /// /// 移除弹窗 /// /// public bool RemovePopUp(IPopUp removePopUp) { if (!setPopUp.Contains(removePopUp)) return false; foreach (string uiName in removePopUp.TriggerUINames) { RemovePopUpUIName(uiName, removePopUp); } return setPopUp.Remove(removePopUp); } #region 私有方法 /// /// 根据UI名添加弹窗 /// /// /// private void AddPopUpByUIName(string uiName, IPopUp newPopUp) { if (!dicPopUpQueue.TryGetValue(uiName, out LinkedList linkPopUp)) { linkPopUp = new LinkedList(); dicPopUpQueue.Add(uiName, linkPopUp); } if (linkPopUp.Count <= 0) { linkPopUp.AddLast(newPopUp); return; } LinkedListNode nodePopUp = linkPopUp.First; while (null != nodePopUp && null != nodePopUp.Value) { if (nodePopUp.Value.Priority > newPopUp.Priority) // 根据优先级排序 { linkPopUp.AddBefore(nodePopUp, newPopUp); return; } nodePopUp = nodePopUp.Next; } linkPopUp.AddLast(newPopUp); } /// /// 根据UI名移除弹窗 /// /// /// private void RemovePopUpUIName(string uiName, IPopUp removePopUp) { if (!dicPopUpQueue.TryGetValue(uiName, out LinkedList linkPopUp)) return; linkPopUp.Remove(removePopUp); } /// /// 触发弹窗 /// /// 触发类型 private async void TriggerPopUp(string uiName) { if (!dicPopUpQueue.TryGetValue(uiName, out LinkedList linkPopUp)) // 不存在弹窗 return; if (linkPopUp.Count <= 0) // 无弹窗 return; if (setCacheNeedRemovePopUp.Count > 0) return; UIWindow uiWindow = UIManager.Instance.GetOpenedWindowByPath(uiName); if (null == uiWindow) return; if (uiWindow.IsHide()) return; foreach (IPopUp popUp in linkPopUp) { if (!setPopUp.Contains(popUp)) // 不存在该弹窗,或者已经弹窗过 continue; if (!await popUp.PopUp()) // 开始弹窗 continue; setCacheNeedRemovePopUp.Add(popUp); // 记录需要移除的弹窗 curUIName = uiName; if (!popUp.IsSameTimePopUp) // 不能同时弹窗则跳出 break; } foreach (IPopUp popUp in setCacheNeedRemovePopUp) { setPopUp.Remove(popUp); linkPopUp.Remove(popUp); } } /// /// UI打开完成 /// /// private async void OnUIOpenByaAnimComplte(string uiName) { await UniTask.WaitUntil(() => { return !FunctionLockManager.Instance.IsPlayingUnlockAnim; }); TriggerPopUp(uiName); } private void OnUIClose(string uiName) { IPopUp popUp = null; foreach (IPopUp temp in setCacheNeedRemovePopUp) { if (temp.PopUpUIName == uiName) { popUp = temp; break; } } setCacheNeedRemovePopUp.Remove(popUp); if (setCacheNeedRemovePopUp.Count < 0) TriggerPopUp(curUIName); } #endregion } }