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