source: trunk/src/timer.cpp @ 2183

Last change on this file since 2183 was 2183, checked in by sam, 7 years ago

build: fix the WTFPL site URL in all code comments.

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