Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / ui / UiBase.cs
@小李xl 小李xl on 21 Jul 2023 7 KB 通用窗体组件
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using Godot;
  5.  
  6. /// <summary>
  7. /// Ui 基类
  8. /// </summary>
  9. [Tool]
  10. public abstract partial class UiBase : Control, ICoroutine
  11. {
  12. /// <summary>
  13. /// 当前 UI 所属层级
  14. /// </summary>
  15. [Export]
  16. public UiLayer Layer = UiLayer.Middle;
  17.  
  18. /// <summary>
  19. /// ui名称
  20. /// </summary>
  21. public string UiName { get; }
  22. /// <summary>
  23. /// 是否已经打开ui
  24. /// </summary>
  25. public bool IsOpen { get; private set; } = false;
  26. /// <summary>
  27. /// 是否已经销毁
  28. /// </summary>
  29. public bool IsDisposed { get; private set; } = false;
  30.  
  31. /// <summary>
  32. /// 负责记录上一个Ui
  33. /// </summary>
  34. public UiBase PrevUi { get; set; }
  35.  
  36. //开启的协程
  37. private List<CoroutineData> _coroutineList;
  38. //嵌套打开的Ui列表
  39. private HashSet<UiBase> _nestedUiSet;
  40. //所属父级Ui, UiNode.RecordNestedUi() 嵌套打开的 Ui 将被赋予此值
  41. private UiBase _targetUi;
  42.  
  43. public UiBase(string uiName)
  44. {
  45. UiName = uiName;
  46. //记录ui打开
  47. UiManager.RecordUi(this, UiManager.RecordType.Open);
  48. }
  49.  
  50. /// <summary>
  51. /// 用于初始化打开的子Ui, 在 OnCreateUi() 之后调用
  52. /// </summary>
  53. public virtual void OnInitNestedUi()
  54. {
  55. }
  56. /// <summary>
  57. /// 创建当前ui时调用
  58. /// </summary>
  59. public virtual void OnCreateUi()
  60. {
  61. }
  62.  
  63. /// <summary>
  64. /// 当前ui显示时调用
  65. /// </summary>
  66. public virtual void OnShowUi()
  67. {
  68. }
  69.  
  70. /// <summary>
  71. /// 当前ui隐藏时调用
  72. /// </summary>
  73. public virtual void OnHideUi()
  74. {
  75. }
  76.  
  77. /// <summary>
  78. /// 销毁当前ui时调用
  79. /// </summary>
  80. public virtual void OnDisposeUi()
  81. {
  82. }
  83.  
  84. /// <summary>
  85. /// 每帧调用一次
  86. /// </summary>
  87. public virtual void Process(float delta)
  88. {
  89. }
  90.  
  91. /// <summary>
  92. /// 显示ui
  93. /// </summary>
  94. public void ShowUi()
  95. {
  96. if (IsOpen)
  97. {
  98. return;
  99. }
  100.  
  101. IsOpen = true;
  102. Visible = true;
  103. OnShowUi();
  104. //子Ui调用显示
  105. if (_nestedUiSet != null)
  106. {
  107. foreach (var uiBase in _nestedUiSet)
  108. {
  109. uiBase.ShowUi();
  110. }
  111. }
  112. }
  113. /// <summary>
  114. /// 隐藏ui, 不会执行销毁
  115. /// </summary>
  116. public void HideUi()
  117. {
  118. if (!IsOpen)
  119. {
  120. return;
  121. }
  122.  
  123. IsOpen = false;
  124. Visible = false;
  125. OnHideUi();
  126. //子Ui调用隐藏
  127. if (_nestedUiSet != null)
  128. {
  129. foreach (var uiBase in _nestedUiSet)
  130. {
  131. uiBase.HideUi();
  132. }
  133. }
  134. }
  135.  
  136. /// <summary>
  137. /// 关闭并销毁ui
  138. /// </summary>
  139. public void DisposeUi()
  140. {
  141. if (IsDisposed)
  142. {
  143. return;
  144. }
  145. //记录ui关闭
  146. UiManager.RecordUi(this, UiManager.RecordType.Close);
  147. HideUi();
  148. IsDisposed = true;
  149. OnDisposeUi();
  150. //子Ui调用销毁
  151. if (_nestedUiSet != null)
  152. {
  153. foreach (var uiBase in _nestedUiSet)
  154. {
  155. uiBase._targetUi = null;
  156. uiBase.DisposeUi();
  157. }
  158. _nestedUiSet.Clear();
  159. }
  160.  
  161. //在父Ui中移除当前Ui
  162. if (_targetUi != null)
  163. {
  164. _targetUi.RecordNestedUi(this, UiManager.RecordType.Close);
  165. }
  166. QueueFree();
  167. }
  168.  
  169. public sealed override void _Process(double delta)
  170. {
  171. if (!IsOpen)
  172. {
  173. return;
  174. }
  175. var newDelta = (float)delta;
  176. Process(newDelta);
  177. //协程更新
  178. if (_coroutineList != null)
  179. {
  180. ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
  181. }
  182. }
  183.  
  184. /// <summary>
  185. /// 记录嵌套打开/关闭的UI
  186. /// </summary>
  187. public void RecordNestedUi(UiBase uiBase, UiManager.RecordType type)
  188. {
  189. if (type == UiManager.RecordType.Open)
  190. {
  191. if (uiBase._targetUi != null && uiBase._targetUi != this)
  192. {
  193. GD.PrintErr($"子Ui:'{uiBase.UiName}'已经被其他Ui:'{uiBase._targetUi.UiName}'嵌套打开!");
  194. uiBase._targetUi.RecordNestedUi(uiBase, UiManager.RecordType.Close);
  195. }
  196. if (_nestedUiSet == null)
  197. {
  198. _nestedUiSet = new HashSet<UiBase>();
  199. }
  200.  
  201. uiBase._targetUi = this;
  202. _nestedUiSet.Add(uiBase);
  203. }
  204. else
  205. {
  206. if (uiBase._targetUi == this)
  207. {
  208. uiBase._targetUi = null;
  209. }
  210. else
  211. {
  212. GD.PrintErr($"当前Ui:'{UiName}'没有嵌套打开子Ui:'{uiBase.UiName}'!");
  213. return;
  214. }
  215. if (_nestedUiSet == null)
  216. {
  217. return;
  218. }
  219. _nestedUiSet.Remove(uiBase);
  220. }
  221. }
  222. public long StartCoroutine(IEnumerator able)
  223. {
  224. return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
  225. }
  226. public void StopCoroutine(long coroutineId)
  227. {
  228. ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
  229. }
  230. public void StopAllCoroutine()
  231. {
  232. ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
  233. }
  234. /// <summary>
  235. /// 延时指定时间调用一个回调函数
  236. /// </summary>
  237. public void CallDelay(float delayTime, Action cb)
  238. {
  239. StartCoroutine(_CallDelay(delayTime, cb));
  240. }
  241. /// <summary>
  242. /// 延时指定时间调用一个回调函数
  243. /// </summary>
  244. public void CallDelay<T1>(float delayTime, Action<T1> cb, T1 arg1)
  245. {
  246. StartCoroutine(_CallDelay(delayTime, cb, arg1));
  247. }
  248. /// <summary>
  249. /// 延时指定时间调用一个回调函数
  250. /// </summary>
  251. public void CallDelay<T1, T2>(float delayTime, Action<T1, T2> cb, T1 arg1, T2 arg2)
  252. {
  253. StartCoroutine(_CallDelay(delayTime, cb, arg1, arg2));
  254. }
  255. /// <summary>
  256. /// 延时指定时间调用一个回调函数
  257. /// </summary>
  258. public void CallDelay<T1, T2, T3>(float delayTime, Action<T1, T2, T3> cb, T1 arg1, T2 arg2, T3 arg3)
  259. {
  260. StartCoroutine(_CallDelay(delayTime, cb, arg1, arg2, arg3));
  261. }
  262.  
  263. private IEnumerator _CallDelay(float delayTime, Action cb)
  264. {
  265. yield return new WaitForSeconds(delayTime);
  266. cb();
  267. }
  268. private IEnumerator _CallDelay<T1>(float delayTime, Action<T1> cb, T1 arg1)
  269. {
  270. yield return new WaitForSeconds(delayTime);
  271. cb(arg1);
  272. }
  273. private IEnumerator _CallDelay<T1, T2>(float delayTime, Action<T1, T2> cb, T1 arg1, T2 arg2)
  274. {
  275. yield return new WaitForSeconds(delayTime);
  276. cb(arg1, arg2);
  277. }
  278. private IEnumerator _CallDelay<T1, T2, T3>(float delayTime, Action<T1, T2, T3> cb, T1 arg1, T2 arg2, T3 arg3)
  279. {
  280. yield return new WaitForSeconds(delayTime);
  281. cb(arg1,arg2, arg3);
  282. }
  283. }