PageRenderTime 46ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  1. using System.Diagnostics;
  2. namespace Delta.Utilities.Profiling
  3. {
  4. /// <summary>
  5. /// Implementation of ITimeSource using C# Stopwatch class
  6. /// </summary>
  7. public class StopwatchTimeSource : BaseTimeSource
  8. {
  9. #region Private
  10. #region stopwatch (Private)
  11. /// <summary>
  12. /// Internal stopwatch
  13. /// </summary>
  14. private readonly Stopwatch stopwatch;
  15. #endregion
  16. #region timerFrequency (Private)
  17. /// <summary>
  18. /// Number of ticks per second
  19. /// </summary>
  20. private readonly long timerFrequency;
  21. #endregion
  22. #region lastTicks (Private)
  23. /// <summary>
  24. /// Ticks from last frame, used to calculate Delta, which is more
  25. /// accurate than using just ElapsedMilliseconds.
  26. /// </summary>
  27. private long lastTicks;
  28. #endregion
  29. #endregion
  30. #region Constructors
  31. /// <summary>
  32. /// Create stopwatch time source
  33. /// </summary>
  34. public StopwatchTimeSource()
  35. {
  36. // Note: Stopwatch.IsHighResolution tells us if we are precise (true)
  37. stopwatch = new Stopwatch();
  38. timerFrequency = Stopwatch.Frequency;
  39. stopwatch.Start();
  40. lastTicks = stopwatch.ElapsedTicks;
  41. }
  42. #endregion
  43. #region Update (Public)
  44. /// <summary>
  45. /// Update the current ElapsedTicks and ElapsedMilliseconds values and
  46. /// return the difference of the last time with a floating point value.
  47. /// </summary>
  48. /// <returns>Difference to the last time this method was called</returns>
  49. public override float Update()
  50. {
  51. // First copy over the last frame values
  52. LastSeconds = ElapsedSeconds;
  53. LastMilliseconds = ElapsedMilliseconds;
  54. // Update Total and Delta times. This is fast, no extra checking needed
  55. long elapsedTicks = stopwatch.ElapsedTicks;
  56. ElapsedMilliseconds = elapsedTicks * 1000 / timerFrequency;
  57. //ElapsedSeconds = (int)(elapsedTicks / timerFrequency);
  58. //might be faster:
  59. ElapsedSeconds = (int)(ElapsedMilliseconds / 1000);
  60. // And finally return the delta in seconds since the last frame.
  61. float delta = ((float)(elapsedTicks - lastTicks) / timerFrequency);
  62. lastTicks = elapsedTicks;
  63. return delta;
  64. }
  65. #endregion
  66. #region GetExactTotalTimeInSecondsToday (Public)
  67. /// <summary>
  68. /// Reports a very accurate value rounded to a float in seconds for today.
  69. /// The return value is in seconds and reports a fraction for up to 0.1ns.
  70. /// The value will be reset every day to stay accurate (again, after 3
  71. /// days floats lose accuracy and will not be very useful anymore). Used
  72. /// for profilers and more accurate input for example. If you do not need
  73. /// this high accuracy please only use the Milliseconds value or the helper
  74. /// methods here (all millisecond exact and updated once per frame).
  75. /// </summary>
  76. /// <returns>Time in seconds today as a float value, not very accurate,
  77. /// but good enough for a day (after 20-40 days it gets really inaccurate)
  78. /// </returns>
  79. public override float GetExactTotalTimeInSecondsToday()
  80. {
  81. long elapsedTicks = stopwatch.ElapsedTicks;
  82. // How many ticks are in a day (ticks per second * seconds in a day)?
  83. long ticksInADay = timerFrequency * 60 * 60 * 24;
  84. // Now modulate the ticksInADay out, we do not want more than that.
  85. // Basically start over every 24 hours and have the time reset to 0 then.
  86. // This way the returned float value stays accurate not just for the
  87. // first few days, but millions of years :)
  88. return ((float)(elapsedTicks % ticksInADay) / timerFrequency);
  89. }
  90. #endregion
  91. }
  92. }