Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/pstatserver/pStatGraph.cxx

Go to the documentation of this file.
00001 // Filename: pStatGraph.cxx
00002 // Created by:  drose (19Jul00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "pStatGraph.h"
00020 
00021 #include <pStatFrameData.h>
00022 #include <pStatCollectorDef.h>
00023 #include <string_utils.h>
00024 #include <config_pstats.h>
00025 
00026 #include <stdio.h>  // for sprintf
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: PStatGraph::GuideBar::Constructor
00030 //       Access: Public
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 PStatGraph::GuideBar::
00034 GuideBar(float height, const string &label, bool is_target) :
00035   _height(height),
00036   _label(label),
00037   _is_target(is_target)
00038 {
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: PStatGraph::GuideBar::Copy Constructor
00043 //       Access: Public
00044 //  Description:
00045 ////////////////////////////////////////////////////////////////////
00046 PStatGraph::GuideBar::
00047 GuideBar(const PStatGraph::GuideBar &copy) :
00048   _height(copy._height),
00049   _label(copy._label),
00050   _is_target(copy._is_target)
00051 {
00052 }
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 //     Function: PStatGraph::Constructor
00056 //       Access: Public
00057 //  Description:
00058 ////////////////////////////////////////////////////////////////////
00059 PStatGraph::
00060 PStatGraph(PStatMonitor *monitor, int xsize, int ysize) :
00061   _monitor(monitor),
00062   _xsize(xsize),
00063   _ysize(ysize)
00064 {
00065   _target_frame_rate = pstats_target_frame_rate;
00066   _labels_changed = false;
00067   _guide_bars_changed = false;
00068   _guide_bar_units = GBU_ms;
00069 }
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: PStatGraph::Destructor
00073 //       Access: Public, Virtual
00074 //  Description:
00075 ////////////////////////////////////////////////////////////////////
00076 PStatGraph::
00077 ~PStatGraph() {
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: PStatGraph::get_num_guide_bars
00082 //       Access: Public
00083 //  Description: Returns the number of horizontal guide bars that
00084 //               should be drawn, based on the indicated target frame
00085 //               rate.  Not all of these may be visible; some may be
00086 //               off the top of the chart because of the vertical
00087 //               scale.
00088 ////////////////////////////////////////////////////////////////////
00089 int PStatGraph::
00090 get_num_guide_bars() const {
00091   return _guide_bars.size();
00092 }
00093 
00094 ////////////////////////////////////////////////////////////////////
00095 //     Function: PStatGraph::get_guide_bar
00096 //       Access: Public
00097 //  Description: Returns the nth horizontal guide bar.  This should be
00098 //               drawn as a horizontal line across the chart at the y
00099 //               pixel location determined by height_to_pixel(bar._height).
00100 //
00101 //               It is possible that this bar will be off the top of
00102 //               the chart.
00103 ////////////////////////////////////////////////////////////////////
00104 const PStatGraph::GuideBar &PStatGraph::
00105 get_guide_bar(int n) const {
00106 #ifndef NDEBUG
00107   static GuideBar bogus_bar(0.0, "bogus", false);
00108   nassertr(n >= 0 && n < (int)_guide_bars.size(), bogus_bar);
00109 #endif
00110   return _guide_bars[n];
00111 }
00112 
00113 
00114 ////////////////////////////////////////////////////////////////////
00115 //     Function: PStatGraph::format_number
00116 //       Access: Public, Static
00117 //  Description: Returns a string representing the value nicely
00118 //               formatted for its range.
00119 ////////////////////////////////////////////////////////////////////
00120 string PStatGraph::
00121 format_number(float value) {
00122   char buffer[128];
00123 
00124   if (value < 0.01) {
00125     sprintf(buffer, "%0.4f", value);
00126   } else if (value < 0.1) {
00127     sprintf(buffer, "%0.3f", value);
00128   } else if (value < 1.0) {
00129     sprintf(buffer, "%0.2f", value);
00130   } else if (value < 10.0) {
00131     sprintf(buffer, "%0.1f", value);
00132   } else {
00133     sprintf(buffer, "%0.0f", value);
00134   }
00135 
00136   return buffer;
00137 }
00138 
00139 ////////////////////////////////////////////////////////////////////
00140 //     Function: PStatGraph::format_number
00141 //       Access: Public, Static
00142 //  Description: Returns a string representing the value nicely
00143 //               formatted for its range, including the units
00144 //               as indicated.
00145 ////////////////////////////////////////////////////////////////////
00146 string PStatGraph::
00147 format_number(float value, int guide_bar_units, const string &unit_name) {
00148   string label;
00149 
00150   if ((guide_bar_units & GBU_named) != 0) {
00151     // Units are whatever is specified by unit_name, not a time unit
00152     // at all.
00153     label = format_number(value);
00154     if ((guide_bar_units & GBU_show_units) != 0 && !unit_name.empty()) {
00155       label += " ";
00156       label += unit_name;
00157     }
00158 
00159   } else {
00160     // Units are either milliseconds or hz, or both.
00161     if ((guide_bar_units & GBU_ms) != 0) {
00162       float ms = value * 1000.0;
00163       label += format_number(ms);
00164       if ((guide_bar_units & GBU_show_units) != 0) {
00165         label += " ms";
00166       }
00167     }
00168 
00169     if ((guide_bar_units & GBU_hz) != 0) {
00170       float hz = 1.0 / value;
00171 
00172       if ((guide_bar_units & GBU_ms) != 0) {
00173         label += " (";
00174       }
00175       label += format_number(hz);
00176       if ((guide_bar_units & GBU_show_units) != 0) {
00177         label += " Hz";
00178       }
00179       if ((guide_bar_units & GBU_ms) != 0) {
00180         label += ")";
00181       }
00182     }
00183   }
00184 
00185   return label;
00186 }
00187 
00188 // STL function object for sorting labels in order by the collector's
00189 // sort index, used in update_labels(), below.
00190 class SortCollectorLabels {
00191 public:
00192   SortCollectorLabels(const PStatClientData *client_data) :
00193     _client_data(client_data) {
00194   }
00195   bool operator () (int a, int b) const {
00196     return
00197       _client_data->get_collector_def(a)._sort >
00198       _client_data->get_collector_def(b)._sort;
00199   }
00200   const PStatClientData *_client_data;
00201 };
00202 
00203 ////////////////////////////////////////////////////////////////////
00204 //     Function: PStatGraph::update_guide_bars
00205 //       Access: Protected
00206 //  Description: Resets the list of guide bars.
00207 ////////////////////////////////////////////////////////////////////
00208 void PStatGraph::
00209 update_guide_bars(int num_bars, float scale) {
00210   _guide_bars.clear();
00211 
00212   // We'd like to draw about num_bars bars on the chart.  But we also
00213   // want the bars to be harmonics of the target frame rate, so that
00214   // the bottom bar is at tfr/n or n * tfr, where n is an integer, and
00215   // the upper bars are even multiples of that.
00216 
00217   // Choose a suitable harmonic of the target frame rate near the
00218   // bottom part of the chart.
00219 
00220   float bottom = (float)num_bars / scale;
00221 
00222   float harmonic;
00223   if (_target_frame_rate < bottom) {
00224     // n * tfr
00225     harmonic = floor(bottom / _target_frame_rate + 0.5) * _target_frame_rate;
00226 
00227   } else {
00228     // tfr / n
00229     harmonic = _target_frame_rate / floor(_target_frame_rate / bottom + 0.5);
00230   }
00231 
00232   // Now, make a few bars at k / harmonic.
00233   for (int k = 1; k / harmonic <= scale; k++) {
00234     _guide_bars.push_back(make_guide_bar(k / harmonic));
00235   }
00236 
00237   _guide_bars_changed = true;
00238 }
00239 
00240 ////////////////////////////////////////////////////////////////////
00241 //     Function: PStatGraph::make_guide_bar
00242 //       Access: Protected
00243 //  Description: Makes a guide bar for the indicated elapsed time or
00244 //               level units.
00245 ////////////////////////////////////////////////////////////////////
00246 PStatGraph::GuideBar PStatGraph::
00247 make_guide_bar(float value) const {
00248   string label = format_number(value, _guide_bar_units, _unit_name);
00249 
00250   bool is_target = false;
00251 
00252   if ((_guide_bar_units & GBU_named) == 0) {
00253     // If it's a time unit, check to see if it matches our target
00254     // frame rate.
00255     float hz = 1.0 / value;
00256     is_target = IS_NEARLY_EQUAL(hz, _target_frame_rate);
00257   }
00258 
00259   return GuideBar(value, label, is_target);
00260 }

Generated on Fri May 2 03:21:34 2003 for Panda-Tool by doxygen1.3