BITKit/Src/Unity/Scripts/UX/Waiting/UXWaiting.cs

132 lines
3.8 KiB
C#

using System;
using System.Collections;
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<UXWaiting>,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;
public async void SetMessage(string message)
{
await UniTask.SwitchToMainThread();
if(container.panel!=null)
{
label.text = message;
}
else
{
BIT4Log.Log<UXWaiting>("WaitingHandle is destroyed");
}
}
}
[SerializeField] private VisualTreeAsset handleTemplate;
[SerializeField] private bool asGlobal;
[UXBindPath("waiting-container")]
private VisualElement _container;
[UXBindPath("waiting-root")]
private VisualElement _root;
private Pool<IUXWaitingHandle> _pool;
private readonly HashSet<IUXWaitingHandle> _handles = new();
public IUXWaitingHandle Get()
{
var handle = _pool.Take();
Active();
_handles.Add(handle);
return handle;
async void Active()
{
await UniTask.SwitchToMainThread();
handle.As<WaitingHandle>().container.SetActive(true);
_root.SetActive(true);
}
}
public async void Release(IUXWaitingHandle handle)
{
await UniTask.SwitchToMainThread();
if (destroyCancellationToken.IsCancellationRequested) return;
_pool.Return(handle);
_handles.Remove(handle);
Check();
}
protected override void Awake()
{
base.Awake();
UXUtils.Inject(this);
_container.Clear();
_pool = new Pool<IUXWaitingHandle>(Create,OnReset,10);
if (asGlobal)
{
DI.Register<IUXWaiting>(this);
}
_root.SetActive(false);
}
private void Start()
{
Check();
}
private async void OnReset(IUXWaitingHandle obj)
{
await UniTask.SwitchToMainThread();
obj.As<WaitingHandle>().container.SetActive(false);
}
[BIT]
private async void Check()
{
await UniTask.Yield();
await UniTask.SwitchToMainThread();
if(destroyCancellationToken.IsCancellationRequested) return;
_root.SetActive(_handles.Count>0);
}
private IUXWaitingHandle Create()
{
var handle = new WaitingHandle
{
container = _container.Create(handleTemplate),
label = _container.Q<Label>(UXConstant.ContextLabel)
};
handle.SetMessage($"未初始化");
handle.container.SetActive(false);
return handle;
}
}
}