using System; using System.Runtime.CompilerServices; using System.Threading; using AlicizaX; using Cysharp.Threading.Tasks; namespace AlicizaX.UI.Runtime { internal sealed class UIMetadata { public UIBase View { get; private set; } public readonly UIMetaRegistry.UIMetaInfo MetaInfo; public readonly UIResRegistry.UIResInfo ResInfo; public readonly Type UILogicType; public bool InCache = false; private CancellationTokenSource _cancellationTokenSource; public CancellationToken CancellationToken => _cancellationTokenSource?.Token ?? CancellationToken.None; public UIState State { get { if (View == null) return UIState.Uninitialized; return View.State; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CreateUI() { if (View is null) { if (!UIStateMachine.ValidateTransition(UILogicType.Name, UIState.Uninitialized, UIState.CreatedUI)) return; View = (UIBase)InstanceFactory.CreateInstanceOptimized(UILogicType); EnsureCancellationToken(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void EnsureCancellationToken() { if (_cancellationTokenSource == null) { _cancellationTokenSource = new CancellationTokenSource(); } } public void CancelAsyncOperations() { _cancellationTokenSource?.Cancel(); _cancellationTokenSource?.Dispose(); _cancellationTokenSource = null; } public void Dispose() { DisposeAsync().Forget(); } internal async UniTask DisposeAsync() { CancelAsyncOperations(); if (State != UIState.Uninitialized && State != UIState.Destroying) { await View.InternalDestroy(); View = null; } } internal void DisposeImmediate() { CancelAsyncOperations(); if (State != UIState.Uninitialized && State != UIState.Destroying && View != null) { View.InternalDestroyImmediate(); View = null; } } public UIMetadata(Type uiType) { if (uiType == null) { throw new ArgumentNullException(nameof(uiType)); } UILogicType = uiType; if (!UIMetaRegistry.TryGet(UILogicType.TypeHandle, out MetaInfo)) { throw new InvalidOperationException($"[UI] Metadata not registered for {UILogicType.FullName}"); } if (!UIResRegistry.TryGet(MetaInfo.HolderRuntimeTypeHandle, out ResInfo)) { throw new InvalidOperationException($"[UI] Resource metadata not registered for holder of {UILogicType.FullName}"); } } } }