148 lines
4.6 KiB
C#
148 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Threading;
|
|
using BITKit.Mod;
|
|
using BITKit.UX;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
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);
|
|
}
|
|
}
|
|
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();
|
|
}
|
|
[CustomType(typeof(IUXWaiting))]
|
|
public sealed class UXWaiting : UIToolkitOverlay,IUXWaiting
|
|
{
|
|
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)
|
|
{
|
|
_ticker = ticker;
|
|
Singleton = this;
|
|
_visibleHandle.AddListener(Dispose);
|
|
}
|
|
protected override string DocumentPath => "ux_global_waiting";
|
|
|
|
private VisualTreeAsset _handleTemplate;
|
|
|
|
[UXBindPath("waiting-container")]
|
|
private VisualElement _container;
|
|
|
|
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();
|
|
private InitializationState _initializationState;
|
|
public IUXWaitingHandle Get()
|
|
{
|
|
var handle = new WaitingHandle();
|
|
_initializedHandles.Enqueue(handle);
|
|
handle.OnSetMessage = (text) =>
|
|
{
|
|
_messageQueue.Enqueue((handle,text));
|
|
};
|
|
handle.OnDispose = () =>
|
|
{
|
|
_disposeQueue.Enqueue(handle);
|
|
_ticker.Add(OnTick);
|
|
};
|
|
|
|
_ticker.Add(OnTick);
|
|
|
|
return handle;
|
|
}
|
|
public void Release(IUXWaitingHandle handle)
|
|
{
|
|
handle.Dispose();
|
|
}
|
|
private void OnTick(float deltaTime)
|
|
{
|
|
if(_initializationState is not InitializationState.Initialized)return;
|
|
while (_initializedHandles.TryDequeue(out var handle))
|
|
{
|
|
var container = _container.Create(_handleTemplate);
|
|
_visibleHandle.AddElement(handle);
|
|
handle.VisualElement = container;
|
|
handle.Label = container.Get<Label>();
|
|
}
|
|
while (_messageQueue.TryDequeue(out var message))
|
|
{
|
|
message.handle.Label.text = message.text;
|
|
}
|
|
while (_disposeQueue.TryDequeue(out var handle))
|
|
{
|
|
handle.VisualElement.RemoveFromHierarchy();
|
|
_visibleHandle.RemoveElement(handle);
|
|
}
|
|
|
|
try
|
|
{
|
|
_visibleHandle.Invoke();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogException(e);
|
|
}
|
|
|
|
}
|
|
|
|
public override async UniTask InitializeAsync()
|
|
{
|
|
await base.InitializeAsync();
|
|
_handleTemplate = await ModService.LoadAsset<VisualTreeAsset>(HandleTemplate);
|
|
if (_handleTemplate is null)
|
|
{
|
|
Debug.LogError($"{HandleTemplate} is null");
|
|
}
|
|
|
|
UXUtils.Inject(this);
|
|
_container.Clear();
|
|
|
|
_visibleHandle.Invoke();
|
|
|
|
_initializationState = InitializationState.Initialized;
|
|
}
|
|
|
|
private void Dispose(bool dontDispose)
|
|
{
|
|
if (dontDispose is false)
|
|
{
|
|
Dispose();
|
|
}
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
_initializationState = 0;
|
|
base.Dispose();
|
|
}
|
|
}
|
|
} |