#region usings
using System;
using System.Collections.Generic;
using SM.Base;
using SM.Base.Windows;
#endregion
namespace SM.Base.Time
{
///
/// Represents a stopwatch.
///
public class Stopwatch
{
private static List _activeStopwatches = new List();
private bool _paused = false;
///
/// If true, the stopwatch was started.
/// This doesn't changed when paused.
///
public bool Active { get; private set; } = false;
///
/// Gets/Sets if the stopwatch is paused.
///
public bool Paused
{
get => _paused;
set
{
if (value)
Pause();
else
Resume();
}
}
///
/// If true, the stopwatch is active and not paused... (who would have guessed...)
///
public bool Running => Active && !Paused;
///
/// Contains how much time already has passed. (in seconds)
///
public float Elapsed { get; protected set; }
///
/// Contains the TimeSpan of how much time already passed.
///
public TimeSpan ElapsedSpan { get; protected set; }
public event Action Tick;
///
/// Starts the stopwatch.
///
public virtual void Start()
{
if (Active) return;
_activeStopwatches.Add(this);
Active = true;
}
///
/// Performs a tick.
///
///
private protected virtual void Ticking(UpdateContext context)
{
Elapsed += context.Deltatime;
ElapsedSpan = TimeSpan.FromSeconds(Elapsed);
Tick?.Invoke(this, context);
}
///
/// Resumes the timer.
///
protected virtual void Resume()
{
_paused = false;
}
///
/// Pauses the timer.
///
protected virtual void Pause()
{
_paused = true;
}
///
/// Stops the stopwatch.
///
public virtual void Stop()
{
if (!Active) return;
Active = false;
_activeStopwatches.Remove(this);
}
///
/// Resets the stopwatch.
///
public void Reset()
{
Elapsed = 0;
}
internal static void PerformTicks(UpdateContext context)
{
for (var i = 0; i < _activeStopwatches.Count; i++)
{
if (_activeStopwatches[i].Paused) continue;
_activeStopwatches[i].Ticking(context);
}
}
}
}