sea-battle-vr/Assets/Scripts/Gameplay/Core/EndGameConditionChecker.cs

96 lines
2.5 KiB
C#

using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading;
public class EndGameConditionChecker : IDisposable
{
public event Action<EndgameReason> OnEndGameCondition;
private bool _isDisposed = false;
private float startTime;
private float endTime;
public float TimeRest => limitedByTime ? endTime - Time.time : - 1;
private bool limitedByTime;
private CancellationTokenSource _cts;
private WeaponModel weaponModel;
private Health playerHealth;
public EndGameConditionChecker(WeaponModel weaponModel, Health playerHealth, int sessionTimeMinutes = 0)
{
if(weaponModel == null)
throw new ArgumentNullException("WeaponModel is null");
if (playerHealth == null)
throw new ArgumentNullException("PlayerHealth is null");
this.weaponModel = weaponModel;
this.playerHealth = playerHealth;
weaponModel.OnNoAmmo += NoAmmoHandler;
playerHealth.Died += PlayerDiedHandler;
limitedByTime = sessionTimeMinutes > 0;
if(limitedByTime )
{
startTime = Time.time;
endTime = startTime + sessionTimeMinutes * 60;
_cts = new CancellationTokenSource();
CheckTimeout(_cts).Forget();
}
}
public void Dispose()
{
if(_isDisposed) return;
_isDisposed = true;
_cts?.Cancel();
_cts?.Dispose();
_cts = null;
weaponModel.OnNoAmmo -= NoAmmoHandler;
playerHealth.Died -= PlayerDiedHandler;
weaponModel = null;
playerHealth = null;
}
private void PlayerDiedHandler(Vector3 obj) => TerminateSession(EndgameReason.Death);
private void NoAmmoHandler() => TerminateSession(EndgameReason.NoAmmo);
private void TerminateSession(EndgameReason reason)
{
if (_isDisposed) return;
OnEndGameCondition?.Invoke(reason);
Dispose();
}
private async UniTaskVoid CheckTimeout(CancellationTokenSource cts)
{
try
{
while (!cts.IsCancellationRequested)
{
if (TimeRest <= 0)
{
TerminateSession(EndgameReason.Timeout);
break;
}
await UniTask.Delay(1000, cancellationToken: cts.Token);
}
}
catch (OperationCanceledException)
{
// ожидаемая отмена
}
}
public enum EndgameReason
{
Timeout,
Death,
NoAmmo
}
}