Timer.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #pragma once
  2. #include "Defines.h"
  3. #include <chrono>
  4. namespace gameplay
  5. {
  6. /**
  7. * Defines a timer with configurable resolution.
  8. */
  9. class GP_API Timer
  10. {
  11. public:
  12. enum class Resolution : uint32_t
  13. {
  14. SECONDS,
  15. MILLISECONDS,
  16. MICROSECONDS,
  17. NANOSECONDS
  18. };
  19. /**
  20. * Constructor.
  21. */
  22. Timer() {}
  23. /**
  24. * Destructor.
  25. */
  26. ~Timer() {}
  27. /**
  28. * Gets the precision of the timer (minimal tick duration).
  29. *
  30. * @return The precision of the timer (minimal tick duration).
  31. */
  32. double get_precision();
  33. /**
  34. * Starts the timer.
  35. */
  36. void start();
  37. /**
  38. * Stops the timer.
  39. */
  40. void stop();
  41. /**
  42. * Gets elapsed time in a specified form, using specified time resolution.
  43. *
  44. * If timer wasn't stopped before, this return the elapsed time between
  45. * timer start and this function call, timer will continue to tick.
  46. *
  47. * @param resolution Time resolution that you want to get result in.
  48. * @return The elapsed time between timer start, and timer stop events.
  49. */
  50. template <typename T = int64_t>
  51. inline T get_elapsed_time(Resolution resolution = Resolution::MILLISECONDS);
  52. private:
  53. bool _running{false};
  54. std::chrono::high_resolution_clock::time_point _start;
  55. std::chrono::high_resolution_clock::time_point _stop;
  56. };
  57. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. // impl
  59. double Timer::get_precision()
  60. {
  61. return std::chrono::high_resolution_clock::period::num / (double)std::chrono::high_resolution_clock::period::den;
  62. }
  63. void Timer::start()
  64. {
  65. _start= std::chrono::high_resolution_clock::now();
  66. _running = true;
  67. }
  68. void Timer::stop()
  69. {
  70. _stop = std::chrono::high_resolution_clock::now();
  71. _running = false;
  72. }
  73. template <typename T>
  74. T Timer::get_elapsed_time(Resolution resolution)
  75. {
  76. std::chrono::high_resolution_clock::time_point stop;
  77. if (_running)
  78. {
  79. stop = std::chrono::high_resolution_clock::now();
  80. }
  81. else
  82. {
  83. stop = _stop;
  84. }
  85. auto elapsedTime = stop - _start;
  86. using dblSeconds = std::chrono::duration<T, std::ratio<1>>;
  87. using dblMilliseconds = std::chrono::duration<T, std::milli>;
  88. using dblMicroseconds = std::chrono::duration<T, std::micro>;
  89. using dblNanoseconds = std::chrono::duration<T, std::nano>;
  90. switch (resolution)
  91. {
  92. case Resolution::SECONDS:
  93. return std::chrono::duration_cast<dblSeconds>(elapsedTime).count();
  94. case Resolution::MILLISECONDS:
  95. return std::chrono::duration_cast<dblMilliseconds>(elapsedTime).count();
  96. case Resolution::MICROSECONDS:
  97. return std::chrono::duration_cast<dblMicroseconds>(elapsedTime).count();
  98. case Resolution::NANOSECONDS:
  99. return std::chrono::duration_cast<dblNanoseconds>(elapsedTime).count();
  100. default:
  101. return std::chrono::duration_cast<dblMilliseconds>(elapsedTime).count();
  102. }
  103. }
  104. }