119 lines
2.7 KiB
C#
119 lines
2.7 KiB
C#
using Syntriax.Engine.Core;
|
|
using Syntriax.Engine.Core.Abstract;
|
|
|
|
namespace Syntriax.Engine.Systems.Time;
|
|
|
|
public class TimerBehaviour : Behaviour, ITimer
|
|
{
|
|
public event IReadOnlyTimer.TimerEventHandler? OnStarted = null;
|
|
public event IReadOnlyTimer.TimerDeltaEventHandler? OnDelta = null;
|
|
public event IReadOnlyTimer.TimerEventHandler? OnStopped = null;
|
|
public event IReadOnlyTimer.TimerEventHandler? OnPaused = null;
|
|
public event IReadOnlyTimer.TimerEventHandler? OnResumed = null;
|
|
|
|
public TimerState State { get; protected set; } = TimerState.Idle;
|
|
public double StartTime { get; protected set; } = 0f;
|
|
public float Percentage => (float)(1f - (Remaining / StartTime));
|
|
|
|
private double _remaining = 0f;
|
|
public double Remaining
|
|
{
|
|
get => _remaining;
|
|
protected set
|
|
{
|
|
if (value < .0f)
|
|
value = .0f;
|
|
|
|
_remaining = value;
|
|
}
|
|
}
|
|
|
|
private bool shouldBeTicking = false;
|
|
private bool hasStartedTickingBefore = false;
|
|
|
|
public virtual void Start(double time)
|
|
{
|
|
StartTime = time;
|
|
Remaining = time;
|
|
|
|
shouldBeTicking = true;
|
|
hasStartedTickingBefore = false;
|
|
|
|
if (IsActive)
|
|
StartTimer();
|
|
}
|
|
|
|
public virtual void Stop()
|
|
{
|
|
if (!shouldBeTicking)
|
|
return;
|
|
|
|
shouldBeTicking = false;
|
|
|
|
State = TimerState.Stopped;
|
|
OnStopped?.Invoke(this);
|
|
}
|
|
|
|
protected override void OnUpdate()
|
|
{
|
|
if (State is not TimerState.Ticking)
|
|
return;
|
|
|
|
double delta = GameManager.Time.DeltaSpan.TotalSeconds;
|
|
|
|
Remaining -= delta;
|
|
OnDelta?.Invoke(this, delta);
|
|
|
|
if (Remaining <= .0f)
|
|
Stop();
|
|
}
|
|
|
|
protected override void OnEnteredHierarchy(IGameManager gameManager)
|
|
{
|
|
if (!shouldBeTicking || State is TimerState.Ticking)
|
|
return;
|
|
|
|
if (hasStartedTickingBefore)
|
|
Resume();
|
|
else
|
|
StartTimer();
|
|
}
|
|
|
|
protected override void OnExitedHierarchy(IGameManager gameManager)
|
|
{
|
|
if (!shouldBeTicking || State is not TimerState.Ticking)
|
|
return;
|
|
|
|
Pause();
|
|
}
|
|
|
|
public virtual void Pause()
|
|
{
|
|
State = TimerState.Paused;
|
|
OnPaused?.Invoke(this);
|
|
}
|
|
|
|
public virtual void Resume()
|
|
{
|
|
State = TimerState.Ticking;
|
|
OnResumed?.Invoke(this);
|
|
}
|
|
|
|
private void StartTimer()
|
|
{
|
|
hasStartedTickingBefore = true;
|
|
|
|
State = TimerState.Ticking;
|
|
OnStarted?.Invoke(this);
|
|
}
|
|
|
|
protected override void OnFinalize()
|
|
{
|
|
StartTime = 0f;
|
|
Remaining = 0f;
|
|
State = TimerState.Idle;
|
|
shouldBeTicking = false;
|
|
hasStartedTickingBefore = false;
|
|
}
|
|
}
|