Panda3D
pStatGraph.cxx
1 // Filename: pStatGraph.cxx
2 // Created by: drose (19Jul00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "pStatGraph.h"
16 #include "pStatServer.h"
17 #include "pStatFrameData.h"
18 #include "pStatCollectorDef.h"
19 #include "string_utils.h"
20 #include "config_pstats.h"
21 
22 #include <stdio.h> // for sprintf
23 
24 ////////////////////////////////////////////////////////////////////
25 // Function: PStatGraph::GuideBar::Constructor
26 // Access: Public
27 // Description:
28 ////////////////////////////////////////////////////////////////////
29 PStatGraph::GuideBar::
30 GuideBar(double height, const string &label, PStatGraph::GuideBarStyle style) :
31  _height(height),
32  _label(label),
33  _style(style)
34 {
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: PStatGraph::GuideBar::Copy Constructor
39 // Access: Public
40 // Description:
41 ////////////////////////////////////////////////////////////////////
42 PStatGraph::GuideBar::
43 GuideBar(const PStatGraph::GuideBar &copy) :
44  _height(copy._height),
45  _label(copy._label),
46  _style(copy._style)
47 {
48 }
49 
50 ////////////////////////////////////////////////////////////////////
51 // Function: PStatGraph::Constructor
52 // Access: Public
53 // Description:
54 ////////////////////////////////////////////////////////////////////
55 PStatGraph::
56 PStatGraph(PStatMonitor *monitor, int xsize, int ysize) :
57  _monitor(monitor),
58  _xsize(xsize),
59  _ysize(ysize)
60 {
61  _target_frame_rate = pstats_target_frame_rate;
62  _labels_changed = false;
63  _guide_bars_changed = false;
64  _guide_bar_units = GBU_ms;
65 }
66 
67 ////////////////////////////////////////////////////////////////////
68 // Function: PStatGraph::Destructor
69 // Access: Public, Virtual
70 // Description:
71 ////////////////////////////////////////////////////////////////////
72 PStatGraph::
73 ~PStatGraph() {
74 }
75 
76 ////////////////////////////////////////////////////////////////////
77 // Function: PStatGraph::get_num_guide_bars
78 // Access: Public
79 // Description: Returns the number of horizontal guide bars that
80 // should be drawn, based on the indicated target frame
81 // rate. Not all of these may be visible; some may be
82 // off the top of the chart because of the vertical
83 // scale.
84 ////////////////////////////////////////////////////////////////////
85 int PStatGraph::
87  return _guide_bars.size();
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: PStatGraph::get_guide_bar
92 // Access: Public
93 // Description: Returns the nth horizontal guide bar. This should be
94 // drawn as a horizontal line across the chart at the y
95 // pixel location determined by height_to_pixel(bar._height).
96 //
97 // It is possible that this bar will be off the top of
98 // the chart.
99 ////////////////////////////////////////////////////////////////////
101 get_guide_bar(int n) const {
102 #ifndef NDEBUG
103  static GuideBar bogus_bar(0.0, "bogus", GBS_normal);
104  nassertr(n >= 0 && n < (int)_guide_bars.size(), bogus_bar);
105 #endif
106  return _guide_bars[n];
107 }
108 
109 ////////////////////////////////////////////////////////////////////
110 // Function: PStatGraph::get_num_user_guide_bars
111 // Access: Public
112 // Description: Returns the current number of user-defined guide
113 // bars. Not all of these may be visible.
114 ////////////////////////////////////////////////////////////////////
115 int PStatGraph::
117  return _monitor->get_server()->get_num_user_guide_bars();
118 }
119 
120 ////////////////////////////////////////////////////////////////////
121 // Function: PStatGraph::get_user_guide_bar
122 // Access: Public
123 // Description: Returns the nth user-defined guide bar.
124 ////////////////////////////////////////////////////////////////////
126 get_user_guide_bar(int n) const {
127  double height = _monitor->get_server()->get_user_guide_bar_height(n);
128  return make_guide_bar(height, GBS_user);
129 }
130 
131 ////////////////////////////////////////////////////////////////////
132 // Function: PStatGraph::move_user_guide_bar
133 // Access: Public
134 // Description: Adjusts the height of the nth user-defined guide bar.
135 ////////////////////////////////////////////////////////////////////
136 void PStatGraph::
137 move_user_guide_bar(int n, double height) {
138  _monitor->get_server()->move_user_guide_bar(n, height);
139 }
140 
141 ////////////////////////////////////////////////////////////////////
142 // Function: PStatGraph::add_user_guide_bar
143 // Access: Public
144 // Description: Creates a new user guide bar and returns its index
145 // number.
146 ////////////////////////////////////////////////////////////////////
147 int PStatGraph::
148 add_user_guide_bar(double height) {
149  return _monitor->get_server()->add_user_guide_bar(height);
150 }
151 
152 ////////////////////////////////////////////////////////////////////
153 // Function: PStatGraph::remove_user_guide_bar
154 // Access: Public
155 // Description: Removes the user guide bar with the indicated index
156 // number. All subsequent index numbers are adjusted
157 // down one.
158 ////////////////////////////////////////////////////////////////////
159 void PStatGraph::
161  _monitor->get_server()->remove_user_guide_bar(n);
162 }
163 
164 ////////////////////////////////////////////////////////////////////
165 // Function: PStatGraph::find_user_guide_bar
166 // Access: Public
167 // Description: Returns the index number of the first user guide bar
168 // found whose height is within the indicated range, or
169 // -1 if no user guide bars fall within the range.
170 ////////////////////////////////////////////////////////////////////
171 int PStatGraph::
172 find_user_guide_bar(double from_height, double to_height) const {
173  return _monitor->get_server()->find_user_guide_bar(from_height, to_height);
174 }
175 
176 
177 ////////////////////////////////////////////////////////////////////
178 // Function: PStatGraph::format_number
179 // Access: Public, Static
180 // Description: Returns a string representing the value nicely
181 // formatted for its range.
182 ////////////////////////////////////////////////////////////////////
183 string PStatGraph::
184 format_number(double value) {
185  char buffer[128];
186 
187  if (value < 0.01) {
188  sprintf(buffer, "%0.4f", value);
189  } else if (value < 0.1) {
190  sprintf(buffer, "%0.3f", value);
191  } else if (value < 1.0) {
192  sprintf(buffer, "%0.2f", value);
193  } else if (value < 10.0) {
194  sprintf(buffer, "%0.1f", value);
195  } else {
196  sprintf(buffer, "%0.0f", value);
197  }
198 
199  return buffer;
200 }
201 
202 ////////////////////////////////////////////////////////////////////
203 // Function: PStatGraph::format_number
204 // Access: Public, Static
205 // Description: Returns a string representing the value nicely
206 // formatted for its range, including the units
207 // as indicated.
208 ////////////////////////////////////////////////////////////////////
209 string PStatGraph::
210 format_number(double value, int guide_bar_units, const string &unit_name) {
211  string label;
212 
213  if ((guide_bar_units & GBU_named) != 0) {
214  // Units are whatever is specified by unit_name, not a time unit
215  // at all.
216  label = format_number(value);
217  if ((guide_bar_units & GBU_show_units) != 0 && !unit_name.empty()) {
218  label += " ";
219  label += unit_name;
220  }
221 
222  } else {
223  // Units are either milliseconds or hz, or both.
224  if ((guide_bar_units & GBU_ms) != 0) {
225  double ms = value * 1000.0;
226  label += format_number(ms);
227  if ((guide_bar_units & GBU_show_units) != 0) {
228  label += " ms";
229  }
230  }
231 
232  if ((guide_bar_units & GBU_hz) != 0) {
233  double hz = 1.0 / value;
234 
235  if ((guide_bar_units & GBU_ms) != 0) {
236  label += " (";
237  }
238  label += format_number(hz);
239  if ((guide_bar_units & GBU_show_units) != 0) {
240  label += " Hz";
241  }
242  if ((guide_bar_units & GBU_ms) != 0) {
243  label += ")";
244  }
245  }
246  }
247 
248  return label;
249 }
250 
251 ////////////////////////////////////////////////////////////////////
252 // Function: PStatGraph::update_guide_bars
253 // Access: Protected
254 // Description: Resets the list of guide bars.
255 ////////////////////////////////////////////////////////////////////
256 void PStatGraph::
257 update_guide_bars(int num_bars, double scale) {
258  _guide_bars.clear();
259 
260  // We'd like to draw about num_bars bars on the chart. But we also
261  // want the bars to be harmonics of the target frame rate, so that
262  // the bottom bar is at tfr/n or n * tfr, where n is an integer, and
263  // the upper bars are even multiples of that.
264 
265  // Choose a suitable harmonic of the target frame rate near the
266  // bottom part of the chart.
267 
268  double bottom = (double)num_bars / scale;
269 
270  double harmonic;
271  if (_target_frame_rate < bottom) {
272  // n * tfr
273  harmonic = floor(bottom / _target_frame_rate + 0.5) * _target_frame_rate;
274 
275  } else {
276  // tfr / n
277  harmonic = _target_frame_rate / floor(_target_frame_rate / bottom + 0.5);
278  }
279 
280  // Now, make a few bars at k / harmonic.
281  for (int k = 1; k / harmonic <= scale; k++) {
282  _guide_bars.push_back(make_guide_bar(k / harmonic));
283  }
284 
285  _guide_bars_changed = true;
286 }
287 
288 ////////////////////////////////////////////////////////////////////
289 // Function: PStatGraph::make_guide_bar
290 // Access: Protected
291 // Description: Makes a guide bar for the indicated elapsed time or
292 // level units.
293 ////////////////////////////////////////////////////////////////////
294 PStatGraph::GuideBar PStatGraph::
295 make_guide_bar(double value, PStatGraph::GuideBarStyle style) const {
296  string label = format_number(value, _guide_bar_units, _unit_name);
297 
298  if ((style == GBS_normal) &&
299  (_guide_bar_units & GBU_named) == 0) {
300  // If it's a time unit, check to see if it matches our target
301  // frame rate.
302  double hz = 1.0 / value;
303  if (IS_THRESHOLD_EQUAL(hz, _target_frame_rate, 0.001)) {
304  style = GBS_target;
305  }
306  }
307 
308  return GuideBar(value, label, style);
309 }
void move_user_guide_bar(int n, double height)
Adjusts the height of the nth user-defined guide bar.
Definition: pStatGraph.cxx:137
int find_user_guide_bar(double from_height, double to_height) const
Returns the index number of the first user guide bar found whose height is within the indicated range...
Definition: pStatGraph.cxx:172
This is an abstract class that presents the interface to any number of different front-ends for the s...
Definition: pStatMonitor.h:43
const GuideBar & get_guide_bar(int n) const
Returns the nth horizontal guide bar.
Definition: pStatGraph.cxx:101
int get_num_guide_bars() const
Returns the number of horizontal guide bars that should be drawn, based on the indicated target frame...
Definition: pStatGraph.cxx:86
int add_user_guide_bar(double height)
Creates a new user guide bar and returns its index number.
Definition: pStatGraph.cxx:148
static string format_number(double value)
Returns a string representing the value nicely formatted for its range.
Definition: pStatGraph.cxx:184
GuideBar get_user_guide_bar(int n) const
Returns the nth user-defined guide bar.
Definition: pStatGraph.cxx:126
int get_num_user_guide_bars() const
Returns the current number of user-defined guide bars.
Definition: pStatGraph.cxx:116
void remove_user_guide_bar(int n)
Removes the user guide bar with the indicated index number.
Definition: pStatGraph.cxx:160