using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using BITKit.UX; using UnityEngine; using Cysharp.Threading.Tasks; using kcp2k; using UnityEngine.Pool; using UnityEngine.UIElements; namespace BITKit { [Serializable] public sealed class UXWaitingSingleton : IUXWaiting { private IUXWaiting Implementation => UXWaiting.Singleton; public IUXWaitingHandle Get() { return Implementation.Get(); } public void Release(IUXWaitingHandle handle) { Implementation.Release(handle); } } [CustomType(typeof(IUXWaiting))] public class UXWaiting : MonoBehaviourSingleton,IUXWaiting { public sealed class WaitingHandle : IUXWaitingHandle { public string Message { get => label.text; set => SetMessage(value); } public object Container => container; internal VisualElement container; internal Label label; internal Action OnDispose; internal Action OnSetMessage; public void SetMessage(string message) => OnSetMessage?.Invoke(message); public void Dispose() => OnDispose?.Invoke(); } [SerializeField] private VisualTreeAsset handleTemplate; [SerializeField] private bool asGlobal; [UXBindPath("waiting-container")] private VisualElement _container; [UXBindPath("waiting-root")] private VisualElement _root; private readonly ConcurrentQueue<(WaitingHandle handle,string text)> _messageQueue = new(); private readonly ConcurrentQueue _initializedHandles = new(); private readonly ConcurrentQueue _disposeQueue = new(); private readonly ValidHandle _visibleHandle = new(); public IUXWaitingHandle Get() { var handle = new WaitingHandle(); _initializedHandles.Enqueue(handle); handle.OnSetMessage = (text) => { _messageQueue.Enqueue((handle,text)); }; handle.OnDispose = () => { _disposeQueue.Enqueue(handle); }; return handle; } public void Release(IUXWaitingHandle handle) { handle.Dispose(); } private void Update() { while (_initializedHandles.TryDequeue(out var handle)) { var container = _container.Create(handleTemplate); handle.container = container; handle.label = container.Get