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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:47
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.
virtual TypeHandle get_parent_type() const
Returns the type of the container that owns the CycleData.
Definition: cycleData.cxx:76
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A ClockObject keeps track of elapsed real time and discrete time.
Definition: clockObject.h:58
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
An interface to whatever real-time clock we might have available in the current environment.
Definition: trueClock.h:33
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A base class for all things that want to be reference-counted.
A thread; that is, a lightweight process.
Definition: thread.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.