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