Go to the documentation of this file.00001
00010 #include "CycleTimer.h"
00011 #include "ticks.h"
00012 #include <limits>
00013
00014 using namespace qrk;
00015 using namespace std;
00016
00017
00018 namespace
00019 {
00020 size_t fps2msec(size_t fps)
00021 {
00022 if (fps == 0) {
00023
00024 return numeric_limits<size_t>::max();
00025 }
00026
00027 size_t msec = 1000 / fps;
00028 return max(msec, static_cast<size_t>(1));
00029 }
00030
00031
00032 size_t msec2fps(size_t msec)
00033 {
00034
00035 return fps2msec(msec);
00036 }
00037 }
00038
00039
00040 struct CycleTimer::pImpl
00041 {
00042 enum {
00043 InvalidTicks = -1,
00044 };
00045
00046 size_t cycle_msec_;
00047 int prev_ticks_;
00048 bool strict_cycle_;
00049
00050
00051 pImpl(void)
00052 : cycle_msec_(fps2msec(DefaultFps)), prev_ticks_(InvalidTicks),
00053 strict_cycle_(false)
00054 {
00055 }
00056
00057
00058 size_t waitMsec(void)
00059 {
00060 if (prev_ticks_ == InvalidTicks) {
00061
00062 prev_ticks_ = ticks();
00063 return 0;
00064 }
00065
00066 int to_next_cycle = toNextCycleMsec();
00067 prev_ticks_ += static_cast<int>(cycle_msec_);
00068
00069 return (to_next_cycle > 0) ? to_next_cycle : 0;
00070 }
00071
00072
00073 void reset(void)
00074 {
00075 prev_ticks_ = ticks();
00076 }
00077
00078
00079 int toNextCycleMsec(void)
00080 {
00081 int next_ticks = prev_ticks_ + static_cast<int>(cycle_msec_);
00082
00083 int current_ticks = ticks();
00084 int to_next_cycle = next_ticks - current_ticks;
00085 if (to_next_cycle > 0) {
00086 return to_next_cycle;
00087 }
00088
00089 if (! strict_cycle_) {
00090 if (to_next_cycle >= 0) {
00091 to_next_cycle %= cycle_msec_;
00092 } else {
00093 prev_ticks_ = current_ticks;
00094 }
00095 }
00096
00097 return to_next_cycle;
00098 }
00099 };
00100
00101
00102 CycleTimer::CycleTimer(void) : pimpl(new pImpl)
00103 {
00104 }
00105
00106
00107 CycleTimer::~CycleTimer(void)
00108 {
00109 }
00110
00111
00112 size_t CycleTimer::waitMsec(void)
00113 {
00114 return pimpl->waitMsec();
00115 }
00116
00117
00118 void CycleTimer::reset(void)
00119 {
00120 pimpl->reset();
00121 }
00122
00123
00124 void CycleTimer::setStrictCycle(bool on)
00125 {
00126 pimpl->strict_cycle_ = on;
00127 }
00128
00129
00130 void CycleTimer::setCycleFps(size_t fps)
00131 {
00132 pimpl->cycle_msec_ = fps2msec(fps);
00133 }
00134
00135
00136 size_t CycleTimer::cycleFps(void) const
00137 {
00138 return msec2fps(pimpl->cycle_msec_);
00139 }
00140
00141
00142 void CycleTimer::setCycleMsec(size_t msec)
00143 {
00144 pimpl->cycle_msec_ = msec;
00145 }
00146
00147
00148 size_t CycleTimer::cycleMsec(void) const
00149 {
00150 return pimpl->cycle_msec_;
00151 }
00152
00153
00154 int CycleTimer::toNextCycleMsec(void)
00155 {
00156 return pimpl->toNextCycleMsec();
00157 }