source: trunk/src/timer.cpp @ 1309

Last change on this file since 1309 was 1309, checked in by sam, 8 years ago

core: make timers second-based rather than millisecond-based.

  • Property svn:keywords set to Id
File size: 3.9 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 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 __native_client__ || defined __APPLE__
19#   include <sys/time.h>
20#   include <unistd.h>
21#elif defined _XBOX
22#   include <xtl.h>
23#   undef near /* Fuck Microsoft */
24#   undef far /* Fuck Microsoft again */
25#   include <xbox.h>
26#elif defined _WIN32
27#   define WIN32_LEAN_AND_MEAN
28#   include <windows.h>
29#elif defined __CELLOS_LV2__
30#   include <sys/sys_time.h>
31#   include <sys/timer.h>
32#   include <sys/time_util.h>
33#else
34#   include <SDL.h>
35#endif
36
37#include "core.h"
38
39namespace lol
40{
41
42/*
43 * Timer implementation class
44 */
45
46class TimerData
47{
48    friend class Timer;
49
50private:
51    TimerData()
52    {
53#if defined __linux__ || defined __native_client__ || defined __APPLE__
54        gettimeofday(&tv0, NULL);
55#elif defined _WIN32
56        QueryPerformanceCounter(&cycles0);
57#elif defined __CELLOS_LV2__
58        SYS_TIMEBASE_GET(cycles0);
59#else
60        SDL_Init(SDL_INIT_TIMER);
61        ticks0 = SDL_GetTicks();
62#endif
63    }
64
65    float GetOrWait(float seconds, bool update)
66    {
67        float secs_elapsed, secs_towait;
68#if defined __linux__ || defined __native_client__ || defined __APPLE__
69        struct timeval tv;
70        gettimeofday(&tv, NULL);
71        secs_elapsed = 1e-6f * (tv.tv_usec - tv0.tv_usec)
72                     + (tv.tv_sec - tv0.tv_sec);
73        if (update)
74            tv0 = tv;
75        secs_towait = seconds - secs_elapsed;
76        if (secs_towait > 0.0f)
77            usleep((int)(secs_towait * 1e6f));
78#elif defined _WIN32
79        LARGE_INTEGER cycles;
80        QueryPerformanceCounter(&cycles);
81        static float secs_per_cycle = GetSecondsPerCycle();
82        secs_elapsed = secs_per_cycle * (cycles.QuadPart - cycles0.QuadPart);
83        if (update)
84            cycles0 = cycles;
85        secs_towait = seconds - secs_elapsed;
86        if (secs_towait > 5e-4f)
87            Sleep((int)(secs_towait * 1e3f + 0.5f));
88#elif defined __CELLOS_LV2__
89        uint64_t cycles;
90        SYS_TIMEBASE_GET(cycles);
91        static float secs_per_cycle = GetSecondsPerCycle();
92        secs_elapsed = secs_per_cycle * (cycles - cycles0);
93        if (update)
94            cycles0 = cycles;
95        secs_towait = seconds - secs_elapsed;
96        if (secs_towait > 0.0f)
97            sys_timer_usleep((int)(secs_towait * 1e6f));
98#else
99        /* The crappy SDL fallback */
100        Uint32 ticks = SDL_GetTicks();
101        secs_elapsed = 1e-3f * (ticks - ticks0);
102        if (update)
103            ticks0 = ticks;
104        secs_towait = seconds - secs_elapsed;
105        if (secs_towait > 5e-4f)
106            SDL_Delay((int)(secs_towait * 1e3f + 0.5f));
107#endif
108        return secs_elapsed;
109    }
110
111    static float GetSecondsPerCycle()
112    {
113#if defined __linux__ || defined __native_client__ || defined __APPLE__
114        return 1e-3f;
115#elif defined _WIN32
116        LARGE_INTEGER tmp;
117        QueryPerformanceFrequency(&tmp);
118        return 1.f / tmp.QuadPart;
119#elif defined __CELLOS_LV2__
120        return 1.f / sys_time_get_timebase_frequency();
121#else
122        return 1e-3f;
123#endif
124    }
125
126#if defined __linux__ || defined __native_client__ || defined __APPLE__
127    struct timeval tv0;
128#elif defined _WIN32
129    LARGE_INTEGER cycles0;
130#elif defined __CELLOS_LV2__
131    uint64_t cycles0;
132#else
133    Uint32 ticks0;
134#endif
135};
136
137/*
138 * Timer public class
139 */
140
141Timer::Timer()
142  : data(new TimerData())
143{
144}
145
146Timer::~Timer()
147{
148    delete data;
149}
150
151float Timer::Get()
152{
153    return data->GetOrWait(0.0f, true);
154}
155
156float Timer::Poll()
157{
158    return data->GetOrWait(0.0f, false);
159}
160
161void Timer::Wait(float seconds)
162{
163    (void)data->GetOrWait(seconds, false);
164}
165
166} /* namespace lol */
167
Note: See TracBrowser for help on using the repository browser.