Panda3D
 All Classes Functions Variables Enumerations
pStatGraph.cxx
00001 // Filename: pStatGraph.cxx
00002 // Created by:  drose (19Jul00)
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 #include "pStatGraph.h"
00016 #include "pStatServer.h"
00017 #include "pStatFrameData.h"
00018 #include "pStatCollectorDef.h"
00019 #include "string_utils.h"
00020 #include "config_pstats.h"
00021 
00022 #include <stdio.h>  // for sprintf
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: PStatGraph::GuideBar::Constructor
00026 //       Access: Public
00027 //  Description:
00028 ////////////////////////////////////////////////////////////////////
00029 PStatGraph::GuideBar::
00030 GuideBar(double height, const string &label, PStatGraph::GuideBarStyle style) :
00031   _height(height),
00032   _label(label),
00033   _style(style)
00034 {
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: PStatGraph::GuideBar::Copy Constructor
00039 //       Access: Public
00040 //  Description:
00041 ////////////////////////////////////////////////////////////////////
00042 PStatGraph::GuideBar::
00043 GuideBar(const PStatGraph::GuideBar &copy) :
00044   _height(copy._height),
00045   _label(copy._label),
00046   _style(copy._style)
00047 {
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: PStatGraph::Constructor
00052 //       Access: Public
00053 //  Description:
00054 ////////////////////////////////////////////////////////////////////
00055 PStatGraph::
00056 PStatGraph(PStatMonitor *monitor, int xsize, int ysize) :
00057   _monitor(monitor),
00058   _xsize(xsize),
00059   _ysize(ysize)
00060 {
00061   _target_frame_rate = pstats_target_frame_rate;
00062   _labels_changed = false;
00063   _guide_bars_changed = false;
00064   _guide_bar_units = GBU_ms;
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: PStatGraph::Destructor
00069 //       Access: Public, Virtual
00070 //  Description:
00071 ////////////////////////////////////////////////////////////////////
00072 PStatGraph::
00073 ~PStatGraph() {
00074 }
00075 
00076 ////////////////////////////////////////////////////////////////////
00077 //     Function: PStatGraph::get_num_guide_bars
00078 //       Access: Public
00079 //  Description: Returns the number of horizontal guide bars that
00080 //               should be drawn, based on the indicated target frame
00081 //               rate.  Not all of these may be visible; some may be
00082 //               off the top of the chart because of the vertical
00083 //               scale.
00084 ////////////////////////////////////////////////////////////////////
00085 int PStatGraph::
00086 get_num_guide_bars() const {
00087   return _guide_bars.size();
00088 }
00089 
00090 ////////////////////////////////////////////////////////////////////
00091 //     Function: PStatGraph::get_guide_bar
00092 //       Access: Public
00093 //  Description: Returns the nth horizontal guide bar.  This should be
00094 //               drawn as a horizontal line across the chart at the y
00095 //               pixel location determined by height_to_pixel(bar._height).
00096 //
00097 //               It is possible that this bar will be off the top of
00098 //               the chart.
00099 ////////////////////////////////////////////////////////////////////
00100 const PStatGraph::GuideBar &PStatGraph::
00101 get_guide_bar(int n) const {
00102 #ifndef NDEBUG
00103   static GuideBar bogus_bar(0.0, "bogus", GBS_normal);
00104   nassertr(n >= 0 && n < (int)_guide_bars.size(), bogus_bar);
00105 #endif
00106   return _guide_bars[n];
00107 }
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: PStatGraph::get_num_user_guide_bars
00111 //       Access: Public
00112 //  Description: Returns the current number of user-defined guide
00113 //               bars.  Not all of these may be visible.
00114 ////////////////////////////////////////////////////////////////////
00115 int PStatGraph::
00116 get_num_user_guide_bars() const {
00117   return _monitor->get_server()->get_num_user_guide_bars();
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: PStatGraph::get_user_guide_bar
00122 //       Access: Public
00123 //  Description: Returns the nth user-defined guide bar.
00124 ////////////////////////////////////////////////////////////////////
00125 PStatGraph::GuideBar PStatGraph::
00126 get_user_guide_bar(int n) const {
00127   double height = _monitor->get_server()->get_user_guide_bar_height(n);
00128   return make_guide_bar(height, GBS_user);
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: PStatGraph::move_user_guide_bar
00133 //       Access: Public
00134 //  Description: Adjusts the height of the nth user-defined guide bar.
00135 ////////////////////////////////////////////////////////////////////
00136 void PStatGraph::
00137 move_user_guide_bar(int n, double height) {
00138   _monitor->get_server()->move_user_guide_bar(n, height);
00139 }
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: PStatGraph::add_user_guide_bar
00143 //       Access: Public
00144 //  Description: Creates a new user guide bar and returns its index
00145 //               number.
00146 ////////////////////////////////////////////////////////////////////
00147 int PStatGraph::
00148 add_user_guide_bar(double height) {
00149   return _monitor->get_server()->add_user_guide_bar(height);
00150 }
00151 
00152 ////////////////////////////////////////////////////////////////////
00153 //     Function: PStatGraph::remove_user_guide_bar
00154 //       Access: Public
00155 //  Description: Removes the user guide bar with the indicated index
00156 //               number.  All subsequent index numbers are adjusted
00157 //               down one.
00158 ////////////////////////////////////////////////////////////////////
00159 void PStatGraph::
00160 remove_user_guide_bar(int n) {
00161   _monitor->get_server()->remove_user_guide_bar(n);
00162 }
00163 
00164 ////////////////////////////////////////////////////////////////////
00165 //     Function: PStatGraph::find_user_guide_bar
00166 //       Access: Public
00167 //  Description: Returns the index number of the first user guide bar
00168 //               found whose height is within the indicated range, or
00169 //               -1 if no user guide bars fall within the range.
00170 ////////////////////////////////////////////////////////////////////
00171 int PStatGraph::
00172 find_user_guide_bar(double from_height, double to_height) const {
00173   return _monitor->get_server()->find_user_guide_bar(from_height, to_height);
00174 }
00175 
00176 
00177 ////////////////////////////////////////////////////////////////////
00178 //     Function: PStatGraph::format_number
00179 //       Access: Public, Static
00180 //  Description: Returns a string representing the value nicely
00181 //               formatted for its range.
00182 ////////////////////////////////////////////////////////////////////
00183 string PStatGraph::
00184 format_number(double value) {
00185   char buffer[128];
00186 
00187   if (value < 0.01) {
00188     sprintf(buffer, "%0.4f", value);
00189   } else if (value < 0.1) {
00190     sprintf(buffer, "%0.3f", value);
00191   } else if (value < 1.0) {
00192     sprintf(buffer, "%0.2f", value);
00193   } else if (value < 10.0) {
00194     sprintf(buffer, "%0.1f", value);
00195   } else {
00196     sprintf(buffer, "%0.0f", value);
00197   }
00198 
00199   return buffer;
00200 }
00201 
00202 ////////////////////////////////////////////////////////////////////
00203 //     Function: PStatGraph::format_number
00204 //       Access: Public, Static
00205 //  Description: Returns a string representing the value nicely
00206 //               formatted for its range, including the units
00207 //               as indicated.
00208 ////////////////////////////////////////////////////////////////////
00209 string PStatGraph::
00210 format_number(double value, int guide_bar_units, const string &unit_name) {
00211   string label;
00212 
00213   if ((guide_bar_units & GBU_named) != 0) {
00214     // Units are whatever is specified by unit_name, not a time unit
00215     // at all.
00216     label = format_number(value);
00217     if ((guide_bar_units & GBU_show_units) != 0 && !unit_name.empty()) {
00218       label += " ";
00219       label += unit_name;
00220     }
00221 
00222   } else {
00223     // Units are either milliseconds or hz, or both.
00224     if ((guide_bar_units & GBU_ms) != 0) {
00225       double ms = value * 1000.0;
00226       label += format_number(ms);
00227       if ((guide_bar_units & GBU_show_units) != 0) {
00228         label += " ms";
00229       }
00230     }
00231 
00232     if ((guide_bar_units & GBU_hz) != 0) {
00233       double hz = 1.0 / value;
00234 
00235       if ((guide_bar_units & GBU_ms) != 0) {
00236         label += " (";
00237       }
00238       label += format_number(hz);
00239       if ((guide_bar_units & GBU_show_units) != 0) {
00240         label += " Hz";
00241       }
00242       if ((guide_bar_units & GBU_ms) != 0) {
00243         label += ")";
00244       }
00245     }
00246   }
00247 
00248   return label;
00249 }
00250 
00251 ////////////////////////////////////////////////////////////////////
00252 //     Function: PStatGraph::update_guide_bars
00253 //       Access: Protected
00254 //  Description: Resets the list of guide bars.
00255 ////////////////////////////////////////////////////////////////////
00256 void PStatGraph::
00257 update_guide_bars(int num_bars, double scale) {
00258   _guide_bars.clear();
00259 
00260   // We'd like to draw about num_bars bars on the chart.  But we also
00261   // want the bars to be harmonics of the target frame rate, so that
00262   // the bottom bar is at tfr/n or n * tfr, where n is an integer, and
00263   // the upper bars are even multiples of that.
00264 
00265   // Choose a suitable harmonic of the target frame rate near the
00266   // bottom part of the chart.
00267 
00268   double bottom = (double)num_bars / scale;
00269 
00270   double harmonic;
00271   if (_target_frame_rate < bottom) {
00272     // n * tfr
00273     harmonic = floor(bottom / _target_frame_rate + 0.5) * _target_frame_rate;
00274 
00275   } else {
00276     // tfr / n
00277     harmonic = _target_frame_rate / floor(_target_frame_rate / bottom + 0.5);
00278   }
00279 
00280   // Now, make a few bars at k / harmonic.
00281   for (int k = 1; k / harmonic <= scale; k++) {
00282     _guide_bars.push_back(make_guide_bar(k / harmonic));
00283   }
00284 
00285   _guide_bars_changed = true;
00286 }
00287 
00288 ////////////////////////////////////////////////////////////////////
00289 //     Function: PStatGraph::make_guide_bar
00290 //       Access: Protected
00291 //  Description: Makes a guide bar for the indicated elapsed time or
00292 //               level units.
00293 ////////////////////////////////////////////////////////////////////
00294 PStatGraph::GuideBar PStatGraph::
00295 make_guide_bar(double value, PStatGraph::GuideBarStyle style) const {
00296   string label = format_number(value, _guide_bar_units, _unit_name);
00297 
00298   if ((style == GBS_normal) &&
00299       (_guide_bar_units & GBU_named) == 0) {
00300     // If it's a time unit, check to see if it matches our target
00301     // frame rate.
00302     double hz = 1.0 / value;
00303     if (IS_THRESHOLD_EQUAL(hz, _target_frame_rate, 0.001)) {
00304       style = GBS_target;
00305     }
00306   }
00307 
00308   return GuideBar(value, label, style);
00309 }
 All Classes Functions Variables Enumerations