You've already forked taptap2024_GJ_chidouren
init
This commit is contained in:
@@ -0,0 +1,651 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace IcecreamView
|
||||
{
|
||||
/// <summary>
|
||||
/// icecream页面管理器,驱动页面的核心控制器,用于控制页面生成、展示、隐藏、跳转等操作
|
||||
/// </summary>
|
||||
public sealed class IC_Controller : IDisposable
|
||||
{
|
||||
public static IC_Controller InstantiateViewManager (IC_IViewConfig gameViewConfig, Transform parent)
|
||||
{
|
||||
var IC = new IC_Controller ();
|
||||
IC.Init (gameViewConfig, parent);
|
||||
return IC;
|
||||
}
|
||||
|
||||
private IC_ViewConfigGroup _config;
|
||||
private List<IC_AbstractView> _viewPool;
|
||||
public Transform BaseRoot;
|
||||
public Dictionary<int, Canvas> Canvases;
|
||||
|
||||
private int _curFocusID = 0;
|
||||
public IC_AbstractView CurFocusView { get; private set; }
|
||||
|
||||
public IC_UIEventManager EventManager { get; private set; }
|
||||
|
||||
public Action<IC_AbstractView> OnViewOpened;
|
||||
public Action<IC_AbstractView> OnViewClosed;
|
||||
public Action<IC_AbstractView> OnViewFocusChanged;
|
||||
|
||||
public void Init (IC_IViewConfig gameViewConfig, Transform baseRoot)
|
||||
{
|
||||
this._config = new IC_ViewConfigGroup ();
|
||||
this.BaseRoot = baseRoot;
|
||||
EventManager = new IC_UIEventManager ();
|
||||
this._viewPool = new List<IC_AbstractView> ();
|
||||
this.Canvases = new Dictionary<int, Canvas> ();
|
||||
this._curFocusID = 0;
|
||||
this.AddConfig (gameViewConfig);
|
||||
}
|
||||
|
||||
public void Init (IC_IViewConfig gameViewConfig, IList<CanvasNode> nodes)
|
||||
{
|
||||
this._config = new IC_ViewConfigGroup ();
|
||||
EventManager = new IC_UIEventManager ();
|
||||
this._viewPool = new List<IC_AbstractView> ();
|
||||
this.Canvases = new Dictionary<int, Canvas> ();
|
||||
foreach (var canvasNode in nodes)
|
||||
{
|
||||
this.BindCanvas (canvasNode);
|
||||
if (canvasNode.IsBaseCanvas)
|
||||
this.BaseRoot = canvasNode.Canvas.transform;
|
||||
}
|
||||
|
||||
this.AddConfig (gameViewConfig);
|
||||
}
|
||||
|
||||
#region UI Method
|
||||
|
||||
public void BindCanvas (CanvasNode canvasNode)
|
||||
{
|
||||
this.Canvases[canvasNode.OrderRange] = canvasNode.Canvas;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建一个View对象
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <param name="Table">ViewTable</param>
|
||||
/// <returns></returns>
|
||||
private IC_AbstractView CreateView (IC_IViewConfig config, string Table, string group = null)
|
||||
{
|
||||
var viewModle = config.OnAddView (Table);
|
||||
IC_AbstractView gameViewAbstract = UnityEngine.Object.Instantiate (viewModle.GetView (), this.BaseRoot);
|
||||
gameViewAbstract.VIEWTABLE = Table;
|
||||
gameViewAbstract._configID = config.GetHashCode ();
|
||||
gameViewAbstract._group = group;
|
||||
// gameViewAbstract.transform.localRotation = Quaternion.Euler(Vector3.zero);
|
||||
if (viewModle.IsOnce ())
|
||||
{
|
||||
gameViewAbstract.isOnce = viewModle.IsOnce ();
|
||||
}
|
||||
else
|
||||
{
|
||||
gameViewAbstract.isOnce = ContainsKeyView (Table);
|
||||
}
|
||||
|
||||
gameViewAbstract.openCount = 0;
|
||||
gameViewAbstract.SetViewManager (this);
|
||||
gameViewAbstract.isOpen = false;
|
||||
gameViewAbstract.OnInitView ();
|
||||
return gameViewAbstract;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定页面
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="table"></param>
|
||||
/// <returns></returns>
|
||||
public T GetView<T> (string table) where T : IC_AbstractView
|
||||
{
|
||||
if (ContainsKeyView (table))
|
||||
{
|
||||
for (int i = 0; i < this._viewPool.Count; i++)
|
||||
{
|
||||
if (table.Equals (this._viewPool[i].VIEWTABLE))
|
||||
{
|
||||
return (T) this._viewPool[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定table页面的指定Module
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T GetViewModule<T> (string table) where T : IC_AbstractModule
|
||||
{
|
||||
var View = GetView<IC_ModuleConnector> (table);
|
||||
if (View != null)
|
||||
{
|
||||
return View.GetViewModule<T> ();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IC_AbstractView OpenView (string table, string group, int sortingLayer, bool isSinge = true,
|
||||
params IC_ViewData[] values)
|
||||
{
|
||||
return OpenView (table, group, sortingLayer, isSinge, null, values);
|
||||
}
|
||||
|
||||
|
||||
public IC_AbstractView OpenView (string table, string group, int sortingLayer, bool isSinge = true, Action onOpened = null ,
|
||||
params IC_ViewData[] values)
|
||||
{
|
||||
int viewCount = getViewIndex (table, isSinge);
|
||||
//如果已经存在相同页面
|
||||
if (viewCount != -1)
|
||||
{
|
||||
var view = this._viewPool[viewCount];
|
||||
if (view.isOpen)
|
||||
{
|
||||
view.OnHardCloseView ();
|
||||
}
|
||||
|
||||
_curFocusID += 1;
|
||||
view.openCount += 1;
|
||||
view._group = group;
|
||||
view.isOpen = true;
|
||||
view.gameObject.SetActive (true);
|
||||
this.SetSortOrder (view, sortingLayer);
|
||||
view._focusID = _curFocusID;
|
||||
view.onOpened = onOpened;
|
||||
view.OnOpenView (values);
|
||||
UpdateFocusView ();
|
||||
this.OnViewOpened?.Invoke (view);
|
||||
return view;
|
||||
}
|
||||
|
||||
if (this._config.TryContainsKeyConfig (table , out var config))
|
||||
{
|
||||
IC_AbstractView gameViewAbstract = CreateView (config , table, group);
|
||||
gameViewAbstract.isOpen = true;
|
||||
gameViewAbstract.gameObject.SetActive (true);
|
||||
this.SetSortOrder (gameViewAbstract, sortingLayer);
|
||||
this._viewPool.Add (gameViewAbstract);
|
||||
this._curFocusID += 1;
|
||||
gameViewAbstract.openCount += 1;
|
||||
gameViewAbstract._focusID = this._curFocusID;
|
||||
gameViewAbstract.onOpened = onOpened;
|
||||
gameViewAbstract.OnOpenView (values);
|
||||
UpdateFocusView ();
|
||||
this.OnViewOpened?.Invoke (gameViewAbstract);
|
||||
return gameViewAbstract;
|
||||
}
|
||||
|
||||
Debug.LogFormat ("<color=yellow>{0}</color>", "IC_Controller : 打开view失败,未找到指定table --- " + table);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetSortOrder (IC_AbstractView view, int sortingLayer)
|
||||
{
|
||||
if (sortingLayer == -1)
|
||||
sortingLayer = view.DefaultStory;
|
||||
view.CurSortOrder = sortingLayer;
|
||||
Transform viewTransform;
|
||||
(viewTransform = view.transform).SetParent (GetCanvasParent (sortingLayer));
|
||||
viewTransform.localScale = Vector3.one;
|
||||
viewTransform.localPosition = Vector3.zero;
|
||||
viewTransform.localRotation = Quaternion.identity;
|
||||
Transform transform;
|
||||
(transform = view.transform).SetAsLastSibling ();
|
||||
var parent = transform.parent;
|
||||
for (int i = parent.childCount - 2; i >= 0; i--)
|
||||
{
|
||||
var tView = parent.GetChild (i).GetComponent<IC_AbstractView> ();
|
||||
if (tView is { gameObject: { activeSelf: true } })
|
||||
{
|
||||
if (view.CurSortOrder >= tView.CurSortOrder)
|
||||
break;
|
||||
else
|
||||
view.transform.SetSiblingIndex (tView.transform.GetSiblingIndex ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Transform GetCanvasParent (int order)
|
||||
{
|
||||
foreach (var canvasesKey in this.Canvases.Keys)
|
||||
{
|
||||
if (order <= canvasesKey)
|
||||
{
|
||||
return this.Canvases[canvasesKey].transform;
|
||||
}
|
||||
}
|
||||
|
||||
return this.BaseRoot;
|
||||
}
|
||||
|
||||
public IC_AbstractView OpenView (string table, int sortingLayer, bool isSinge = true,
|
||||
params IC_ViewData[] values)
|
||||
{
|
||||
return OpenView (table, null, sortingLayer, isSinge, values);
|
||||
}
|
||||
|
||||
public IC_AbstractView OpenView (string table, bool isSinge = true, params IC_ViewData[] values)
|
||||
{
|
||||
return OpenView (table, null, -1, isSinge, values);
|
||||
}
|
||||
|
||||
public IC_AbstractView OpenView (string table, bool isSinge = true, Action onOpened = null, params IC_ViewData[] values)
|
||||
{
|
||||
return OpenView (table, null, -1, isSinge, values);
|
||||
}
|
||||
|
||||
public IC_AbstractView OpenView (string table, params IC_ViewData[] values)
|
||||
{
|
||||
return OpenView (table, null, -1, true, values);
|
||||
}
|
||||
|
||||
public IC_AbstractView OpenView (string table, Action onOpened, params IC_ViewData[] values)
|
||||
{
|
||||
return OpenView (table, null, -1, true, onOpened, values);
|
||||
}
|
||||
|
||||
public IC_AbstractView OpenView (string table, string group, params IC_ViewData[] values)
|
||||
{
|
||||
return OpenView (table, group, -1, true, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭所有页面 并打开指定页面
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
/// <returns></returns>
|
||||
public IC_AbstractView OpenViewAndCloseOther (string table, bool isSinge, params IC_ViewData[] values)
|
||||
{
|
||||
if (table == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
this.CloseAllView ();
|
||||
IC_AbstractView view = OpenView (table, isSinge, values);
|
||||
return view;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提前缓存指定Table数组
|
||||
/// </summary>
|
||||
/// <param name="Tables"></param>
|
||||
internal void CacheView (List<string> Tables)
|
||||
{
|
||||
foreach (var Table in Tables)
|
||||
{
|
||||
if (this._config.TryContainsKeyConfig (Table, out var config))
|
||||
{
|
||||
var view = CreateView (config, Table);
|
||||
view.gameObject.SetActive (false);
|
||||
this._viewPool.Add (view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓存指定页面
|
||||
/// </summary>
|
||||
/// <param name="Table"></param>
|
||||
/// <returns></returns>
|
||||
internal void CacheView (string Table)
|
||||
{
|
||||
if (this._config.TryContainsKeyConfig (Table, out var config))
|
||||
{
|
||||
var view = CreateView (config, Table);
|
||||
view.gameObject.SetActive (false);
|
||||
this._viewPool.Add (view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断指定table是否存在
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
/// <returns></returns>
|
||||
public bool ContainsKeyView (string table)
|
||||
{
|
||||
for (int i = 0; i < this._viewPool.Count; i++)
|
||||
{
|
||||
if (table.Equals (this._viewPool[i].VIEWTABLE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断指定table页面是否已存在
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsOpenedView (string table)
|
||||
{
|
||||
for (int i = 0; i < this._viewPool.Count; i++)
|
||||
{
|
||||
var abstractView = this._viewPool[i];
|
||||
if (table.Equals (abstractView.VIEWTABLE) && abstractView.isOpen)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回一个指定table的View对应下标
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
/// <returns></returns>
|
||||
private int getViewIndex (string table, bool isSinge = false, bool objectType = false)
|
||||
{
|
||||
for (int i = 0; i < this._viewPool.Count; i++)
|
||||
{
|
||||
if (table.Equals (this._viewPool[i].VIEWTABLE, StringComparison.Ordinal))
|
||||
{
|
||||
if (isSinge)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
else if (this._viewPool[i].gameObject.activeSelf == objectType)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新当前焦点页面
|
||||
/// </summary>
|
||||
internal void UpdateFocusView ()
|
||||
{
|
||||
//先计算出当前焦点页面
|
||||
var focusView = _getFocusView ();
|
||||
//在比较是否与当前的焦点页面相同
|
||||
//如果相同则不做处理
|
||||
//如果不同则更新当前焦点页面
|
||||
if (ReferenceEquals (focusView, null) || focusView == CurFocusView)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var lastFocusView = CurFocusView;
|
||||
if (lastFocusView is { CurFocusState: true, isOpen: true })
|
||||
{
|
||||
lastFocusView.CurFocusState = false;
|
||||
}
|
||||
|
||||
//此处改为先通知新页面获得焦点,再通知旧页面失去焦点
|
||||
CurFocusView = focusView;
|
||||
CurFocusView.CurFocusState = true;
|
||||
CurFocusView.OnFocus (true);
|
||||
if (lastFocusView is { CurFocusState: false })
|
||||
{
|
||||
lastFocusView.OnFocus (false);
|
||||
}
|
||||
this.OnViewFocusChanged?.Invoke (CurFocusView);
|
||||
}
|
||||
|
||||
IC_AbstractView _getFocusView ()
|
||||
{
|
||||
//对所有符合规则的页面焦点ID与当前焦点ID进行比较,获得差值最小的页面
|
||||
//如果差值相同则取最后打开的页面
|
||||
IC_AbstractView view = null;
|
||||
int min = int.MaxValue;
|
||||
for (int i = 0; i < _viewPool.Count; i++)
|
||||
{
|
||||
var tempView = _viewPool[i];
|
||||
if (tempView.isOpen && tempView.hasFocusView)
|
||||
{
|
||||
var temp = Mathf.Abs (tempView._focusID - _curFocusID);
|
||||
if (temp <= min)
|
||||
{
|
||||
min = temp;
|
||||
view = tempView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭指定Table的页面
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
/// <param name="onClosed"></param>
|
||||
public void CloseView (string table , Action onClosed = null)
|
||||
{
|
||||
var count = getViewIndex (table, false, true);
|
||||
if (count == -1) return;
|
||||
_closeView (this._viewPool[count] , onClosed);
|
||||
UpdateFocusView ();
|
||||
}
|
||||
|
||||
internal void CloseViewFromView (IC_AbstractView view)
|
||||
{
|
||||
_closeView (view);
|
||||
UpdateFocusView ();
|
||||
}
|
||||
|
||||
private void _closeView (IC_AbstractView view , Action onClosed = null)
|
||||
{
|
||||
if (ReferenceEquals (view, default)) return;
|
||||
|
||||
if (!view.isOpen)
|
||||
{
|
||||
#if UNITY_EDITOR || DEBUG
|
||||
Debug.Log (view.VIEWTABLE + " view is Closed");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
_closeViewBefore (view);
|
||||
view.openCount = 0;
|
||||
view.isOpen = false;
|
||||
view.onClosed = onClosed;
|
||||
view.OnCloseView ();
|
||||
if (view._closeHook ())
|
||||
{
|
||||
view._directClose ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭指定类型的所有页面
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
public void CloseTableViews (string table)
|
||||
{
|
||||
if (table == null) return;
|
||||
for (int i = 0; i < this._viewPool.Count; i++)
|
||||
{
|
||||
if (table.Equals (this._viewPool[i].VIEWTABLE, StringComparison.Ordinal))
|
||||
{
|
||||
_closeView (_viewPool[i]);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateFocusView ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭指定Group的所有页面
|
||||
/// </summary>
|
||||
public void CloseViewWithGroup (string group)
|
||||
{
|
||||
if (group == null) return;
|
||||
for (int i = this._viewPool.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var view = this._viewPool[i];
|
||||
if (group.Equals (view.Group, StringComparison.Ordinal))
|
||||
{
|
||||
_closeView (view);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateFocusView ();
|
||||
}
|
||||
|
||||
internal void CloseViewWithConfigId (IC_IViewConfig config)
|
||||
{
|
||||
var hashCode = config.GetHashCode ();
|
||||
for (int i = this._viewPool.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var view = this._viewPool[i];
|
||||
if (view._configID == hashCode)
|
||||
{
|
||||
_closeView (view);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateFocusView ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭所有页面
|
||||
/// </summary>
|
||||
public void CloseAllView ()
|
||||
{
|
||||
for (int i = this._viewPool.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var view = this._viewPool[i];
|
||||
if (view.isOpen)
|
||||
{
|
||||
_closeView (view);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateFocusView ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 直接销毁所有View,不会触发任何生命周期
|
||||
/// </summary>
|
||||
internal void ClearAll ()
|
||||
{
|
||||
_curFocusID = 0;
|
||||
CurFocusView = null;
|
||||
this._viewPool.ForEach (view => UnityEngine.Object.Destroy (view.gameObject));
|
||||
this._viewPool.Clear ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁指定的view
|
||||
/// </summary>
|
||||
/// <param name="hash"></param>
|
||||
internal void DestroyViewAtHash (int hash)
|
||||
{
|
||||
for (int i = 0; i < this._viewPool.Count; i++)
|
||||
{
|
||||
if (this._viewPool[i].gameObject.GetHashCode () == hash)
|
||||
{
|
||||
// GameObject.Destroy(ViewPool[i].gameObject);
|
||||
this._config.OnRemoveView (this._viewPool[i]);
|
||||
this._viewPool.Remove (this._viewPool[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// /// <summary>
|
||||
// /// 重置view配置表
|
||||
// /// </summary>
|
||||
// /// <param name="viewConfig"></param>
|
||||
// /// <param name="config"></param>
|
||||
// public void ResetConfig (IC_IViewConfig viewConfig)
|
||||
// {
|
||||
// if (viewConfig == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// this.ClearAll ();
|
||||
// this._config?.OnDispose ();
|
||||
// this._config = viewConfig;
|
||||
// this._config.OnInit ();
|
||||
// //缓存页面
|
||||
// this.CacheView (this._config.GetCacheTables ());
|
||||
// if (!string.IsNullOrEmpty (this._config.GetDefaultViewTable ()))
|
||||
// {
|
||||
// OpenView (this._config.GetDefaultViewTable ());
|
||||
// }
|
||||
// }
|
||||
|
||||
public void AddConfig (IC_IViewConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._config.AddConfig (config))
|
||||
{
|
||||
config.OnInit ();
|
||||
//缓存页面
|
||||
this.CacheView (this._config.GetCacheTables ());
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveConfig (IC_IViewConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.CloseViewWithConfigId (config);
|
||||
this._config.RemoveConfig (config);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
foreach (var value in Canvases.Values)
|
||||
{
|
||||
Object.Destroy (value.gameObject);
|
||||
}
|
||||
|
||||
this.Canvases.Clear ();
|
||||
this.ClearAll ();
|
||||
this._config?.OnDispose ();
|
||||
System.GC.Collect ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 真正被销毁之前
|
||||
/// </summary>
|
||||
/// <param name="view"></param>
|
||||
internal void _closeViewBefore (IC_AbstractView view)
|
||||
{
|
||||
if (view.CurFocusState)
|
||||
{
|
||||
view.CurFocusState = false;
|
||||
// view.OnFocus (false);
|
||||
}
|
||||
|
||||
_curFocusID -= view.openCount;
|
||||
if (_curFocusID < 0)
|
||||
{
|
||||
_curFocusID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user