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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
/// <summary>
/// 弹窗处理器 - 负责管理游戏中的弹窗队列,按顺序显示弹窗窗口
/// 避免多个窗口同时弹出造成界面混乱
/// 只有在homewin打开的情况下才触发
/// </summary>
public class PopupWindowsProcessor : SingletonMonobehaviour<PopupWindowsProcessor>
{
    // 弹窗队列,存储待处理的弹窗请求
    List<PopupWindow> popupWindowQueue = new List<PopupWindow>();
    
    // 当前正在显示的弹窗
    PopupWindow currentWindow;
 
    // 上次弹窗时间,用于控制弹窗之间的间隔
    float lastTime = 0; //上次弹窗时间
    
    /// <summary>
    /// 添加一个弹窗到处理队列
    /// </summary>
    /// <param name="name">窗口名称</param>
    /// <param name="functionId">功能ID,用于指定窗口的具体功能或显示模式</param>
    public void Add(string name, int functionId = 0)
    {
        var popupWindow = new PopupWindow()
        {
            window = name,
            functionId = functionId,
        };
 
        if (popupWindowQueue.Contains(popupWindow))
        {
            popupWindowQueue.Remove(popupWindow);
        }
 
        popupWindowQueue.Add(popupWindow);
    }
 
    /// <summary>
    /// 从处理队列中移除指定的弹窗
    /// </summary>
    /// <param name="name">窗口名称</param>
    /// <param name="functionId">功能ID</param>
    public void Remove(string name, int functionId = 0)
    {
        var popupWindow = new PopupWindow()
        {
            window = name,
            functionId = functionId,
        };
 
        if (popupWindowQueue.Contains(popupWindow))
        {
            popupWindowQueue.Remove(popupWindow);
        }
    }
 
    /// <summary>
    /// LateUpdate中处理弹窗队列,确保在所有其他逻辑处理完毕后才显示弹窗
    /// </summary>
    private void LateUpdate()
    {
        //打开窗口需要时间,不然会导致队列中的窗口全部同时打开
        if (Time.realtimeSinceStartup - lastTime < 1)
            return;
 
        // 检查玩家是否完成登录加载
        if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
            return;
 
        // 检查是否进入游戏主场景
        if (StageManager.Instance.currentStage != StageName.Game)
        {
            return;
        }
 
        // 检查是否在新手引导中
        if (NewBieCenter.Instance.inGuiding)
        {
            return;
        }
 
        if (popupWindowQueue.Count == 0)
        {
            return;
        }
 
        // 检查是否正在显示Loading窗口
        if (UIManager.Instance.IsOpened<LoadingWin>())
            return;
 
        if (!UIManager.Instance.IsOpened<HomeWin>())
            return;
 
        if (UIManager.Instance.IsOpened(popupWindowQueue[0].window))
        {
            //当前模式可以打开多个相同窗口,增加防范
            return;
        }
 
        if (currentWindow.window != null)
        {
            //判断上一个推送是否关闭
            UIBase ui = UIManager.Instance.GetUI(currentWindow.window);
            if (ui != null && ui.IsActive())
                return;
 
        }
 
        currentWindow = popupWindowQueue[0];
        popupWindowQueue.RemoveAt(0);
        UIManager.Instance.OpenWindow(currentWindow.window, currentWindow.functionId);
        Debug.LogFormat("推送窗口 " + currentWindow.window);
 
        lastTime = Time.realtimeSinceStartup;
    }
 
    /// <summary>
    /// 弹窗结构体,用于表示一个待处理的弹窗请求
    /// 包含窗口名称和功能ID,通过这两个字段可以唯一标识一个弹窗请求
    /// </summary>
    public struct PopupWindow
    {
        // 窗口名称
        public string window;
        
        // 功能ID,用于指定窗口的具体功能或显示模式
        public int functionId;
 
        public static bool operator ==(PopupWindow lhs, PopupWindow rhs)
        {
            return lhs.window == rhs.window && lhs.functionId == rhs.functionId;
        }
 
        public static bool operator !=(PopupWindow lhs, PopupWindow rhs)
        {
            return lhs.window != rhs.window || lhs.functionId != rhs.functionId;
        }
 
        // 添加GetHashCode和Equals方法以确保结构体可以正确比较
        public override bool Equals(object obj)
        {
            if (obj is PopupWindow)
            {
                PopupWindow other = (PopupWindow)obj;
                return this.window == other.window && this.functionId == other.functionId;
            }
            return false;
        }
 
        public override int GetHashCode()
        {
            return window.GetHashCode() ^ functionId.GetHashCode();
        }
    }
 
}