~kazade/kaztimer/trunk

« back to all changes in this revision

Viewing changes to src/kaztimer.cpp

  • Committer: Luke Benstead
  • Date: 2011-01-17 20:06:01 UTC
  • Revision ID: kazade@gmail.com-20110117200601-rsk8k5rm8x1p5te7
Initial implementation

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <ctime>
 
2
#include <boost/shared_ptr.hpp>
 
3
#include <map>
 
4
#include "kaztimer.h"
 
5
 
 
6
class Timer {
 
7
public:
 
8
    Timer():
 
9
        step_(-1),
 
10
        accumulator_(0.0f) {
 
11
 
 
12
        set_game_timer();
 
13
    }
 
14
 
 
15
    void set_fixed(int step) {
 
16
        step_ = step;
 
17
        is_fixed_ = true;
 
18
        last_time_ = get_current_time_in_ms();
 
19
        accumulator_ = 0.0f;
 
20
    }
 
21
 
 
22
    void set_game_timer() {
 
23
        step_ = -1;
 
24
        is_fixed_ = false;
 
25
        last_time_ = get_current_time_in_ms();
 
26
    }
 
27
    
 
28
    void update_frame_time() {
 
29
        frame_time_ = get_elapsed_time();
 
30
        if(frame_time_ > 0.25) {
 
31
            frame_time_ = 0.25;
 
32
        }        
 
33
        
 
34
        if(is_fixed_) {
 
35
            accumulator_ += frame_time_;
 
36
        }         
 
37
    }
 
38
 
 
39
    bool can_update() {
 
40
        if(!is_fixed_) {            
 
41
            return true;
 
42
        }
 
43
        
 
44
        double fixed_step = get_fixed_step();
 
45
        if(accumulator_ >= fixed_step) {
 
46
            accumulator_ -= fixed_step;
 
47
            return true;
 
48
        }
 
49
        
 
50
        return false;
 
51
    }
 
52
 
 
53
    double get_fixed_step() {
 
54
        return 1.0 / double(step_);
 
55
    }
 
56
 
 
57
    double get_delta_time() {                    
 
58
        if(is_fixed_) {                                    
 
59
            return get_fixed_step();
 
60
        }
 
61
 
 
62
        return frame_time_;
 
63
    }
 
64
 
 
65
    double get_elapsed_time() {
 
66
        long current_time = get_current_time_in_ms();
 
67
        double elapsed = double(current_time - last_time_) * 0.001;
 
68
        last_time_ = current_time;
 
69
        return elapsed;
 
70
    }
 
71
 
 
72
    long get_current_time_in_ms() {
 
73
#ifdef WIN32
 
74
        return timeGetTime();
 
75
#else
 
76
        timespec ts;
 
77
        clock_gettime(CLOCK_REALTIME, &ts);
 
78
        return (long) (ts.tv_sec * 1000.0) + ts.tv_nsec / 1000000.0;
 
79
#endif
 
80
    }
 
81
 
 
82
private:
 
83
    int step_;
 
84
    bool is_fixed_;
 
85
 
 
86
    long last_time_;
 
87
    double accumulator_;
 
88
    double frame_time_;
 
89
};
 
90
 
 
91
static std::map<KTIuint, boost::shared_ptr<Timer> > timers_;
 
92
 
 
93
static KTIuint bound_timer_id_ = 0;
 
94
static KTIuint current_timer_id_ = 0;
 
95
 
 
96
KTIuint get_next_timer_id() {
 
97
    return ++current_timer_id_;
 
98
}
 
99
 
 
100
Timer* get_bound_timer() {
 
101
    if(timers_.find(bound_timer_id_) == timers_.end()) {
 
102
        return NULL;
 
103
    }
 
104
 
 
105
    return timers_[bound_timer_id_].get();
 
106
}
 
107
 
 
108
void ktiGenTimers(KTIsizei n, KTIuint* names) {
 
109
    for(KTIuint i = 0; i < n; ++i) {
 
110
        KTIuint new_id = get_next_timer_id();
 
111
        timers_[new_id].reset(new Timer());
 
112
        names[i] = new_id;
 
113
    }
 
114
}
 
115
 
 
116
void ktiBindTimer(KTIuint name) {
 
117
    if(timers_.find(name) == timers_.end()) {
 
118
        bound_timer_id_ = 0;
 
119
    }
 
120
 
 
121
    bound_timer_id_ = name;
 
122
}
 
123
 
 
124
void ktiStartFixedStepTimer(KTIint steps_per_second) {
 
125
    Timer* timer = get_bound_timer();
 
126
    if(!timer) {
 
127
        return;
 
128
    }
 
129
 
 
130
    timer->set_fixed(steps_per_second);
 
131
}
 
132
 
 
133
void ktiStartGameTimer() {
 
134
    Timer* timer = get_bound_timer();
 
135
    if(!timer) {
 
136
        return;
 
137
    }
 
138
 
 
139
    timer->set_game_timer();
 
140
}
 
141
 
 
142
KTIbool ktiTimerCanUpdate() {
 
143
    Timer* timer = get_bound_timer();
 
144
    if(!timer) {
 
145
        return false;
 
146
    }
 
147
 
 
148
    return timer->can_update();
 
149
}
 
150
 
 
151
void ktiUpdateFrameTime() {
 
152
    Timer* timer = get_bound_timer();
 
153
    if(!timer) {
 
154
        return;
 
155
    }    
 
156
    
 
157
    timer->update_frame_time();
 
158
}
 
159
 
 
160
KTIdouble ktiGetDeltaTime() {
 
161
    Timer* timer = get_bound_timer();
 
162
    if(!timer) {
 
163
        return 0.0;
 
164
    }
 
165
 
 
166
    return timer->get_delta_time();
 
167
}
 
168
 
 
169
void ktiDeleteTimers(KTIsizei n, const KTIuint* names) {
 
170
    for(KTIuint i = 0; i < n; ++i) {
 
171
        timers_.erase(names[i]);
 
172
    }
 
173
}