2025-09-05 19:46:30 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Buffers;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using AlicizaX;
|
|
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.Pool;
|
|
|
|
|
|
|
|
|
|
|
|
namespace AlicizaX.UI.Runtime
|
|
|
|
|
|
{
|
|
|
|
|
|
public abstract partial class UIBase
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly Dictionary<UIBase, UIMetadata> _children = new();
|
|
|
|
|
|
|
|
|
|
|
|
private void UpdateChildren()
|
|
|
|
|
|
{
|
|
|
|
|
|
var values = _children.Values;
|
|
|
|
|
|
foreach (var meta in values)
|
|
|
|
|
|
{
|
2025-11-13 17:46:20 +08:00
|
|
|
|
if (meta.View.State == UIState.Opened && meta.MetaInfo.NeedUpdate)
|
2025-09-05 19:46:30 +08:00
|
|
|
|
{
|
|
|
|
|
|
meta.View.InternalUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async UniTask DestroyAllChildren()
|
|
|
|
|
|
{
|
|
|
|
|
|
var temp = ArrayPool<UIMetadata>.Shared.Rent(_children.Count);
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
foreach (var kvp in _children)
|
|
|
|
|
|
{
|
|
|
|
|
|
temp[i++] = kvp.Value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < i; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (temp[j].View.Visible) await temp[j].View.InternalClose();
|
|
|
|
|
|
temp[j].Dispose();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
|
|
|
|
|
{
|
2025-11-13 17:46:20 +08:00
|
|
|
|
ArrayPool<UIMetadata>.Shared.Return(temp, true);
|
2025-09-05 19:46:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_children.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ChildVisible(bool value)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var meta in _children.Values)
|
|
|
|
|
|
{
|
|
|
|
|
|
var view = meta.View;
|
|
|
|
|
|
if (view.State == UIState.Opened)
|
|
|
|
|
|
{
|
|
|
|
|
|
view.Visible = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 17:46:20 +08:00
|
|
|
|
internal async UniTask<UIBase> CreateWidgetUIAsync(UIMetadata metadata, Transform parent, bool visible)
|
2025-09-05 19:46:30 +08:00
|
|
|
|
{
|
|
|
|
|
|
metadata.CreateUI();
|
2025-11-13 17:46:20 +08:00
|
|
|
|
await UIHolderFactory.CreateUIResourceAsync(metadata, parent, this);
|
2025-09-05 19:46:30 +08:00
|
|
|
|
await ProcessWidget(metadata, visible);
|
|
|
|
|
|
return (UIBase)metadata.View;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 17:46:20 +08:00
|
|
|
|
internal UIBase CreateWidgetUISync(UIMetadata metadata, Transform parent, bool visible)
|
|
|
|
|
|
{
|
|
|
|
|
|
metadata.CreateUI();
|
|
|
|
|
|
UIHolderFactory.CreateUIResourceSync(metadata, parent, this);
|
|
|
|
|
|
ProcessWidget(metadata, visible).Forget();
|
|
|
|
|
|
return (UIBase)metadata.View;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region CreateWidget
|
|
|
|
|
|
|
|
|
|
|
|
#region Async
|
|
|
|
|
|
|
|
|
|
|
|
protected async UniTask<UIBase> CreateWidgetAsync(string typeName, Transform parent, bool visible = true)
|
2025-09-05 19:46:30 +08:00
|
|
|
|
{
|
|
|
|
|
|
UIMetaRegistry.TryGet(typeName, out var metaRegistry);
|
|
|
|
|
|
UIMetadata metadata = UIMetadataFactory.GetMetadata(metaRegistry.RuntimeTypeHandle);
|
2025-11-13 17:46:20 +08:00
|
|
|
|
return await CreateWidgetUIAsync(metadata, parent, visible);
|
2025-09-05 19:46:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 17:46:20 +08:00
|
|
|
|
protected async UniTask<T> CreateWidgetAsync<T>(Transform parent, bool visible = true) where T : UIBase
|
2025-09-05 19:46:30 +08:00
|
|
|
|
{
|
|
|
|
|
|
UIMetadata metadata = MetaTypeCache<T>.Metadata;
|
2025-11-13 17:46:20 +08:00
|
|
|
|
return (T)await CreateWidgetUIAsync(metadata, parent, visible);
|
2025-09-05 19:46:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 17:46:20 +08:00
|
|
|
|
protected async UniTask<T> CreateWidgetAsync<T>(UIHolderObjectBase holder) where T : UIBase
|
2025-09-05 19:46:30 +08:00
|
|
|
|
{
|
|
|
|
|
|
UIMetadata metadata = MetaTypeCache<T>.Metadata;
|
|
|
|
|
|
metadata.CreateUI();
|
|
|
|
|
|
UIBase widget = (UIBase)metadata.View;
|
|
|
|
|
|
widget.BindUIHolder(holder, this);
|
|
|
|
|
|
await ProcessWidget(metadata, true);
|
|
|
|
|
|
return (T)widget;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 17:46:20 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Sync
|
|
|
|
|
|
|
|
|
|
|
|
protected UIBase CreateWidgetSync(string typeName, Transform parent, bool visible = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
UIMetaRegistry.TryGet(typeName, out var metaRegistry);
|
|
|
|
|
|
UIMetadata metadata = UIMetadataFactory.GetMetadata(metaRegistry.RuntimeTypeHandle);
|
|
|
|
|
|
return CreateWidgetUISync(metadata, parent, visible);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected T CreateWidgetSync<T>(Transform parent, bool visible = true) where T : UIBase
|
|
|
|
|
|
{
|
|
|
|
|
|
UIMetadata metadata = MetaTypeCache<T>.Metadata;
|
|
|
|
|
|
return (T)CreateWidgetUISync(metadata, parent, visible);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected T CreateWidgetSync<T>(UIHolderObjectBase holder) where T : UIBase
|
|
|
|
|
|
{
|
|
|
|
|
|
UIMetadata metadata = MetaTypeCache<T>.Metadata;
|
|
|
|
|
|
metadata.CreateUI();
|
|
|
|
|
|
UIBase widget = (UIBase)metadata.View;
|
|
|
|
|
|
widget.BindUIHolder(holder, this);
|
|
|
|
|
|
ProcessWidget(metadata, true).Forget();
|
|
|
|
|
|
return (T)widget;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-05 19:46:30 +08:00
|
|
|
|
private async UniTask ProcessWidget(UIMetadata meta, bool visible)
|
|
|
|
|
|
{
|
2025-11-13 17:46:20 +08:00
|
|
|
|
if (!AddWidget(meta)) return;
|
2025-09-05 19:46:30 +08:00
|
|
|
|
await meta.View.InternalInitlized();
|
|
|
|
|
|
meta.View.Visible = visible;
|
|
|
|
|
|
if (meta.View.Visible)
|
|
|
|
|
|
{
|
|
|
|
|
|
await meta.View.InternalOpen();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 17:46:20 +08:00
|
|
|
|
private bool AddWidget(UIMetadata meta)
|
2025-09-05 19:46:30 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (!_children.TryAdd(meta.View, meta))
|
|
|
|
|
|
{
|
|
|
|
|
|
Log.Warning("Already has widget:{0}", meta.View);
|
|
|
|
|
|
meta.Dispose();
|
2025-11-13 17:46:20 +08:00
|
|
|
|
return false;
|
2025-09-05 19:46:30 +08:00
|
|
|
|
}
|
2025-11-13 17:46:20 +08:00
|
|
|
|
|
|
|
|
|
|
return true;
|
2025-09-05 19:46:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async UniTask RemoveWidget(UIBase widget)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_children.Remove(widget, out var meta))
|
|
|
|
|
|
{
|
|
|
|
|
|
await widget.InternalClose();
|
|
|
|
|
|
meta.Dispose();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|