/**
* Code from Xenko TimerTick
*/
using System;
using System.Diagnostics;
namespace NETCoreTest.Framework
{
public class TimerTick
{
#region Fields
private long startRawTime;
private long lastRawTime;
private int pauseCount;
private long pauseStartTime;
private long timePaused;
private decimal speedFactor;
#endregion
#region Constructors and Destructors
///
/// Initializes a new instance of the class.
///
public TimerTick()
{
speedFactor = 1.0m;
Reset();
}
///
/// Initializes a new instance of the class.
///
/// The start time.
public TimerTick(TimeSpan startTime)
{
speedFactor = 1.0m;
Reset(startTime);
}
#endregion
#region Public Properties
///
/// Gets the start time when this timer was created.
///
public TimeSpan StartTime { get; private set; }
///
/// Gets the total time elasped since the last reset or when this timer was created.
///
public TimeSpan TotalTime { get; private set; }
///
/// Gets the total time elasped since the last reset or when this timer was created, including
///
public TimeSpan TotalTimeWithPause { get; private set; }
///
/// Gets the elapsed time since the previous call to .
///
public TimeSpan ElapsedTime { get; private set; }
///
/// Gets the elapsed time since the previous call to including
///
public TimeSpan ElapsedTimeWithPause { get; private set; }
///
/// Gets or sets the speed factor. Default is 1.0
///
/// The speed factor.
public double SpeedFactor
{
get { return (double) speedFactor; }
set { speedFactor = (decimal) value; }
}
///
/// Gets a value indicating whether this instance is paused.
///
/// true if this instance is paused; otherwise, false.
public bool IsPaused
{
get { return pauseCount > 0; }
}
#endregion
#region Public Methods and Operators
///
/// Resets this instance. is set to zero.
///
public void Reset()
{
Reset(TimeSpan.Zero);
}
///
/// Resets this instance. is set to startTime.
///
/// The start time.
public void Reset(TimeSpan startTime)
{
StartTime = startTime;
TotalTime = startTime;
startRawTime = Stopwatch.GetTimestamp();
lastRawTime = startRawTime;
timePaused = 0;
pauseStartTime = 0;
pauseCount = 0;
}
///
/// Resumes this instance, only if a call to has been already issued.
///
public void Resume()
{
pauseCount--;
if (pauseCount <= 0)
{
timePaused += Stopwatch.GetTimestamp() - pauseStartTime;
pauseStartTime = 0L;
}
}
///
/// Update the and ,
///
///
/// This method must be called on a regular basis at every *tick*.
///
public void Tick()
{
// Don't tick when this instance is paused.
if (IsPaused)
{
ElapsedTime = TimeSpan.Zero;
return;
}
long rawTime = Stopwatch.GetTimestamp();
TotalTime = StartTime + new TimeSpan((long) Math.Round(ConvertRawToTimestamp(rawTime - timePaused - startRawTime).Ticks * speedFactor));
TotalTimeWithPause = StartTime + new TimeSpan((long) Math.Round(ConvertRawToTimestamp(rawTime - startRawTime).Ticks * speedFactor));
ElapsedTime = ConvertRawToTimestamp(rawTime - timePaused - lastRawTime);
ElapsedTimeWithPause = ConvertRawToTimestamp(rawTime - lastRawTime);
if (ElapsedTime < TimeSpan.Zero)
{
ElapsedTime = TimeSpan.Zero;
}
lastRawTime = rawTime;
}
///
/// Pauses this instance.
///
public void Pause()
{
pauseCount++;
if (pauseCount == 1)
{
pauseStartTime = Stopwatch.GetTimestamp();
}
}
public static TimeSpan ConvertRawToTimestamp(long delta)
{
return new TimeSpan(delta == 0 ? 0 : (delta * TimeSpan.TicksPerSecond) / Stopwatch.Frequency);
}
#endregion
}
}