Panda3D
clockObject.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file clockObject.I
10  * @author drose
11  * @date 2000-02-17
12  */
13 
14 /**
15  *
16  */
17 INLINE ClockObject::
18 ~ClockObject() {
19 }
20 
21 /**
22  * Returns the current mode of the clock. See set_mode().
23  */
24 INLINE ClockObject::Mode ClockObject::
25 get_mode() const {
26  return _mode;
27 }
28 
29 /**
30  * Returns the time in seconds as of the last time tick() was called
31  * (typically, this will be as of the start of the current frame).
32  *
33  * This is generally the kind of time you want to ask for in most rendering
34  * and animation contexts, since it's important that all of the animation for
35  * a given frame remains in sync with each other.
36  */
37 INLINE double ClockObject::
38 get_frame_time(Thread *current_frame) const {
39  CDReader cdata(_cycler, current_frame);
40  return cdata->_reported_frame_time;
41 }
42 
43 /**
44  * Returns the actual number of seconds elapsed since the ClockObject was
45  * created, or since it was last reset. This is useful for doing real timing
46  * measurements, e.g. for performance statistics.
47  *
48  * This returns the most precise timer we have for short time intervals, but
49  * it may tend to drift over the long haul. If more accurate timekeeping is
50  * needed over a long period of time, use get_long_time() instead.
51  */
52 INLINE double ClockObject::
53 get_real_time() const {
54  return (_true_clock->get_short_time() - _start_short_time);
55 }
56 
57 /**
58  * Returns the actual number of seconds elapsed since the ClockObject was
59  * created, or since it was last reset.
60  *
61  * This is similar to get_real_time(), except that it uses the most accurate
62  * counter we have over a long period of time, and so it is less likely to
63  * drift. However, it may not be very precise for measuring short intervals.
64  * On Windows, for instace, this is only accurate to within about 55
65  * milliseconds.
66  */
67 INLINE double ClockObject::
68 get_long_time() const {
69  return (_true_clock->get_long_time() - _start_long_time);
70 }
71 
72 /**
73  * Simultaneously resets both the time and the frame count to zero.
74  */
75 INLINE void ClockObject::
76 reset() {
77  set_real_time(0.0);
78  set_frame_time(0.0);
79  set_frame_count(0);
80 }
81 
82 /**
83  * Returns the number of times tick() has been called since the ClockObject
84  * was created, or since it was last reset. This is generally the number of
85  * frames that have been rendered.
86  */
87 INLINE int ClockObject::
88 get_frame_count(Thread *current_thread) const {
89  CDReader cdata(_cycler, current_thread);
90  return cdata->_frame_count;
91 }
92 
93 /**
94  * Returns the average frame rate since the last reset. This is simply the
95  * total number of frames divided by the total elapsed time. This reports the
96  * virtual frame rate if the clock is in (or has been in) M_non_real_time
97  * mode.
98  */
99 INLINE double ClockObject::
100 get_net_frame_rate(Thread *current_thread) const {
101  CDReader cdata(_cycler, current_thread);
102  return (double)cdata->_frame_count / cdata->_reported_frame_time;
103 }
104 
105 /**
106  * Returns the elapsed time for the previous frame: the number of seconds
107  * elapsed between the last two calls to tick().
108  */
109 INLINE double ClockObject::
110 get_dt(Thread *current_thread) const {
111  CDReader cdata(_cycler, current_thread);
112  if (_max_dt > 0.0) {
113  return std::min(_max_dt, cdata->_dt);
114  }
115  return cdata->_dt;
116 }
117 
118 /**
119  * Returns the current maximum allowable time elapsed between any two frames.
120  * See set_max_dt().
121  */
122 INLINE double ClockObject::
123 get_max_dt() const {
124  return _max_dt;
125 }
126 
127 /**
128  * Sets a limit on the value returned by get_dt(). If this value is less than
129  * zero, no limit is imposed; otherwise, this is the maximum value that will
130  * ever be returned by get_dt(), regardless of how much time has actually
131  * elapsed between frames.
132  *
133  * This limit is only imposed in real-time mode; in non-real-time mode, the dt
134  * is fixed anyway and max_dt is ignored.
135  *
136  * This is generally used to guarantee reasonable behavior even in the
137  * presence of a very slow or chuggy frame rame.
138  */
139 INLINE void ClockObject::
140 set_max_dt(double max_dt) {
141  _max_dt = max_dt;
142 }
143 
144 /**
145  * In degrade mode, returns the ratio by which the performance is degraded. A
146  * value of 2.0 causes the clock to be slowed down by a factor of two
147  * (reducing performance to 1/2 what would be otherwise).
148  *
149  * This has no effect if mode is not M_degrade.
150  */
151 INLINE double ClockObject::
152 get_degrade_factor() const {
153  return _degrade_factor;
154 }
155 
156 /**
157  * In degrade mode, sets the ratio by which the performance is degraded. A
158  * value of 2.0 causes the clock to be slowed down by a factor of two
159  * (reducing performance to 1/2 what would be otherwise).
160  *
161  * This has no effect if mode is not M_degrade.
162  */
163 INLINE void ClockObject::
164 set_degrade_factor(double degrade_factor) {
165  _degrade_factor = degrade_factor;
166 }
167 
168 /**
169  * Specifies the interval of time (in seconds) over which
170  * get_average_frame_rate() averages the number of frames per second to
171  * compute the frame rate. Changing this does not necessarily immediately
172  * change the result of get_average_frame_rate(), until this interval of time
173  * has elapsed again.
174  *
175  * Setting this to zero disables the computation of get_average_frame_rate().
176  */
177 INLINE void ClockObject::
178 set_average_frame_rate_interval(double time) {
179  _average_frame_rate_interval = time;
180  if (_average_frame_rate_interval == 0.0) {
181  _ticks.clear();
182  }
183 }
184 
185 /**
186  * Returns the interval of time (in seconds) over which
187  * get_average_frame_rate() averages the number of frames per second to
188  * compute the frame rate.
189  */
190 INLINE double ClockObject::
191 get_average_frame_rate_interval() const {
192  return _average_frame_rate_interval;
193 }
194 
195 /**
196  * Returns true if a clock error was detected since the last time
197  * check_errors() was called. A clock error means that something happened, an
198  * OS or BIOS bug, for instance, that makes the current value of the clock
199  * somewhat suspect, and an application may wish to resynchronize with any
200  * external clocks.
201  */
202 INLINE bool ClockObject::
203 check_errors(Thread *current_thread) {
204  CDReader cdata(_cycler, current_thread); // Just to hold a mutex.
205  int orig_error_count = _error_count;
206  _error_count = _true_clock->get_error_count();
207  return (_error_count != orig_error_count);
208 }
209 
210 /**
211  * Returns a pointer to the global ClockObject. This is the ClockObject that
212  * most code should use for handling scene graph rendering and animation.
213  */
216  ClockObject *clock = (ClockObject *)AtomicAdjust::get_ptr(_global_clock);
217  if (UNLIKELY(clock == nullptr)) {
218  make_global_clock();
219  clock = (ClockObject *)_global_clock;
220  }
221  return clock;
222 }
223 
224 /**
225  *
226  */
227 INLINE ClockObject::CData::
228 CData(const ClockObject::CData &copy) :
229  _frame_count(copy._frame_count),
230  _reported_frame_time(copy._reported_frame_time),
231  _dt(copy._dt)
232 {
233 }
234 
235 /**
236  *
237  */
238 INLINE TimeVal::
239 TimeVal() {
240 }
241 
242 /**
243  *
244  */
245 INLINE ulong TimeVal::
246 get_sec() const {
247  return tv[0];
248 }
249 
250 /**
251  *
252  */
253 INLINE ulong TimeVal::
254 get_usec() const {
255  return tv[1];
256 }
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:215
static Pointer get_ptr(const Pointer &var)
Atomically retrieves the snapshot value of the indicated variable.
set_real_time
Resets the clock to the indicated time.
Definition: clockObject.h:92
double get_net_frame_rate(Thread *current_thread=Thread::get_current_thread()) const
Returns the average frame rate since the last reset.
Definition: clockObject.I:100
set_max_dt
Sets a limit on the value returned by get_dt().
Definition: clockObject.h:103
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
set_average_frame_rate_interval
Specifies the interval of time (in seconds) over which get_average_frame_rate() averages the number o...
Definition: clockObject.h:113
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
Definition: clockObject.h:91
get_frame_count
Returns the number of times tick() has been called since the ClockObject was created,...
Definition: clockObject.h:94
A ClockObject keeps track of elapsed real time and discrete time.
Definition: clockObject.h:58
get_error_count
Returns the number of clock errors that have been detected.
Definition: trueClock.h:53
set_frame_count
Resets the number of frames counted to the indicated number.
Definition: clockObject.h:94
A thread; that is, a lightweight process.
Definition: thread.h:46
set_degrade_factor
In degrade mode, sets the ratio by which the performance is degraded.
Definition: clockObject.h:107
bool check_errors(Thread *current_thread)
Returns true if a clock error was detected since the last time check_errors() was called.
Definition: clockObject.I:203
void reset()
Simultaneously resets both the time and the frame count to zero.
Definition: clockObject.I:76
set_frame_time
Changes the time as reported for the current frame to the indicated time.
Definition: clockObject.h:91
get_dt
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...
Definition: clockObject.h:99