source: abuse/trunk/src/lol/timer.cpp @ 682

Last change on this file since 682 was 574, checked in by Sam Hocevar, 9 years ago

lol: add the cross-platform Timer class from Lol Engine.

File size: 3.6 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstdlib>
16#include <stdint.h>
17
18#if defined __linux__ || defined __APPLE__
19#   include <sys/time.h>
20#   include <unistd.h>
21#elif defined _WIN32
22#   define WIN32_LEAN_AND_MEAN
23#   include <windows.h>
24#elif defined __CELLOS_LV2__
25#   include <sys/sys_time.h>
26#   include <sys/timer.h>
27#   include <sys/time_util.h>
28#else
29#   include <SDL.h>
30#endif
31
32#include "common.h"
33
34namespace lol
35{
36
37/*
38 * Timer implementation class
39 */
40
41class TimerData
42{
43    friend class Timer;
44
45private:
46    TimerData()
47    {
48#if defined __linux__ || defined __APPLE__
49        gettimeofday(&tv0, NULL);
50#elif defined _WIN32
51        QueryPerformanceCounter(&cycles0);
52#elif defined __CELLOS_LV2__
53        SYS_TIMEBASE_GET(cycles0);
54#else
55        SDL_Init(SDL_INIT_TIMER);
56        ticks0 = SDL_GetTicks();
57#endif
58    }
59
60    float GetOrWait(float deltams, bool update)
61    {
62        float ret, towait;
63#if defined __linux__ || defined __APPLE__
64        struct timeval tv;
65        gettimeofday(&tv, NULL);
66        ret = 1e-3f * (tv.tv_usec - tv0.tv_usec)
67            + 1e3f * (tv.tv_sec - tv0.tv_sec);
68        if (update)
69            tv0 = tv;
70        towait = deltams - ret;
71        if (towait > 0.0f)
72            usleep((int)(towait * 1e3f));
73#elif defined _WIN32
74        LARGE_INTEGER cycles;
75        QueryPerformanceCounter(&cycles);
76        static float ms_per_cycle = GetMsPerCycle();
77        ret = ms_per_cycle * (cycles.QuadPart - cycles0.QuadPart);
78        if (update)
79            cycles0 = cycles;
80        towait = deltams - ret;
81        if (towait > 5e-4f)
82            Sleep((int)(towait + 0.5f));
83#elif defined __CELLOS_LV2__
84        uint64_t cycles;
85        SYS_TIMEBASE_GET(cycles);
86        static float ms_per_cycle = GetMsPerCycle();
87        ret = ms_per_cycle * (cycles - cycles0);
88        if (update)
89            cycles0 = cycles;
90        towait = deltams - ret;
91        if (towait > 0.0f)
92            sys_timer_usleep((int)(towait * 1e3f));
93#else
94        /* The crappy SDL fallback */
95        Uint32 ticks = SDL_GetTicks();
96        ret = ticks - ticks0;
97        if (update)
98            ticks0 = ticks;
99        towait = deltams - ret;
100        if (towait > 0.5f)
101            SDL_Delay((int)(towait + 0.5f));
102#endif
103        return ret;
104    }
105
106    static float GetMsPerCycle()
107    {
108#if defined __linux__ || defined __APPLE__
109        return 1.0f;
110#elif defined _WIN32
111        LARGE_INTEGER tmp;
112        QueryPerformanceFrequency(&tmp);
113        return = 1e3f / tmp.QuadPart;
114#elif defined __CELLOS_LV2__
115        return 1e3f / sys_time_get_timebase_frequency();
116#else
117        return 1.0f;
118#endif
119    }
120
121#if defined __linux__ || defined __APPLE__
122    struct timeval tv0;
123#elif defined _WIN32
124    LARGE_INTEGER cycles0;
125#elif defined __CELLOS_LV2__
126    uint64_t cycles0;
127#else
128    Uint32 ticks0;
129#endif
130};
131
132/*
133 * Timer public class
134 */
135
136Timer::Timer()
137  : data(new TimerData())
138{
139}
140
141Timer::~Timer()
142{
143    delete data;
144}
145
146float Timer::GetMs()
147{
148    return data->GetOrWait(0.0f, true);
149}
150
151float Timer::PollMs()
152{
153    return data->GetOrWait(0.0f, false);
154}
155
156void Timer::WaitMs(float deltams)
157{
158    (void)data->GetOrWait(deltams, false);
159}
160
161} /* namespace lol */
162
Note: See TracBrowser for help on using the repository browser.