Files
2026-09-20 15:26:03 +03:00

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();
}
}
}
}