using System; using System.Buffers; using System.Collections.Generic; using AlicizaX.Runtime; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.Pool; namespace AlicizaX.UI.Runtime { public abstract partial class UIBase { private readonly Dictionary _children = new(); private void UpdateChildren() { var values = _children.Values; // O(1) 操作 foreach (var meta in values) { if (meta.View.State == UIState.Opened) { meta.View.InternalUpdate(); } } } private void DestroyAllChildren() { var temp = ArrayPool.Shared.Rent(_children.Count); try { int i = 0; foreach (var kvp in _children) { temp[i++] = kvp.Value; } for (int j = 0; j < i; j++) { temp[j].Dispose(); } } finally { ArrayPool.Shared.Return(temp); } _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; } } } protected T CreateWidget(Transform parent) where T : UIWidget { UIMetadata metadata = MetaTypeCache.Metadata; metadata.CreateUI(); UILoaderFactory.LoadUIResourcesSync(metadata, parent, this); ProcessWidget(metadata); return (T)metadata.View; } protected T CreateWidget(UIHolderObjectBase holder) where T : UIWidget { UIMetadata metadata = MetaTypeCache.Metadata; metadata.CreateUI(); UIWidget widget = (UIWidget)metadata.View; widget.BindUIHolder(holder.gameObject, this); ProcessWidget(metadata); return (T)widget; } protected async UniTask CreateWidgetAsync(Transform parent) where T : UIBase { UIMetadata metadata = MetaTypeCache.Metadata; metadata.CreateUI(); await UILoaderFactory.LoadUIResourcesAsync(metadata, parent, this); ProcessWidget(metadata); return (T)metadata.View; } private void ProcessWidget(UIMetadata meta) { AddWidget(meta); meta.View.InternalInitlized(); if (meta.View.Holder.Visible) { meta.View.InternalOpen(); } } private void AddWidget(UIMetadata meta) { if (!_children.TryAdd(meta.View, meta)) { meta.Dispose(); Log.Warning("Already has widget:{0}", meta.View); } } public void RemoveWidget(UIBase widget) { if (_children.Remove(widget, out var meta)) { meta.Dispose(); } } } }