I'm writing a standard game loop using std::chrono. I need to pass a float to my render method that represents how far into the next frame I am. To calculate the number I'm using the count() method of chrono::duration, hence I need to convert two durations to the same ratio.
void engine::run() {
using namespace std::chrono;
using updates = duration<steady_clock::rep, std::ratio<1, 40>>;
using common = std::common_type<updates, steady_clock::duration>::type;
constexpr updates time_per_update{1};
auto previous = steady_clock::now();
auto lag = steady_clock::duration::zero();
while (!quit) {
auto now = steady_clock::now();
auto delta = now - previous;
previous = now;
lag += delta;
while (lag >= time_per_update) {
lag -= time_per_update;
update(time_per_update);
}
render(common{lag}.count() / static_cast<double>(common{time_per_update}.count()));
}
}
If I change the ratio in 'updates' to, say 41, I get a compile error at the subtraction, because a 1/41 of a second cannot be precisely converted to steady_clock::duration. However, when I rewrite the code to this, it compiles just fine:
void engine::run() {
using namespace std::chrono;
using updates = duration<steady_clock::rep, std::ratio<1, 41>>;
using common = std::common_type<updates, steady_clock::duration>::type;
constexpr common time_per_update{updates{1}};
auto previous = steady_clock::now();
common lag = steady_clock::duration::zero();
while (!quit) {
auto now = steady_clock::now();
auto delta = now - previous;
previous = now;
lag += delta;
while (lag >= time_per_update) {
lag -= time_per_update;
update(time_per_update);
}
render(lag.count() / static_cast<double>(time_per_update.count()));
}
}
I was under the impression the conversion to common_type happens implicitly during the subtraction. What am I missing? Is there a better way to do this?
size_tand then compute lags in a POD type (size_t,int64_t,...) as differences. Use for examplesize_t microseconds=std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();and adjustmicrosecondstonanosecondsif you need such a precision.