123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using XGame.Framework.Asset;
- using XGame.Framework.Asyncs;
- using XGame.Framework.Interfaces;
- namespace XGame.Framework.UI
- {
- public class UIModule : IUIModule, IUpdate, ILateUpdate, IUIContextSetter, IDisposable, IUIAssetModuleCreator
- {
- private UIContext _context;
- private IUITree _uitree;
- private IAssetModule _assetModule;
- /// <summary>
- /// 加载中的
- /// </summary>
- private Dictionary<string, IAsync> _loadingMap;
- /// <summary>
- /// 已打开的UI
- /// </summary>
- private Dictionary<string, IUIView> _openedMap;
- /// <summary>
- /// 已关闭的UI
- /// </summary>
- private Dictionary<string, IUIView> _closedMap;
- /// <summary>
- /// Update 和 LateUpdate用
- /// </summary>
- private List<IUIView> _updates;
- public UIModule(IAssetModule assetModule, IUITree uitree)
- {
- _assetModule = assetModule;
- _uitree = uitree;
- _loadingMap = new Dictionary<string, IAsync>();
- _openedMap = new Dictionary<string, IUIView>();
- _closedMap = new Dictionary<string, IUIView>();
- _updates = new List<IUIView>();
- }
- public UIContext Context { get => _context; set => _context = value; }
- #region 接口实现
- Camera IUIModule.Camera => _uitree.Camera;
- Canvas IUIModule.GetCanvas(UILayer layer)
- {
- return _uitree.GetCanvas(layer);
- }
- IAsync IUIModule.OpenAsync(UIKey uikey, object intent)
- {
- string key = uikey;
- if (_loadingMap.ContainsKey(key))
- {
- return _loadingMap[key];
- }
- var asyncGroup = new AsyncGroup();
- if (_openedMap.ContainsKey(key))
- {
- Log.Warn($"重复开启UI:{key}");
- }
- else if (_closedMap.TryGetValue(key, out var closedView))
- { // 已关闭的UI
- asyncGroup.On(_ =>
- {
- _closedMap.Remove(key);
- _uitree.SetAsLastSibling(closedView.Panel);
- closedView.Enable(intent);
- _openedMap.Add(key, closedView);
- });
- }
- else
- {
- _loadingMap.Add(key, asyncGroup);
- var loadAsync = _assetModule.LoadAsync<UIPanel>(key);
- loadAsync.Join(asyncGroup);
- loadAsync.On(_ =>
- {
- _loadingMap.Remove(key);
- var panel = loadAsync.Result;
- if (panel == null)
- {
- Log.Error($"UI加载结果为空. UIKey:{key}");
- return;
- }
- var view = Activator.CreateInstance(uikey.UIViewType) as IUIView;
- var context = _context.Clone();
- (context as IUIViewAdapter).Key = uikey;
- (view as UIView).Init(context, panel);
- _uitree.AddPanel(panel);
- view.Enable(intent);
- _openedMap.Add(key, view);
- });
- }
- asyncGroup.End();
- return asyncGroup;
- }
- void IUIModule.Close(UIKey uikey, bool isDestroy)
- {
- var key = uikey.Key;
- if (_loadingMap.TryGetValue(key, out var async))
- {
- _loadingMap.Remove(key);
- async.RemoveAll();
- return;
- }
- if (_openedMap.TryGetValue(key, out var uiView))
- {
- _openedMap.Remove(key);
- uiView.Disable();
- if (isDestroy)
- {
- DestroyUIView(uiView);
- }
- else
- {
- _closedMap.Add(key, uiView);
- }
- return;
- }
- if (isDestroy && _closedMap.TryGetValue(key, out uiView))
- {
- _closedMap.Remove(key);
- DestroyUIView(uiView);
- }
- }
- IAsync IUIModule.Preload(UIKey uikey)
- {
- var loadAsync = _assetModule.PreloadAsync<UIPanel>(uikey);
- return loadAsync;
- }
- void IUpdate.Update(int millisecond)
- {
- if (_openedMap.Count == 0)
- return;
- _updates.Clear();
- _updates.AddRange(_openedMap.Values);
- for(var i = 0; i < _updates.Count;)
- {
- var view = _updates[i];
- view.Update(millisecond);
- if (view.Active)
- {
- i++;
- }
- else
- {
- _updates.RemoveAt(i);
- }
- }
- }
- void ILateUpdate.LateUpdate(int millisecond)
- {
- if (_updates.Count == 0)
- return;
- foreach (var uiview in _updates)
- {
- uiview.LateUpdate(millisecond);
- }
- _updates.Clear();
- }
- void IDisposable.Dispose()
- {
- _updates.Clear();
- foreach (var async in _loadingMap.Values)
- {
- async.RemoveAll();
- }
- _loadingMap.Clear();
- foreach (var uiview in _closedMap.Values)
- {
- DestroyUIView(uiview);
- }
- _closedMap.Clear();
- foreach (var uiview in _openedMap.Values)
- {
- DestroyUIView(uiview);
- }
- _openedMap.Clear();
- (_uitree as IDisposable)?.Dispose();
- (_assetModule as IDisposable)?.Dispose();
- _assetModule = null;
- _context = null;
- }
- IUIAssetModule IUIAssetModuleCreator.Create(UIContext context)
- {
- return new UIAssetModule(context);
- }
- #endregion
- #region 内部函数
- private void DestroyUIView(IUIView view)
- {
- var uiPanel = view.Panel as UIPanel;
- (view as IDisposable).Dispose();
- _assetModule.Recycle(uiPanel.gameObject, true);
- }
- #endregion
- }
- }
|