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