Panda3D
clockObject.h
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.h
10  * @author drose
11  * @date 1999-02-19
12  */
13 
14 #ifndef CLOCKOBJECT_H
15 #define CLOCKOBJECT_H
16 
17 #include "pandabase.h"
18 
19 #include "trueClock.h"
20 #include "pdeque.h"
21 #include "cycleData.h"
22 #include "cycleDataReader.h"
23 #include "cycleDataWriter.h"
24 #include "cycleDataStageReader.h"
25 #include "pipelineCycler.h"
26 #include "thread.h"
27 #include "referenceCount.h"
28 #include "pointerTo.h"
29 #include "vector_double.h" // needed to see exported allocators for pdeque
30 
31 class EXPCL_PANDA_PUTIL TimeVal {
32 PUBLISHED:
33  INLINE TimeVal();
34  INLINE ulong get_sec() const;
35  INLINE ulong get_usec() const;
36  ulong tv[2];
37 };
38 
39 /**
40  * A ClockObject keeps track of elapsed real time and discrete time. In
41  * normal mode, get_frame_time() returns the time as of the last time tick()
42  * was called. This is the "discrete" time, and is usually used to get the
43  * time as of, for instance, the beginning of the current frame.
44  *
45  * In other modes, as set by set_mode() or the clock-mode config variable,
46  * get_frame_time() may return other values to simulate different timing
47  * effects, for instance to perform non-real-time animation. See set_mode().
48  *
49  * In all modes, get_real_time() always returns the elapsed real time in
50  * seconds since the ClockObject was constructed, or since it was last reset.
51  *
52  * You can create your own ClockObject whenever you want to have your own
53  * local timer. There is also a default, global ClockObject intended to
54  * represent global time for the application; this is normally set up to tick
55  * every frame so that its get_frame_time() will return the time for the
56  * current frame.
57  */
58 class EXPCL_PANDA_PUTIL ClockObject : public ReferenceCount {
59 PUBLISHED:
60  enum Mode {
61  M_normal,
62  M_non_real_time,
63  M_forced,
64  M_degrade,
65  M_slave,
66  M_limited,
67  M_integer,
68  M_integer_limited,
69  };
70 
71  ClockObject(Mode mode = M_normal);
72  ClockObject(const ClockObject &copy);
73  INLINE ~ClockObject();
74 
75  void set_mode(Mode mode);
76  INLINE Mode get_mode() const;
77  MAKE_PROPERTY(mode, get_mode, set_mode);
78 
79  INLINE double get_frame_time(Thread *current_thread = Thread::get_current_thread()) const;
80  INLINE double get_real_time() const;
81  INLINE double get_long_time() const;
82 
83  INLINE void reset();
84  void set_real_time(double time);
85  void set_frame_time(double time, Thread *current_thread = Thread::get_current_thread());
86  void set_frame_count(int frame_count, Thread *current_thread = Thread::get_current_thread());
87 
88  INLINE int get_frame_count(Thread *current_thread = Thread::get_current_thread()) const;
89  INLINE double get_net_frame_rate(Thread *current_thread = Thread::get_current_thread()) const;
90 
91  MAKE_PROPERTY(frame_time, get_frame_time, set_frame_time);
92  MAKE_PROPERTY(real_time, get_real_time, set_real_time);
93  MAKE_PROPERTY(long_time, get_long_time);
94  MAKE_PROPERTY(frame_count, get_frame_count, set_frame_count);
95 
96  INLINE double get_dt(Thread *current_thread = Thread::get_current_thread()) const;
97  void set_dt(double dt);
98  void set_frame_rate(double frame_rate);
99  MAKE_PROPERTY(dt, get_dt, set_dt);
100 
101  INLINE double get_max_dt() const;
102  INLINE void set_max_dt(double max_dt);
103  MAKE_PROPERTY(max_dt, get_max_dt, set_max_dt);
104 
105  INLINE double get_degrade_factor() const;
106  INLINE void set_degrade_factor(double degrade_factor);
107  MAKE_PROPERTY(degrade_factor, get_degrade_factor, set_degrade_factor);
108 
109  INLINE void set_average_frame_rate_interval(double time);
110  INLINE double get_average_frame_rate_interval() const;
111  MAKE_PROPERTY(average_frame_rate_interval,
112  get_average_frame_rate_interval,
113  set_average_frame_rate_interval);
114 
115  double get_average_frame_rate(Thread *current_thread = Thread::get_current_thread()) const;
116  double get_max_frame_duration(Thread *current_thread = Thread::get_current_thread()) const;
117  double calc_frame_rate_deviation(Thread *current_thread = Thread::get_current_thread()) const;
118  MAKE_PROPERTY(average_frame_rate, get_average_frame_rate);
119  MAKE_PROPERTY(max_frame_duration, get_max_frame_duration);
120 
121  void tick(Thread *current_thread = Thread::get_current_thread());
122  void sync_frame_time(Thread *current_thread = Thread::get_current_thread());
123 
124  INLINE bool check_errors(Thread *current_thread);
125 
126  INLINE static ClockObject *get_global_clock();
127 
128 public:
129  static void (*_start_clock_wait)();
130  static void (*_start_clock_busy_wait)();
131  static void (*_stop_clock_wait)();
132 
133 private:
134  void wait_until(double want_time);
135  static void make_global_clock();
136  static void dummy_clock_wait();
137 
138  TrueClock *_true_clock;
139  Mode _mode;
140  double _start_short_time;
141  double _start_long_time;
142  double _actual_frame_time;
143  double _max_dt;
144  double _user_frame_rate;
145  double _degrade_factor;
146  int _error_count;
147 
148  // For tracking the average frame rate over a certain interval of time.
149  double _average_frame_rate_interval;
150  typedef pdeque<double> Ticks;
151  Ticks _ticks;
152 
153  // This is the data that needs to be cycled each frame.
154  class EXPCL_PANDA_PUTIL CData : public CycleData {
155  public:
156  CData();
157  INLINE CData(const CData &copy);
158 
159  virtual CycleData *make_copy() const;
160  virtual TypeHandle get_parent_type() const {
161  return ClockObject::get_class_type();
162  }
163 
164  int _frame_count;
165  double _reported_frame_time;
166  double _reported_frame_time_epoch;
167  double _dt;
168  };
169 
170  PipelineCycler<CData> _cycler;
171  typedef CycleDataReader<CData> CDReader;
172  typedef CycleDataWriter<CData> CDWriter;
173  typedef CycleDataStageReader<CData> CDStageReader;
174 
175  static AtomicAdjust::Pointer _global_clock;
176 
177 public:
178  static TypeHandle get_class_type() {
179  return _type_handle;
180  }
181  static void init_type() {
182  ReferenceCount::init_type();
183  register_type(_type_handle, "ClockObject",
184  ReferenceCount::get_class_type());
185  }
186 
187 private:
188  static TypeHandle _type_handle;
189 };
190 
191 EXPCL_PANDA_PUTIL std::ostream &
192 operator << (std::ostream &out, ClockObject::Mode mode);
193 EXPCL_PANDA_PUTIL std::istream &
194 operator >> (std::istream &in, ClockObject::Mode &mode);
195 
196 #include "clockObject.I"
197 
198 #endif
A ClockObject keeps track of elapsed real time and discrete time.
Definition: clockObject.h:58
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:50
A base class for all things that want to be reference-counted.
A thread; that is, a lightweight process.
Definition: thread.h:46
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition: thread.h:109
An interface to whatever real-time clock we might have available in the current environment.
Definition: trueClock.h:33
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.