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

155 lines
4.6 KiB
C#
Raw Normal View History

2024-03-31 23:31:00 +08:00
using System;
using System.Collections;
2024-07-29 09:39:22 +08:00
using System.Collections.Concurrent;
2024-03-31 23:31:00 +08:00
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
{
2024-06-11 17:16:34 +08:00
[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);
}
}
2024-05-31 01:23:15 +08:00
[CustomType(typeof(IUXWaiting))]
2024-06-11 17:16:34 +08:00
public class UXWaiting : MonoBehaviourSingleton<UXWaiting>,IUXWaiting
2024-03-31 23:31:00 +08:00
{
public sealed class WaitingHandle : IUXWaitingHandle
{
public string Message
{
get => label.text;
set => SetMessage(value);
}
public object Container => container;
internal VisualElement container;
internal Label label;
2024-06-27 18:53:49 +08:00
internal Action OnDispose;
2024-07-29 09:39:22 +08:00
internal Action<Label,string> OnSetMessage;
2024-03-31 23:31:00 +08:00
public async void SetMessage(string message)
{
2024-07-29 09:39:22 +08:00
OnSetMessage?.Invoke(label,message);
// await UniTask.SwitchToMainThread();
// BIT4Log.Log<UXWaiting>($"SetMessage {message}");
// if(container.panel!=null)
// {
// label.text = message;
// }
// else
// {
// BIT4Log.Log<UXWaiting>("WaitingHandle is destroyed");
// }
2024-03-31 23:31:00 +08:00
}
2024-06-27 18:53:49 +08:00
public void Dispose() => OnDispose?.Invoke();
2024-03-31 23:31:00 +08:00
}
[SerializeField] private VisualTreeAsset handleTemplate;
[SerializeField] private bool asGlobal;
[UXBindPath("waiting-container")]
private VisualElement _container;
[UXBindPath("waiting-root")]
private VisualElement _root;
2024-06-27 18:53:49 +08:00
private Pool<WaitingHandle> _pool;
private readonly HashSet<WaitingHandle> _handles = new();
2024-07-29 09:39:22 +08:00
private readonly ConcurrentQueue<(Label label,string text)> _messageQueue = new();
2024-03-31 23:31:00 +08:00
public IUXWaitingHandle Get()
{
var handle = _pool.Take();
Active();
2024-05-31 01:23:15 +08:00
_handles.Add(handle);
2024-06-27 18:53:49 +08:00
handle.OnDispose = () => Release(handle);
2024-03-31 23:31:00 +08:00
return handle;
async void Active()
{
await UniTask.SwitchToMainThread();
handle.As<WaitingHandle>().container.SetActive(true);
_root.SetActive(true);
}
}
public async void Release(IUXWaitingHandle handle)
{
2024-05-31 01:23:15 +08:00
await UniTask.SwitchToMainThread();
if (destroyCancellationToken.IsCancellationRequested) return;
2024-06-27 18:53:49 +08:00
_pool.Return(handle.As<WaitingHandle>());
_handles.Remove(handle.As<WaitingHandle>());
2024-03-31 23:31:00 +08:00
Check();
}
2024-07-29 09:39:22 +08:00
private void Update()
{
while (_messageQueue.TryDequeue(out var message))
{
message.label.text = message.text;
}
}
2024-06-11 17:16:34 +08:00
protected override void Awake()
2024-03-31 23:31:00 +08:00
{
2024-06-11 17:16:34 +08:00
base.Awake();
2024-03-31 23:31:00 +08:00
UXUtils.Inject(this);
2024-05-31 01:23:15 +08:00
_container.Clear();
2024-06-27 18:53:49 +08:00
_pool = new Pool<WaitingHandle>(Create,OnReset,10);
2024-03-31 23:31:00 +08:00
if (asGlobal)
{
DI.Register<IUXWaiting>(this);
}
_root.SetActive(false);
}
2024-05-31 01:23:15 +08:00
private void Start()
{
Check();
}
2024-03-31 23:31:00 +08:00
private async void OnReset(IUXWaitingHandle obj)
{
await UniTask.SwitchToMainThread();
obj.As<WaitingHandle>().container.SetActive(false);
}
2024-05-31 01:23:15 +08:00
[BIT]
2024-03-31 23:31:00 +08:00
private async void Check()
{
await UniTask.Yield();
await UniTask.SwitchToMainThread();
if(destroyCancellationToken.IsCancellationRequested) return;
2024-05-31 01:23:15 +08:00
_root.SetActive(_handles.Count>0);
2024-03-31 23:31:00 +08:00
}
2024-06-27 18:53:49 +08:00
private WaitingHandle Create()
2024-03-31 23:31:00 +08:00
{
var handle = new WaitingHandle
{
container = _container.Create(handleTemplate),
label = _container.Q<Label>(UXConstant.ContextLabel)
};
2024-07-29 09:39:22 +08:00
handle.OnSetMessage = (label, text) =>
{
_messageQueue.Enqueue((label,text));
};
2024-03-31 23:31:00 +08:00
handle.SetMessage($"未初始化");
handle.container.SetActive(false);
return handle;
}
}
}