Panda3D
|
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 ©) : 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 }