using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using TEngine;
using UnityEngine;
namespace GameLogic
{
///
/// UI基类。
///
public class UIBase
{
///
/// UI类型。
///
public enum UIType
{
///
/// 类型无。
///
None,
///
/// 类型Windows。
///
Window,
///
/// 类型Widget。
///
Widget,
}
///
/// 所属UI父节点。
///
protected UIBase _parent = null;
///
/// UI父节点。
///
public UIBase Parent => _parent;
///
/// 自定义数据集。
///
protected System.Object[] _userDatas;
///
/// 自定义数据。
///
public System.Object UserData
{
get
{
if (_userDatas != null && _userDatas.Length >= 1)
{
return _userDatas[0];
}
else
{
return null;
}
}
}
///
/// 自定义数据集。
///
public System.Object[] UserDatas => _userDatas;
///
/// 窗口的实例资源对象。
///
// ReSharper disable once InconsistentNaming
public virtual GameObject gameObject { protected set; get; }
///
/// 窗口位置组件。
///
// ReSharper disable once InconsistentNaming
public virtual Transform transform { protected set; get; }
///
/// 窗口矩阵位置组件。
///
// ReSharper disable once InconsistentNaming
public virtual RectTransform rectTransform { protected set; get; }
///
/// UI类型。
///
public virtual UIType Type => UIType.None;
///
/// 资源是否准备完毕。
///
public bool IsPrepare { protected set; get; }
///
/// UI子组件列表。
///
internal readonly List ListChild = new List();
///
/// 存在Update更新的UI子组件列表。
///
protected List _listUpdateChild = null;
///
/// 是否持有Update行为。
///
protected bool _updateListValid = false;
///
/// 代码自动生成绑定。
///
protected virtual void ScriptGenerator()
{
}
///
/// 绑定UI成员元素。
///
protected virtual void BindMemberProperty()
{
}
///
/// 注册事件。
///
protected virtual void RegisterEvent()
{
}
///
/// 窗口创建。
///
protected virtual void OnCreate()
{
}
///
/// 窗口刷新。
///
protected virtual void OnRefresh()
{
}
///
/// 是否需要Update。
///
protected bool _hasOverrideUpdate = true;
///
/// 窗口更新。
///
protected virtual void OnUpdate()
{
_hasOverrideUpdate = false;
}
internal void CallDestroy()
{
OnDestroy();
}
///
/// 窗口销毁。
///
protected virtual void OnDestroy()
{
}
///
/// 当触发窗口的层级排序。
///
protected virtual void OnSortDepth(int depth)
{
}
///
/// 当因为全屏遮挡触或者窗口可见性触发窗口的显隐。
///
protected virtual void OnSetVisible(bool visible)
{
}
internal void SetUpdateDirty()
{
_updateListValid = false;
if (Parent != null)
{
Parent.SetUpdateDirty();
}
}
#region FindChildComponent
public Transform FindChild(string path)
{
return FindChildImp(rectTransform, path);
}
public Transform FindChild(Transform trans, string path)
{
return FindChildImp(trans, path);
}
public T FindChildComponent(string path) where T : Component
{
return FindChildComponentImp(rectTransform, path);
}
public T FindChildComponent(Transform trans, string path) where T : Component
{
return FindChildComponentImp(trans, path);
}
private static Transform FindChildImp(Transform transform, string path)
{
var findTrans = transform.Find(path);
return findTrans != null ? findTrans : null;
}
private static T FindChildComponentImp(Transform transform, string path) where T : Component
{
var findTrans = transform.Find(path);
if (findTrans != null)
{
return findTrans.gameObject.GetComponent();
}
return null;
}
#endregion
#region UIEvent
private GameEventMgr _eventMgr;
protected GameEventMgr EventMgr
{
get
{
if (_eventMgr == null)
{
_eventMgr = MemoryPool.Acquire();
}
return _eventMgr;
}
}
public void AddUIEvent(int eventType, Action handler)
{
EventMgr.AddEvent(eventType, handler);
}
protected void AddUIEvent(int eventType, Action handler)
{
EventMgr.AddEvent(eventType, handler);
}
protected void AddUIEvent(int eventType, Action handler)
{
EventMgr.AddEvent(eventType, handler);
}
protected void AddUIEvent(int eventType, Action handler)
{
EventMgr.AddEvent(eventType, handler);
}
protected void AddUIEvent(int eventType, Action handler)
{
EventMgr.AddEvent(eventType, handler);
}
protected void RemoveAllUIEvent()
{
if (_eventMgr != null)
{
MemoryPool.Release(_eventMgr);
}
}
#endregion
#region UIWidget
///
/// 创建UIWidget通过父UI位置节点。
/// 因为资源实例已经存在父物体所以不需要异步。
///
/// 父UI位置节点。
/// 是否可见。
/// UIWidget。
/// UIWidget实例。
public T CreateWidget(string goPath, bool visible = true) where T : UIWidget, new()
{
var goRootTrans = FindChild(goPath);
if (goRootTrans != null)
{
return CreateWidget(goRootTrans.gameObject, visible);
}
return null;
}
///
/// 创建UIWidget通过父UI位置节点。
/// 因为资源实例已经存在父物体所以不需要异步。
///
///
/// 父UI位置节点。
/// 是否可见。
/// UIWidget。
/// UIWidget实例。
public T CreateWidget(Transform parentTrans, string goPath, bool visible = true) where T : UIWidget, new()
{
var goRootTrans = FindChild(parentTrans, goPath);
if (goRootTrans != null)
{
return CreateWidget(goRootTrans.gameObject, visible);
}
return null;
}
///
/// 创建UIWidget通过游戏物体。
/// 因为资源实例已经存在父物体所以不需要异步。
///
/// 游戏物体。
/// 是否可见。
/// UIWidget。
/// UIWidget实例。
public T CreateWidget(GameObject goRoot, bool visible = true) where T : UIWidget, new()
{
var widget = new T();
if (widget.Create(this, goRoot, visible))
{
return widget;
}
return null;
}
///
/// 创建UIWidget通过资源定位地址。
///
/// 资源父节点。
/// 资源定位地址。
/// 是否可见。
/// UIWidget。
/// UIWidget实例。
public T CreateWidgetByPath(Transform parentTrans, string assetLocation, bool visible = true) where T : UIWidget, new()
{
GameObject goInst = UIModule.Resource.LoadGameObject(assetLocation, parent: parentTrans);
return CreateWidget(goInst, visible);
}
///
/// 创建UIWidget通过资源定位地址。
///
/// 资源父节点。
/// 资源定位地址。
/// 是否可见。
/// UIWidget。
/// UIWidget实例。
public async UniTask CreateWidgetByPathAsync(Transform parentTrans, string assetLocation, bool visible = true) where T : UIWidget, new()
{
GameObject goInst = await UIModule.Resource.LoadGameObjectAsync(assetLocation, parentTrans, gameObject.GetCancellationTokenOnDestroy());
return CreateWidget(goInst, visible);
}
///
/// 根据prefab或者模版来创建新的 widget。
///
/// 资源创建副本。
/// 资源父节点。
/// 是否可见。
/// UIWidget。
/// UIWidget实例。
public T CreateWidgetByPrefab(GameObject goPrefab, Transform parentTrans = null, bool visible = true) where T : UIWidget, new()
{
var widget = new T();
if (!widget.CreateByPrefab(this, goPrefab, parentTrans, visible))
{
return null;
}
return widget;
}
///
/// 通过UI类型来创建widget。
///
/// 资源父节点。
/// 是否可见。
/// UIWidget。
/// UIWidget实例。
public T CreateWidgetByType(Transform parentTrans, bool visible = true) where T : UIWidget, new()
{
return CreateWidgetByPath(parentTrans, typeof(T).Name, visible);
}
///
/// 通过UI类型来创建widget。
///
/// 资源父节点。
/// 是否可见。
/// UIWidget。
/// UIWidget实例。
public async UniTask CreateWidgetByTypeAsync(Transform parentTrans, bool visible = true) where T : UIWidget, new()
{
return await CreateWidgetByPathAsync(parentTrans, typeof(T).Name, visible);
}
///
/// 调整图标数量。
///
/// 常用于Icon创建。
/// 存放Icon的列表。
/// 创建数目。
/// 资源父节点。
/// 资产副本。
/// 资产地址。
/// 图标类型。
public void AdjustIconNum(List listIcon, int number, Transform parentTrans, GameObject prefab = null, string assetPath = "")
where T : UIWidget, new()
{
if (listIcon == null)
{
listIcon = new List();
}
if (listIcon.Count < number)
{
int needNum = number - listIcon.Count;
for (int iconIdx = 0; iconIdx < needNum; iconIdx++)
{
T tmpT = prefab == null ? CreateWidgetByType(parentTrans) : CreateWidgetByPrefab(prefab, parentTrans);
listIcon.Add(tmpT);
}
}
else if (listIcon.Count > number)
{
RemoveUnUseItem(listIcon, number);
}
}
///
/// 异步调整图标数量。
///
///
///
///
///
///
///
///
///
public void AsyncAdjustIconNum(List listIcon, int tarNum, Transform parentTrans, GameObject prefab = null,
string assetPath = "", int maxNumPerFrame = 5,
Action updateAction = null) where T : UIWidget, new()
{
AsyncAdjustIconNumInternal(listIcon, tarNum, parentTrans, maxNumPerFrame, updateAction, prefab, assetPath).Forget();
}
///
/// 异步创建接口。
///
///
///
///
///
///
///
///
///
private async UniTaskVoid AsyncAdjustIconNumInternal(List listIcon, int tarNum, Transform parentTrans, int maxNumPerFrame,
Action updateAction, GameObject prefab, string assetPath) where T : UIWidget, new()
{
if (listIcon == null)
{
listIcon = new List();
}
int createCnt = 0;
for (int i = 0; i < tarNum; i++)
{
T tmpT = null;
if (i < listIcon.Count)
{
tmpT = listIcon[i];
}
else
{
if (prefab == null)
{
tmpT = await CreateWidgetByPathAsync(parentTrans, assetPath);
}
else
{
tmpT = CreateWidgetByPrefab(prefab, parentTrans);
}
listIcon.Add(tmpT);
}
int index = i;
if (updateAction != null)
{
updateAction(tmpT, index);
}
createCnt++;
if (createCnt >= maxNumPerFrame)
{
createCnt = 0;
await UniTask.Yield();
}
}
if (listIcon.Count > tarNum)
{
RemoveUnUseItem(listIcon, tarNum);
}
}
private void RemoveUnUseItem(List listIcon, int tarNum) where T : UIWidget
{
var removeIcon = new List();
for (int iconIdx = 0; iconIdx < listIcon.Count; iconIdx++)
{
var icon = listIcon[iconIdx];
if (iconIdx >= tarNum)
{
removeIcon.Add(icon);
}
}
for (var index = 0; index < removeIcon.Count; index++)
{
var icon = removeIcon[index];
listIcon.Remove(icon);
icon.OnDestroy();
icon.OnDestroyWidget();
ListChild.Remove(icon);
if (icon.gameObject != null)
{
UnityEngine.Object.Destroy(icon.gameObject);
}
}
}
#endregion
}
}