Syntriax.Engine/Engine.Systems/Time/StopwatchBehaviour.cs

100 lines
2.4 KiB
C#

using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Systems.Time;
public class StopwatchBehaviour : Behaviour, IStopwatch
{
public event IReadOnlyStopwatch.StopwatchEventHandler? OnStarted = null;
public event IReadOnlyStopwatch.StopwatchDeltaEventHandler? OnDelta = null;
public event IReadOnlyStopwatch.StopwatchEventHandler? OnStopped = null;
public event IReadOnlyStopwatch.StopwatchEventHandler? OnPaused = null;
public event IReadOnlyStopwatch.StopwatchEventHandler? OnResumed = null;
public double Time { get; protected set; } = 0f;
public TimerState State { get; protected set; } = TimerState.Idle;
private bool shouldBeTicking = false;
private bool hasStartedTickingBefore = false;
public virtual void StopwatchStart()
{
Time = 0f;
shouldBeTicking = true;
hasStartedTickingBefore = false;
if (IsActive)
StartStopwatch();
}
public virtual void StopwatchStop()
{
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;
Time += delta;
OnDelta?.Invoke(this, delta);
}
protected override void OnEnteredHierarchy(IGameManager gameManager)
{
if (!shouldBeTicking || State is TimerState.Ticking)
return;
if (hasStartedTickingBefore)
StopwatchResume();
else
StartStopwatch();
}
protected override void OnExitedHierarchy(IGameManager gameManager)
{
if (!shouldBeTicking || State is not TimerState.Ticking)
return;
StopwatchPause();
}
public virtual void StopwatchPause()
{
State = TimerState.Paused;
OnPaused?.Invoke(this);
}
public virtual void StopwatchResume()
{
State = TimerState.Ticking;
OnResumed?.Invoke(this);
}
private void StartStopwatch()
{
hasStartedTickingBefore = true;
State = TimerState.Ticking;
OnStarted?.Invoke(this);
}
protected override void OnFinalize()
{
Time = 0f;
State = TimerState.Idle;
shouldBeTicking = false;
hasStartedTickingBefore = false;
}
}