/Utilities/Profiling/StopwatchTimeSource.cs
C# | 102 lines | 48 code | 10 blank | 44 comment | 0 complexity | f17b39f496f9843468463cd0d0746d6c MD5 | raw file
Possible License(s): Apache-2.0
- using System.Diagnostics;
-
- namespace Delta.Utilities.Profiling
- {
- /// <summary>
- /// Implementation of ITimeSource using C# Stopwatch class
- /// </summary>
- public class StopwatchTimeSource : BaseTimeSource
- {
- #region Private
-
- #region stopwatch (Private)
- /// <summary>
- /// Internal stopwatch
- /// </summary>
- private readonly Stopwatch stopwatch;
- #endregion
-
- #region timerFrequency (Private)
- /// <summary>
- /// Number of ticks per second
- /// </summary>
- private readonly long timerFrequency;
- #endregion
-
- #region lastTicks (Private)
- /// <summary>
- /// Ticks from last frame, used to calculate Delta, which is more
- /// accurate than using just ElapsedMilliseconds.
- /// </summary>
- private long lastTicks;
- #endregion
-
- #endregion
-
- #region Constructors
- /// <summary>
- /// Create stopwatch time source
- /// </summary>
- public StopwatchTimeSource()
- {
- // Note: Stopwatch.IsHighResolution tells us if we are precise (true)
- stopwatch = new Stopwatch();
- timerFrequency = Stopwatch.Frequency;
- stopwatch.Start();
- lastTicks = stopwatch.ElapsedTicks;
- }
- #endregion
-
- #region Update (Public)
- /// <summary>
- /// Update the current ElapsedTicks and ElapsedMilliseconds values and
- /// return the difference of the last time with a floating point value.
- /// </summary>
- /// <returns>Difference to the last time this method was called</returns>
- public override float Update()
- {
- // First copy over the last frame values
- LastSeconds = ElapsedSeconds;
- LastMilliseconds = ElapsedMilliseconds;
-
- // Update Total and Delta times. This is fast, no extra checking needed
- long elapsedTicks = stopwatch.ElapsedTicks;
- ElapsedMilliseconds = elapsedTicks * 1000 / timerFrequency;
- //ElapsedSeconds = (int)(elapsedTicks / timerFrequency);
- //might be faster:
- ElapsedSeconds = (int)(ElapsedMilliseconds / 1000);
-
- // And finally return the delta in seconds since the last frame.
- float delta = ((float)(elapsedTicks - lastTicks) / timerFrequency);
- lastTicks = elapsedTicks;
- return delta;
- }
- #endregion
-
- #region GetExactTotalTimeInSecondsToday (Public)
- /// <summary>
- /// Reports a very accurate value rounded to a float in seconds for today.
- /// The return value is in seconds and reports a fraction for up to 0.1ns.
- /// The value will be reset every day to stay accurate (again, after 3
- /// days floats lose accuracy and will not be very useful anymore). Used
- /// for profilers and more accurate input for example. If you do not need
- /// this high accuracy please only use the Milliseconds value or the helper
- /// methods here (all millisecond exact and updated once per frame).
- /// </summary>
- /// <returns>Time in seconds today as a float value, not very accurate,
- /// but good enough for a day (after 20-40 days it gets really inaccurate)
- /// </returns>
- public override float GetExactTotalTimeInSecondsToday()
- {
- long elapsedTicks = stopwatch.ElapsedTicks;
- // How many ticks are in a day (ticks per second * seconds in a day)?
- long ticksInADay = timerFrequency * 60 * 60 * 24;
- // Now modulate the ticksInADay out, we do not want more than that.
- // Basically start over every 24 hours and have the time reset to 0 then.
- // This way the returned float value stays accurate not just for the
- // first few days, but millions of years :)
- return ((float)(elapsedTicks % ticksInADay) / timerFrequency);
- }
- #endregion
- }
- }