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

148 lines
4.6 KiB
C#
Raw Normal View History

2024-03-31 23:31:00 +08:00
using System;
2024-07-29 09:39:22 +08:00
using System.Collections.Concurrent;
2024-11-03 16:38:17 +08:00
using System.Threading;
using BITKit.Mod;
2024-03-31 23:31:00 +08:00
using BITKit.UX;
using Cysharp.Threading.Tasks;
2024-11-03 16:38:17 +08:00
using UnityEngine;
2024-03-31 23:31:00 +08:00
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-11-03 16:38:17 +08:00
public sealed class WaitingHandle : IUXWaitingHandle
{
public string Message
{
get => Label.text;
set => SetMessage(value);
}
public object Container => VisualElement;
internal VisualElement VisualElement;
internal Label Label;
internal Action OnDispose;
internal Action<string> OnSetMessage;
public void SetMessage(string message) => OnSetMessage?.Invoke(message);
public void Dispose() => OnDispose?.Invoke();
}
2024-05-31 01:23:15 +08:00
[CustomType(typeof(IUXWaiting))]
2024-11-03 16:38:17 +08:00
public sealed class UXWaiting : UIToolkitOverlay,IUXWaiting
2024-03-31 23:31:00 +08:00
{
2024-11-03 16:38:17 +08:00
private const string HandleTemplate = "ux_waiting_handle";
public static UXWaiting Singleton { get; private set; }
private readonly ITicker _ticker;
public UXWaiting(IUXService uxService, ITicker ticker, CancellationTokenSource cancellationToken) : base(uxService, cancellationToken)
2024-03-31 23:31:00 +08:00
{
2024-11-03 16:38:17 +08:00
_ticker = ticker;
Singleton = this;
_visibleHandle.AddListener(Dispose);
2024-03-31 23:31:00 +08:00
}
2024-11-03 16:38:17 +08:00
protected override string DocumentPath => "ux_global_waiting";
2024-03-31 23:31:00 +08:00
2024-11-03 16:38:17 +08:00
private VisualTreeAsset _handleTemplate;
2024-03-31 23:31:00 +08:00
[UXBindPath("waiting-container")]
private VisualElement _container;
2024-08-04 11:39:37 +08:00
private readonly ConcurrentQueue<(WaitingHandle handle,string text)> _messageQueue = new();
private readonly ConcurrentQueue<WaitingHandle> _initializedHandles = new();
private readonly ConcurrentQueue<WaitingHandle> _disposeQueue = new();
private readonly ValidHandle _visibleHandle = new();
2024-11-03 16:38:17 +08:00
private InitializationState _initializationState;
2024-03-31 23:31:00 +08:00
public IUXWaitingHandle Get()
{
2024-08-04 11:39:37 +08:00
var handle = new WaitingHandle();
_initializedHandles.Enqueue(handle);
handle.OnSetMessage = (text) =>
2024-03-31 23:31:00 +08:00
{
2024-08-04 11:39:37 +08:00
_messageQueue.Enqueue((handle,text));
};
handle.OnDispose = () =>
{
_disposeQueue.Enqueue(handle);
2024-11-03 16:38:17 +08:00
_ticker.Add(OnTick);
2024-08-04 11:39:37 +08:00
};
2024-11-03 16:38:17 +08:00
_ticker.Add(OnTick);
2024-08-04 11:39:37 +08:00
return handle;
2024-03-31 23:31:00 +08:00
}
2024-08-04 11:39:37 +08:00
public void Release(IUXWaitingHandle handle)
2024-03-31 23:31:00 +08:00
{
2024-08-04 11:39:37 +08:00
handle.Dispose();
2024-03-31 23:31:00 +08:00
}
2024-12-25 11:35:30 +08:00
private void OnTick(float deltaTime)
2024-07-29 09:39:22 +08:00
{
2024-12-25 11:35:30 +08:00
if(_initializationState is not InitializationState.Initialized)return;
2024-08-04 11:39:37 +08:00
while (_initializedHandles.TryDequeue(out var handle))
{
2024-11-03 16:38:17 +08:00
var container = _container.Create(_handleTemplate);
_visibleHandle.AddElement(handle);
handle.VisualElement = container;
handle.Label = container.Get<Label>();
2024-08-04 11:39:37 +08:00
}
2024-07-29 09:39:22 +08:00
while (_messageQueue.TryDequeue(out var message))
{
2024-11-03 16:38:17 +08:00
message.handle.Label.text = message.text;
2024-08-04 11:39:37 +08:00
}
while (_disposeQueue.TryDequeue(out var handle))
{
2024-11-03 16:38:17 +08:00
handle.VisualElement.RemoveFromHierarchy();
_visibleHandle.RemoveElement(handle);
2024-07-29 09:39:22 +08:00
}
2025-01-12 11:13:19 +08:00
try
{
_visibleHandle.Invoke();
}
catch (Exception e)
{
Debug.LogException(e);
}
2024-07-29 09:39:22 +08:00
}
2024-11-03 16:38:17 +08:00
public override async UniTask InitializeAsync()
2024-03-31 23:31:00 +08:00
{
2024-11-03 16:38:17 +08:00
await base.InitializeAsync();
_handleTemplate = await ModService.LoadAsset<VisualTreeAsset>(HandleTemplate);
if (_handleTemplate is null)
{
Debug.LogError($"{HandleTemplate} is null");
}
2024-03-31 23:31:00 +08:00
UXUtils.Inject(this);
2024-05-31 01:23:15 +08:00
_container.Clear();
2025-01-12 11:13:19 +08:00
_visibleHandle.Invoke();
2024-11-03 16:38:17 +08:00
_initializationState = InitializationState.Initialized;
}
private void Dispose(bool dontDispose)
{
if (dontDispose is false)
{
Dispose();
}
2024-03-31 23:31:00 +08:00
}
2024-11-03 16:38:17 +08:00
public override void Dispose()
2024-05-31 01:23:15 +08:00
{
2024-11-03 16:38:17 +08:00
_initializationState = 0;
base.Dispose();
2024-03-31 23:31:00 +08:00
}
}
}