У меня интересная, но странная проблема с игровым таймером. Кажется, миллисекунды работают просто отлично. Тем не менее, когда я пытаюсь применить std::chrono::seconds
бросил я вдруг получаю 0.000000
при броске на поплавок.
Мой таймер выглядит следующим образом:
#include <iostream>
#include <time.h>
#include <chrono>class Timer
{
public:
typedef std::chrono::high_resolution_clock Time;
typedef std::chrono::milliseconds ms; //<--If changed to seconds, I get 0.00000
typedef std::chrono::duration<float> fsec;
std::chrono::high_resolution_clock::time_point m_timestamp;
float currentElapsed;
Timer()
{
m_timestamp = Time::now();
}
float getTimeElapsed()
{
return currentElapsed;
}
void Tick()
{
currentElapsed = std::chrono::duration_cast<ms>(Time::now() - m_timestamp).count();
m_timestamp = Time::now();
}
public:
//Singleton stuff
static Timer* Instance();
static void Create();
};
Таймер ставится один раз за кадр. Так, например, я обычно получаю около 33 мс на кадр. 33ms / 1000 = 0.033s
секунд, так что должно быть много места для битов, чтобы держать это.
Есть идеи о том, что может происходить?
Любая помощь очень ценится!
РЕДАКТИРОВАТЬ: Извините, секунды, а не миллисекунды
std::chrono::seconds
и другие. все они имеют целочисленные представления (C ++ 11 §20.11.2 [time.syn]). Когда вы преобразуете длительность с высоким разрешением в длительность с низким разрешением, вы выполняете целочисленное деление с результирующим усечением, например,
using namespace std::chrono;
assert(duration_cast<seconds>(milliseconds{999}) == seconds{0});
Вы можете избежать этого усечения, переключившись на представление с плавающей запятой до масштабирование вместо после:
using namespace std::chrono;
currentElapsed = duration_cast<duration<float,std::milli>>(Time::now() - m_timestamp).count();
Еще лучше, хранить currentElapsed
как duration
сохранить «единицы», связанные с величиной:
class Timer {
typedef std::chrono::high_resolution_clock Time;
typedef std::chrono::duration<float> duration;
Time::time_point m_timestamp;
duration currentElapsed;
public:
Timer() : m_timestamp(Time::now()) {}
duration getTimeElapsed() const {
return currentElapsed;
}
void Tick() {
auto now = Time::now();
currentElapsed = now - m_timestamp;
m_timestamp = now;
}
};
Других решений пока нет …