104 lines
3.3 KiB
C#
104 lines
3.3 KiB
C#
using System;
|
|
using System.Threading;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
|
|
namespace Code.Infrastructure.Loadings
|
|
{
|
|
public class Loading
|
|
{
|
|
private int _progress;
|
|
public bool Completed { get; private set; }
|
|
private Action _completed;
|
|
private Action<Loading> _loadProgress;
|
|
|
|
public Loading(int externalMaxProgress, Action completed, Action<Loading> loadProgress = null)
|
|
{
|
|
_progress = externalMaxProgress;
|
|
MaxProgress = externalMaxProgress;
|
|
|
|
_completed = completed;
|
|
_loadProgress = loadProgress;
|
|
}
|
|
/// <summary>
|
|
/// Получаем текущее значение прогресса
|
|
/// </summary>
|
|
public int CurrentProgress => _progress;
|
|
public int MaxProgress { get; private set; }
|
|
/// <summary>
|
|
/// Сдвигаем прогресс загрузки на 1
|
|
/// </summary>
|
|
public void DoProgress()
|
|
{
|
|
_progress--;
|
|
_loadProgress?.Invoke(this);
|
|
|
|
if(_progress == 0) // Зачем инвертировать, если так читается лучше, райдер соси
|
|
{
|
|
Completed = true;
|
|
_completed?.Invoke();
|
|
|
|
_cts?.Dispose();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Ждём заполнения шкалы прогресса
|
|
/// </summary>
|
|
public async UniTask FreezeTillDone()
|
|
{
|
|
_cts ??= new CancellationTokenSource();
|
|
try
|
|
{
|
|
await UniTask.WaitUntil(this, _ => Completed)
|
|
.AttachExternalCancellation(_cts.Token)
|
|
.SuppressCancellationThrow();
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
throw;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogException(e);
|
|
throw;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Привязать асинхронный процесс к выполнению загрузки. Сдвигает MaxProgress на 1
|
|
/// </summary>
|
|
public Loading AttachProcess(Func<UniTask> process)
|
|
{
|
|
AddLoadProcess(process).Forget();
|
|
return this;
|
|
}
|
|
private CancellationTokenSource _cts;
|
|
/// <summary>
|
|
/// Привязать асинхронный процесс к выполнению загрузки. Сдвигает MaxProgress на 1
|
|
/// </summary>
|
|
// Originally written by MrTorex https://github.com/MrTorex
|
|
public async UniTaskVoid AddLoadProcess(Func<UniTask> loader)
|
|
{
|
|
_cts ??= new CancellationTokenSource();
|
|
|
|
MaxProgress++;
|
|
_progress++;
|
|
try
|
|
{
|
|
await loader().AttachExternalCancellation(_cts.Token);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
throw;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogException(e);
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
DoProgress();
|
|
}
|
|
}
|
|
}
|
|
} |