Clean up getTime helpers

This increases size of the getTime return values to 64 bits.
It also removes the TimeGetter classes since the getTime functions
are now very precise.
master
ShadowNinja 2016-03-06 14:31:16 -05:00
parent 7f4cdbcbe9
commit b662a4577d
22 changed files with 116 additions and 216 deletions

View File

@ -1618,7 +1618,7 @@ float Client::mediaReceiveProgress()
typedef struct TextureUpdateArgs {
IrrlichtDevice *device;
gui::IGUIEnvironment *guienv;
u32 last_time_ms;
u64 last_time_ms;
u16 last_percent;
const wchar_t* text_base;
ITextureSource *tsrc;
@ -1634,7 +1634,7 @@ void texture_update_progress(void *args, u32 progress, u32 max_progress)
u32 time_ms = targs->last_time_ms;
if (cur_percent != targs->last_percent) {
targs->last_percent = cur_percent;
time_ms = getTimeMs();
time_ms = porting::getTimeMs();
// only draw when the user will notice something:
do_draw = (time_ms - targs->last_time_ms > 100);
}
@ -1692,7 +1692,7 @@ void Client::afterContentReceived(IrrlichtDevice *device)
TextureUpdateArgs tu_args;
tu_args.device = device;
tu_args.guienv = guienv;
tu_args.last_time_ms = getTimeMs();
tu_args.last_time_ms = porting::getTimeMs();
tu_args.last_percent = 0;
tu_args.text_base = wgettext("Initializing nodes");
tu_args.tsrc = m_tsrc;

View File

@ -51,22 +51,6 @@ bool noMenuActive()
MainGameCallback *g_gamecallback = NULL;
// Instance of the time getter
static TimeGetter *g_timegetter = NULL;
u32 getTimeMs()
{
if (g_timegetter == NULL)
return 0;
return g_timegetter->getTime(PRECISION_MILLI);
}
u32 getTime(TimePrecision prec) {
if (g_timegetter == NULL)
return 0;
return g_timegetter->getTime(prec);
}
ClientLauncher::~ClientLauncher()
{
if (receiver)
@ -96,9 +80,6 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
return false;
}
// Create time getter
g_timegetter = new IrrlichtTimeGetter(device);
// Speed tests (done after irrlicht is loaded to get timer)
if (cmd_args.getFlag("speedtests")) {
dstream << "Running speed tests" << std::endl;

View File

@ -24,42 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/inputhandler.h"
#include "gameparams.h"
// A small helper class
class TimeGetter
{
public:
virtual u32 getTime(TimePrecision prec) = 0;
};
// A precise irrlicht one
class IrrlichtTimeGetter: public TimeGetter
{
public:
IrrlichtTimeGetter(IrrlichtDevice *device):
m_device(device)
{}
u32 getTime(TimePrecision prec)
{
if (prec == PRECISION_MILLI) {
if (m_device == NULL)
return 0;
return m_device->getTimer()->getRealTime();
} else {
return porting::getTime(prec);
}
}
private:
IrrlichtDevice *m_device;
};
// Not so precise one which works without irrlicht
class SimpleTimeGetter: public TimeGetter
{
public:
u32 getTime(TimePrecision prec)
{
return porting::getTime(prec);
}
};
class ClientLauncher
{

View File

@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "keys.h"
#include "settings.h"
#include "gettime.h"
#include "porting.h"
#include "../util/string.h"
bool JoystickButtonCmb::isTriggered(const irr::SEvent::SJoystickEvent &ev) const
@ -199,7 +200,7 @@ bool JoystickController::handleEvent(const irr::SEvent::SJoystickEvent &ev)
if (ev.Joystick != m_joystick_id)
return false;
m_internal_time = getTimeMs() / 1000.f;
m_internal_time = porting::getTimeMs() / 1000.f;
std::bitset<KeyType::INTERNAL_ENUM_COUNT> keys_pressed;

View File

@ -592,7 +592,7 @@ void RemoteClient::notifyEvent(ClientStateEvent event)
u32 RemoteClient::uptime()
{
return getTime(PRECISION_SECONDS) - m_connection_time;
return porting::getTime(PRECISION_SECONDS) - m_connection_time;
}
ClientInterface::ClientInterface(con::Connection* con)

View File

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "threading/mutex.h"
#include "network/networkpacket.h"
#include "util/cpp11_container.h"
#include "porting.h"
#include <list>
#include <vector>
@ -265,7 +266,7 @@ public:
m_version_patch(0),
m_full_version("unknown"),
m_deployed_compression(0),
m_connection_time(getTime(PRECISION_SECONDS))
m_connection_time(porting::getTime(PRECISION_SECONDS))
{
}
~RemoteClient()

View File

@ -71,7 +71,7 @@ int Database_SQLite3::busyHandler(void *data, int count)
{
s64 &first_time = reinterpret_cast<s64 *>(data)[0];
s64 &prev_time = reinterpret_cast<s64 *>(data)[1];
s64 cur_time = getTimeMs();
s64 cur_time = porting::getTimeMs();
if (count == 0) {
first_time = cur_time;

View File

@ -21,33 +21,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define GETTIME_HEADER
#include "irrlichttypes.h"
#include <time.h>
#include <string>
/*
Get a millisecond counter value.
Precision depends on implementation.
Overflows at any value above 10000000.
Implementation of this is done in:
Normal build: main.cpp
Server build: servermain.cpp
*/
enum TimePrecision
{
PRECISION_SECONDS = 0,
PRECISION_SECONDS,
PRECISION_MILLI,
PRECISION_MICRO,
PRECISION_NANO
};
extern u32 getTimeMs();
extern u32 getTime(TimePrecision prec);
/*
Timestamp stuff
*/
#include <string>
#include <time.h>
inline std::string getTimestamp()
{

View File

@ -55,7 +55,7 @@ GUIChatConsole::GUIChatConsole(
m_client(client),
m_menumgr(menumgr),
m_screensize(v2u32(0,0)),
m_animate_time_old(0),
m_animate_time_old(porting::getTimeMs()),
m_open(false),
m_close_on_enter(false),
m_height(0),
@ -71,8 +71,6 @@ GUIChatConsole::GUIChatConsole(
m_font(NULL),
m_fontsize(0, 0)
{
m_animate_time_old = getTimeMs();
// load background settings
s32 console_alpha = g_settings->getS32("console_alpha");
m_background_color.setAlpha(clamp_u8(console_alpha));
@ -124,7 +122,7 @@ void GUIChatConsole::openConsole(f32 scale)
m_desired_height_fraction = scale;
m_desired_height = scale * m_screensize.Y;
reformatConsole();
m_animate_time_old = getTimeMs();
m_animate_time_old = porting::getTimeMs();
IGUIElement::setVisible(true);
Environment->setFocus(this);
m_menumgr->createdMenu(this);
@ -212,7 +210,7 @@ void GUIChatConsole::draw()
}
// Animation
u32 now = getTimeMs();
u64 now = porting::getTimeMs();
animate(now - m_animate_time_old);
m_animate_time_old = now;

View File

@ -98,7 +98,7 @@ private:
v2u32 m_screensize;
// used to compute how much time passed since last animate()
u32 m_animate_time_old;
u64 m_animate_time_old;
// should the console be opened or closed?
bool m_open;

View File

@ -2664,9 +2664,9 @@ void GUIFormSpecMenu::drawMenu()
m_old_tooltip = L"";
} else {
if (id == m_old_tooltip_id) {
delta = porting::getDeltaMs(m_hovered_time, getTimeMs());
delta = porting::getDeltaMs(m_hovered_time, porting::getTimeMs());
} else {
m_hovered_time = getTimeMs();
m_hovered_time = porting::getTimeMs();
m_old_tooltip_id = id;
}
}
@ -3244,10 +3244,10 @@ bool GUIFormSpecMenu::DoubleClickDetection(const SEvent event)
m_doubleclickdetect[0].time = m_doubleclickdetect[1].time;
m_doubleclickdetect[1].pos = m_pointer;
m_doubleclickdetect[1].time = getTimeMs();
m_doubleclickdetect[1].time = porting::getTimeMs();
}
else if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
u32 delta = porting::getDeltaMs(m_doubleclickdetect[0].time, getTimeMs());
u32 delta = porting::getDeltaMs(m_doubleclickdetect[0].time, porting::getTimeMs());
if (delta > 400) {
return false;
}

View File

@ -421,7 +421,7 @@ protected:
gui::IGUIStaticText *m_tooltip_element;
u32 m_tooltip_show_delay;
s32 m_hovered_time;
s64 m_hovered_time;
s32 m_old_tooltip_id;
std::wstring m_old_tooltip;
@ -527,7 +527,7 @@ private:
struct clickpos
{
v2s32 pos;
s32 time;
s64 time;
};
clickpos m_doubleclickdetect[2];

View File

@ -828,7 +828,7 @@ bool GUITable::OnEvent(const SEvent &event)
}
else if (event.KeyInput.PressedDown && event.KeyInput.Char) {
// change selection based on text as it is typed
s32 now = getTimeMs();
u64 now = porting::getTimeMs();
if (now - m_keynav_time >= 500)
m_keynav_buffer = L"";
m_keynav_time = now;

View File

@ -196,7 +196,7 @@ protected:
bool m_sel_doubleclick;
// Keyboard navigation stuff
s32 m_keynav_time;
u64 m_keynav_time;
core::stringw m_keynav_buffer;
// Drawing and geometry information

View File

@ -619,7 +619,7 @@ void Hud::resizeHotbar() {
}
struct MeshTimeInfo {
s32 time;
s64 time;
scene::IMesh *mesh;
};
@ -653,9 +653,9 @@ void drawItemStack(video::IVideoDriver *driver,
MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
if (mesh != ti.mesh) {
ti.mesh = mesh;
ti.time = getTimeMs();
ti.time = porting::getTimeMs();
} else {
delta = porting::getDeltaMs(ti.time, getTimeMs()) % 100000;
delta = porting::getDeltaMs(ti.time, porting::getTimeMs()) % 100000;
}
}
core::rect<s32> oldViewPort = driver->getViewPort();

View File

@ -107,24 +107,6 @@ static bool migrate_map_database(const GameParams &game_params, const Settings &
/**********************************************************************/
/*
gettime.h implementation
*/
#ifdef SERVER
u32 getTimeMs()
{
/* Use imprecise system calls directly (from porting.h) */
return porting::getTime(PRECISION_MILLI);
}
u32 getTime(TimePrecision prec)
{
return porting::getTime(prec);
}
#endif
FileLogOutput file_log_output;

View File

@ -981,7 +981,7 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
time_until_purge *= 1000; // seconds -> milliseconds
u32 curr_time = getTime(PRECISION_MILLI);
u32 curr_time = porting::getTime(PRECISION_MILLI);
u32 prev_unprocessed = m_unprocessed_count;
m_unprocessed_count = m_transforming_liquid.size();

View File

@ -942,5 +942,18 @@ void attachOrCreateConsole(void)
#endif
}
// Load performance counter frequency only once at startup
#ifdef _WIN32
inline double get_perf_freq()
{
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return freq.QuadPart;
}
double perf_freq = get_perf_freq();
#endif
} //namespace porting

View File

@ -181,124 +181,99 @@ std::string get_sysinfo();
void initIrrlicht(irr::IrrlichtDevice * );
/*
Resolution is 10-20ms.
Remember to check for overflows.
Overflow can occur at any value higher than 10000000.
*/
// Monotonic counter getters.
#ifdef _WIN32 // Windows
inline u32 getTimeS()
{
return GetTickCount() / 1000;
}
extern double perf_freq;
inline u32 getTimeMs()
{
return GetTickCount();
}
inline u64 os_get_time(double mult)
{
LARGE_INTEGER t;
QueryPerformanceCounter(&t);
return static_cast<double>(t.QuadPart) / (perf_freq / mult);
}
inline u32 getTimeUs()
{
LARGE_INTEGER freq, t;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&t);
return (double)(t.QuadPart) / ((double)(freq.QuadPart) / 1000000.0);
}
inline u32 getTimeNs()
{
LARGE_INTEGER freq, t;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&t);
return (double)(t.QuadPart) / ((double)(freq.QuadPart) / 1000000000.0);
}
// Resolution is <1us.
inline u64 getTimeS() { return os_get_time(1); }
inline u64 getTimeMs() { return os_get_time(1000); }
inline u64 getTimeUs() { return os_get_time(1000*1000); }
inline u64 getTimeNs() { return os_get_time(1000*1000*1000); }
#else // Posix
inline void _os_get_clock(struct timespec *ts)
{
inline void os_get_clock(struct timespec *ts)
{
#if defined(__MACH__) && defined(__APPLE__)
// from http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
// OS X does not have clock_gettime, use clock_get_time
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
ts->tv_sec = mts.tv_sec;
ts->tv_nsec = mts.tv_nsec;
// From http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
// OS X does not have clock_gettime, use clock_get_time
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
ts->tv_sec = mts.tv_sec;
ts->tv_nsec = mts.tv_nsec;
#elif defined(CLOCK_MONOTONIC_RAW)
clock_gettime(CLOCK_MONOTONIC_RAW, ts);
clock_gettime(CLOCK_MONOTONIC_RAW, ts);
#elif defined(_POSIX_MONOTONIC_CLOCK)
clock_gettime(CLOCK_MONOTONIC, ts);
clock_gettime(CLOCK_MONOTONIC, ts);
#else
struct timeval tv;
gettimeofday(&tv, NULL);
TIMEVAL_TO_TIMESPEC(&tv, ts);
#endif // defined(__MACH__) && defined(__APPLE__)
}
struct timeval tv;
gettimeofday(&tv, NULL);
TIMEVAL_TO_TIMESPEC(&tv, ts);
#endif
}
// Note: these clock functions do not return wall time, but
// generally a clock that starts at 0 when the process starts.
inline u32 getTimeS()
{
struct timespec ts;
_os_get_clock(&ts);
return ts.tv_sec;
}
inline u64 getTimeS()
{
struct timespec ts;
os_get_clock(&ts);
return ts.tv_sec;
}
inline u32 getTimeMs()
{
struct timespec ts;
_os_get_clock(&ts);
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}
inline u64 getTimeMs()
{
struct timespec ts;
os_get_clock(&ts);
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}
inline u32 getTimeUs()
{
struct timespec ts;
_os_get_clock(&ts);
return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
}
inline u64 getTimeUs()
{
struct timespec ts;
os_get_clock(&ts);
return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
}
inline u32 getTimeNs()
{
struct timespec ts;
_os_get_clock(&ts);
return ts.tv_sec * 1000000000 + ts.tv_nsec;
}
inline u64 getTimeNs()
{
struct timespec ts;
os_get_clock(&ts);
return ts.tv_sec * 1000000000 + ts.tv_nsec;
}
/*#include <sys/timeb.h>
inline u32 getTimeMs()
{
struct timeb tb;
ftime(&tb);
return tb.time * 1000 + tb.millitm;
}*/
#endif
inline u32 getTime(TimePrecision prec)
inline u64 getTime(TimePrecision prec)
{
switch (prec) {
case PRECISION_SECONDS:
return getTimeS();
case PRECISION_MILLI:
return getTimeMs();
case PRECISION_MICRO:
return getTimeUs();
case PRECISION_NANO:
return getTimeNs();
case PRECISION_SECONDS: return getTimeS();
case PRECISION_MILLI: return getTimeMs();
case PRECISION_MICRO: return getTimeUs();
case PRECISION_NANO: return getTimeNs();
}
return 0;
FATAL_ERROR("Called getTime with invalid time precision");
}
/**
* Delta calculation function taking two 32bit arguments.
* @param old_time_ms old time for delta calculation (order is relevant!)
* @param new_time_ms new time for delta calculation (order is relevant!)
* @return positive 32bit delta value
* Delta calculation function arguments.
* @param old_time_ms old time for delta calculation
* @param new_time_ms new time for delta calculation
* @return positive delta value
*/
inline u32 getDeltaMs(u32 old_time_ms, u32 new_time_ms)
inline u64 getDeltaMs(u64 old_time_ms, u64 new_time_ms)
{
if (new_time_ms >= old_time_ms) {
return (new_time_ms - old_time_ms);

View File

@ -794,7 +794,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
if (m_move_id == -1) {
m_move_id = event.TouchInput.ID;
m_move_has_really_moved = false;
m_move_downtime = getTimeMs();
m_move_downtime = porting::getTimeMs();
m_move_downlocation = v2s32(event.TouchInput.X, event.TouchInput.Y);
m_move_sent_as_mouse_event = false;
}

View File

@ -186,7 +186,7 @@ private:
int m_move_id;
bool m_move_has_really_moved;
s32 m_move_downtime;
s64 m_move_downtime;
bool m_move_sent_as_mouse_event;
v2s32 m_move_downlocation;

View File

@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "timetaker.h"
#include "../gettime.h"
#include "../porting.h"
#include "../log.h"
#include <ostream>
@ -29,14 +29,14 @@ TimeTaker::TimeTaker(const char *name, u32 *result, TimePrecision prec)
m_result = result;
m_running = true;
m_precision = prec;
m_time1 = getTime(prec);
m_time1 = porting::getTime(prec);
}
u32 TimeTaker::stop(bool quiet)
{
if(m_running)
{
u32 time2 = getTime(m_precision);
u32 time2 = porting::getTime(m_precision);
u32 dtime = time2 - m_time1;
if(m_result != NULL)
{
@ -64,7 +64,7 @@ u32 TimeTaker::stop(bool quiet)
u32 TimeTaker::getTimerTime()
{
u32 time2 = getTime(m_precision);
u32 time2 = porting::getTime(m_precision);
u32 dtime = time2 - m_time1;
return dtime;
}