Panda3D

clockObject.h

00001 // Filename: clockObject.h
00002 // Created by:  drose (19Feb99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef CLOCKOBJECT_H
00016 #define CLOCKOBJECT_H
00017 
00018 #include "pandabase.h"
00019 
00020 #include "trueClock.h"
00021 #include "pdeque.h"
00022 #include "cycleData.h"
00023 #include "cycleDataReader.h"
00024 #include "cycleDataWriter.h"
00025 #include "cycleDataStageReader.h"
00026 #include "pipelineCycler.h"
00027 #include "thread.h"
00028 #include "referenceCount.h"
00029 #include "pointerTo.h"
00030 
00031 class EXPCL_PANDA_PUTIL TimeVal {
00032 PUBLISHED:
00033   INLINE TimeVal();
00034   INLINE ulong get_sec() const;
00035   INLINE ulong get_usec() const;
00036   ulong tv[2];
00037 };
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //       Class : ClockObject
00041 // Description : A ClockObject keeps track of elapsed real time and
00042 //               discrete time.  In normal mode, get_frame_time()
00043 //               returns the time as of the last time tick() was
00044 //               called.  This is the "discrete" time, and is usually
00045 //               used to get the time as of, for instance, the
00046 //               beginning of the current frame.
00047 //
00048 //               In other modes, as set by set_mode() or the
00049 //               clock-mode config variable, get_frame_time() may
00050 //               return other values to simulate different timing
00051 //               effects, for instance to perform non-real-time
00052 //               animation.  See set_mode().
00053 //
00054 //               In all modes, get_real_time() always returns the
00055 //               elapsed real time in seconds since the ClockObject
00056 //               was constructed, or since it was last reset.
00057 //
00058 //               You can create your own ClockObject whenever you want
00059 //               to have your own local timer.  There is also a
00060 //               default, global ClockObject intended to represent
00061 //               global time for the application; this is normally set
00062 //               up to tick every frame so that its get_frame_time()
00063 //               will return the time for the current frame.
00064 ////////////////////////////////////////////////////////////////////
00065 class EXPCL_PANDA_PUTIL ClockObject : public ReferenceCount {
00066 PUBLISHED:
00067   enum Mode {
00068     M_normal,
00069     M_non_real_time,
00070     M_forced,
00071     M_degrade,
00072     M_slave,
00073     M_limited,
00074     M_integer,
00075     M_integer_limited,
00076   };
00077 
00078   ClockObject();
00079   INLINE ~ClockObject();
00080 
00081   void set_mode(Mode mode);
00082   INLINE Mode get_mode() const;
00083 
00084   INLINE double get_frame_time(Thread *current_thread = Thread::get_current_thread()) const;
00085   INLINE double get_real_time() const;
00086   INLINE double get_long_time() const;
00087 
00088   INLINE void reset();
00089   void set_real_time(double time);
00090   void set_frame_time(double time, Thread *current_thread = Thread::get_current_thread());
00091   void set_frame_count(int frame_count, Thread *current_thread = Thread::get_current_thread());
00092 
00093   INLINE int get_frame_count(Thread *current_thread = Thread::get_current_thread()) const;
00094   INLINE double get_net_frame_rate(Thread *current_thread = Thread::get_current_thread()) const;
00095 
00096   INLINE double get_dt(Thread *current_thread = Thread::get_current_thread()) const;
00097   void set_dt(double dt);
00098   void set_frame_rate(double frame_rate);
00099 
00100   INLINE double get_max_dt() const;
00101   INLINE void set_max_dt(double max_dt);
00102 
00103   INLINE double get_degrade_factor() const;
00104   INLINE void set_degrade_factor(double degrade_factor);
00105 
00106   INLINE void set_average_frame_rate_interval(double time);
00107   INLINE double get_average_frame_rate_interval() const;
00108   double get_average_frame_rate(Thread *current_thread = Thread::get_current_thread()) const;
00109   double get_max_frame_duration(Thread *current_thread = Thread::get_current_thread()) const;
00110   double calc_frame_rate_deviation(Thread *current_thread = Thread::get_current_thread()) const;
00111 
00112   void tick(Thread *current_thread = Thread::get_current_thread());
00113   void sync_frame_time(Thread *current_thread = Thread::get_current_thread());
00114 
00115   INLINE bool check_errors(Thread *current_thread);
00116 
00117   INLINE static ClockObject *get_global_clock();
00118 
00119 public:
00120   static void (*_start_clock_wait)();
00121   static void (*_start_clock_busy_wait)();
00122   static void (*_stop_clock_wait)();
00123 
00124 private:
00125   void wait_until(double want_time);
00126   static void make_global_clock();
00127   static void dummy_clock_wait();
00128 
00129   TrueClock *_true_clock;
00130   Mode _mode;
00131   double _start_short_time;
00132   double _start_long_time;
00133   double _actual_frame_time;
00134   double _max_dt;
00135   double _user_frame_rate;
00136   double _degrade_factor;
00137   int _error_count;
00138 
00139   // For tracking the average frame rate over a certain interval of
00140   // time.
00141   double _average_frame_rate_interval;
00142   typedef pdeque<double> Ticks;
00143   Ticks _ticks;
00144 
00145   // This is the data that needs to be cycled each frame.
00146   class EXPCL_PANDA_PUTIL CData : public CycleData {
00147   public:
00148     CData();
00149     INLINE CData(const CData &copy);
00150 
00151     virtual CycleData *make_copy() const;
00152     virtual TypeHandle get_parent_type() const {
00153       return ClockObject::get_class_type();
00154     }
00155 
00156     int _frame_count;
00157     double _reported_frame_time;
00158     double _reported_frame_time_epoch;
00159     double _dt;
00160   };
00161 
00162   PipelineCycler<CData> _cycler;
00163   typedef CycleDataReader<CData> CDReader;
00164   typedef CycleDataWriter<CData> CDWriter;
00165   typedef CycleDataStageReader<CData> CDStageReader;
00166 
00167   static PT(ClockObject) _global_clock;
00168 
00169 public:
00170   static TypeHandle get_class_type() {
00171     return _type_handle;
00172   }
00173   static void init_type() {
00174     register_type(_type_handle, "ClockObject");
00175   }
00176 
00177 private:
00178   static TypeHandle _type_handle;
00179 };
00180 
00181 EXPCL_PANDA_PUTIL ostream &
00182 operator << (ostream &out, ClockObject::Mode mode);
00183 EXPCL_PANDA_PUTIL istream &
00184 operator >> (istream &in, ClockObject::Mode &mode);
00185 
00186 #include "clockObject.I"
00187 
00188 #endif
00189 
 All Classes Functions Variables Enumerations