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

pandatool/src/pstatserver/pStatPianoRoll.cxx

Go to the documentation of this file.
00001 // Filename: pStatPianoRoll.cxx
00002 // Created by:  drose (18Jul00)
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 "pStatPianoRoll.h"
00020 
00021 #include <pStatFrameData.h>
00022 #include <pStatCollectorDef.h>
00023 #include <string_utils.h>
00024 #include <config_pstats.h>
00025 
00026 #include <algorithm>
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: PStatPianoRoll::BarBuilder::Constructor
00030 //       Access: Public
00031 //  Description: This class is used internally to build up the set of
00032 //               color bars defined by a frame's worth of data.
00033 ////////////////////////////////////////////////////////////////////
00034 PStatPianoRoll::BarBuilder::
00035 BarBuilder() {
00036   _is_new = true;
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: PStatPianoRoll::BarBuilder::clear
00041 //       Access: Public
00042 //  Description: Resets the data in the BarBuilder for a new frame.
00043 ////////////////////////////////////////////////////////////////////
00044 void PStatPianoRoll::BarBuilder::
00045 clear() {
00046   _is_new = false;
00047   _color_bars.clear();
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: PStatPianoRoll::BarBuilder::add_data_point
00052 //       Access: Public
00053 //  Description: Adds a new data point.  The first data point for a
00054 //               given collector turns in on (starts the bar), the
00055 //               second data point turns it off (ends the bar).
00056 ////////////////////////////////////////////////////////////////////
00057 void PStatPianoRoll::BarBuilder::
00058 add_data_point(float time) {
00059   if (_color_bars.empty() || _color_bars.back()._end >= 0.0) {
00060     // This is an odd-numbered data point: start the bar.
00061     ColorBar bar;
00062     bar._start = time;
00063     bar._end = -1.0;
00064     _color_bars.push_back(bar);
00065 
00066   } else {
00067     // This is an even-numbered data point: end the bar.
00068     _color_bars.back()._end = time;
00069   }
00070 }
00071 
00072 ////////////////////////////////////////////////////////////////////
00073 //     Function: PStatPianoRoll::BarBuilder::finish
00074 //       Access: Public
00075 //  Description: Makes sure that each start-bar data point was matched
00076 //               by a corresponding end-bar data point.
00077 ////////////////////////////////////////////////////////////////////
00078 void PStatPianoRoll::BarBuilder::
00079 finish(float time) {
00080   if (!_color_bars.empty() && _color_bars.back()._end < 0.0) {
00081     nout << "Warning: collector was left on at the end of the frame.\n";
00082     _color_bars.back()._end = time;
00083   }
00084 }
00085 
00086 ////////////////////////////////////////////////////////////////////
00087 //     Function: PStatPianoRoll::Constructor
00088 //       Access: Public
00089 //  Description:
00090 ////////////////////////////////////////////////////////////////////
00091 PStatPianoRoll::
00092 PStatPianoRoll(PStatMonitor *monitor, int thread_index, int xsize, int ysize) :
00093   PStatGraph(monitor, xsize, ysize),
00094   _thread_index(thread_index)
00095 {
00096   _time_width = 1.0 / pstats_target_frame_rate;
00097   _start_time = 0.0;
00098 
00099   _current_frame = -1;
00100   _guide_bar_units = GBU_ms | GBU_hz | GBU_show_units;
00101   normal_guide_bars();
00102 }
00103 
00104 ////////////////////////////////////////////////////////////////////
00105 //     Function: PStatPianoRoll::Destructor
00106 //       Access: Public, Virtual
00107 //  Description:
00108 ////////////////////////////////////////////////////////////////////
00109 PStatPianoRoll::
00110 ~PStatPianoRoll() {
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////
00114 //     Function: PStatPianoRoll::update
00115 //       Access: Public
00116 //  Description: Updates the chart with the latest data.
00117 ////////////////////////////////////////////////////////////////////
00118 void PStatPianoRoll::
00119 update() {
00120   const PStatClientData *client_data = _monitor->get_client_data();
00121 
00122   // Don't bother to update the thread data until we know at least
00123   // something about the collectors and threads.
00124   if (client_data->get_num_collectors() != 0 &&
00125       client_data->get_num_threads() != 0) {
00126     const PStatThreadData *thread_data =
00127       client_data->get_thread_data(_thread_index);
00128     if (!thread_data->is_empty()) {
00129       int frame_number = thread_data->get_latest_frame_number();
00130       if (frame_number != _current_frame) {
00131         compute_page(thread_data->get_frame(frame_number));
00132         _current_frame = frame_number;
00133         force_redraw();
00134       }
00135     }
00136   }
00137 
00138   idle();
00139 }
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: PStatPianoRoll::changed_size
00143 //       Access: Protected
00144 //  Description: To be called by the user class when the widget size
00145 //               has changed.  This updates the chart's internal data
00146 //               and causes it to issue redraw commands to reflect the
00147 //               new size.
00148 ////////////////////////////////////////////////////////////////////
00149 void PStatPianoRoll::
00150 changed_size(int xsize, int ysize) {
00151   if (xsize != _xsize || ysize != _ysize) {
00152     _xsize = xsize;
00153     _ysize = ysize;
00154 
00155     normal_guide_bars();
00156     force_redraw();
00157   }
00158 }
00159 
00160 ////////////////////////////////////////////////////////////////////
00161 //     Function: PStatPianoRoll::force_redraw
00162 //       Access: Protected
00163 //  Description: To be called by the user class when the whole thing
00164 //               needs to be redrawn for some reason.
00165 ////////////////////////////////////////////////////////////////////
00166 void PStatPianoRoll::
00167 force_redraw() {
00168   if (!_labels.empty()) {
00169     begin_draw();
00170     for (int i = 0; i < (int)_labels.size(); i++) {
00171       int collector_index = _labels[i];
00172       const ColorBars &bars = _page_data[collector_index]._color_bars;
00173 
00174       begin_row(i);
00175       ColorBars::const_iterator bi;
00176       for (bi = bars.begin(); bi != bars.end(); ++bi) {
00177         const ColorBar &bar = (*bi);
00178         draw_bar(i, timestamp_to_pixel(bar._start), timestamp_to_pixel(bar._end));
00179       }
00180       end_row(i);
00181     }
00182     end_draw();
00183   }
00184 }
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: PStatPianoRoll::normal_guide_bars
00188 //       Access: Protected, Virtual
00189 //  Description: Calls update_guide_bars with parameters suitable to
00190 //               this kind of graph.
00191 ////////////////////////////////////////////////////////////////////
00192 void PStatPianoRoll::
00193 normal_guide_bars() {
00194   // We want vaguely 100 pixels between guide bars.
00195   update_guide_bars(get_xsize() / 100, _time_width);
00196 }
00197 
00198 ////////////////////////////////////////////////////////////////////
00199 //     Function: PStatPianoRoll::begin_draw
00200 //       Access: Protected, Virtual
00201 //  Description: Should be overridden by the user class.  This hook
00202 //               will be called before drawing any bars in the chart.
00203 ////////////////////////////////////////////////////////////////////
00204 void PStatPianoRoll::
00205 begin_draw() {
00206 }
00207 
00208 ////////////////////////////////////////////////////////////////////
00209 //     Function: PStatPianoRoll::begin_row
00210 //       Access: Protected, Virtual
00211 //  Description: Should be overridden by the user class.  This hook
00212 //               will be called before drawing any one row of bars.
00213 //               These bars correspond to the collector whose index is
00214 //               get_row_collector(row), and in the color
00215 //               get_row_color(row).
00216 ////////////////////////////////////////////////////////////////////
00217 void PStatPianoRoll::
00218 begin_row(int) {
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: PStatPianoRoll::draw_bar
00223 //       Access: Protected, Virtual
00224 //  Description: Draws a single bar in the chart for the indicated
00225 //               row, in the color get_row_color(row), for the
00226 //               indicated horizontal pixel range.
00227 ////////////////////////////////////////////////////////////////////
00228 void PStatPianoRoll::
00229 draw_bar(int, int, int) {
00230 }
00231 
00232 ////////////////////////////////////////////////////////////////////
00233 //     Function: PStatPianoRoll::end_row
00234 //       Access: Protected, Virtual
00235 //  Description: Should be overridden by the user class.  This hook
00236 //               will be called after drawing a series of color bars
00237 //               for a single row.
00238 ////////////////////////////////////////////////////////////////////
00239 void PStatPianoRoll::
00240 end_row(int) {
00241 }
00242 
00243 ////////////////////////////////////////////////////////////////////
00244 //     Function: PStatPianoRoll::end_draw
00245 //       Access: Protected, Virtual
00246 //  Description: Should be overridden by the user class.  This hook
00247 //               will be called after drawing a series of color bars
00248 //               in the chart.
00249 ////////////////////////////////////////////////////////////////////
00250 void PStatPianoRoll::
00251 end_draw() {
00252 }
00253 
00254 ////////////////////////////////////////////////////////////////////
00255 //     Function: PStatPianoRoll::idle
00256 //       Access: Protected, Virtual
00257 //  Description: Should be overridden by the user class to perform any
00258 //               other updates might be necessary after the bars have
00259 //               been redrawn.
00260 ////////////////////////////////////////////////////////////////////
00261 void PStatPianoRoll::
00262 idle() {
00263 }
00264 
00265 
00266 // STL function object for sorting labels in order by the collector's
00267 // sort index, used in compute_page(), below.
00268 class SortCollectorLabels1 {
00269 public:
00270   SortCollectorLabels1(const PStatClientData *client_data) :
00271     _client_data(client_data) {
00272   }
00273   bool operator () (int a, int b) const {
00274     return
00275       _client_data->get_collector_def(a)._sort >
00276       _client_data->get_collector_def(b)._sort;
00277   }
00278   const PStatClientData *_client_data;
00279 };
00280 
00281 ////////////////////////////////////////////////////////////////////
00282 //     Function: PStatPianoRoll::compute_page
00283 //       Access: Private
00284 //  Description: Examines the given frame data and rebuilds the
00285 //               _page_data to match it.
00286 ////////////////////////////////////////////////////////////////////
00287 void PStatPianoRoll::
00288 compute_page(const PStatFrameData &frame_data) {
00289   _start_time = frame_data.get_start();
00290 
00291   PageData::iterator pi;
00292   for (pi = _page_data.begin(); pi != _page_data.end(); ++pi) {
00293     (*pi).second.clear();
00294   }
00295 
00296   size_t num_bars = _page_data.size();
00297 
00298   int num_events = frame_data.get_num_events();
00299   for (int i = 0; i < num_events; i++) {
00300     int collector_index = frame_data.get_time_collector(i);
00301     float time = frame_data.get_time(i);
00302     _page_data[collector_index].add_data_point(time);
00303   }
00304 
00305   if (_page_data.size() != num_bars) {
00306     // If we added some new bars this time, we'll have to update our
00307     // list.
00308     const PStatClientData *client_data = _monitor->get_client_data();
00309 
00310     _labels.clear();
00311     for (pi = _page_data.begin(); pi != _page_data.end(); ++pi) {
00312       int collector_index = (*pi).first;
00313       if (client_data->has_collector(collector_index)) {
00314         _labels.push_back(collector_index);
00315       }
00316     }
00317 
00318     SortCollectorLabels1 sort_labels(client_data);
00319     sort(_labels.begin(), _labels.end(), sort_labels);
00320 
00321     _labels_changed = true;
00322   }
00323 
00324   // Finally, make sure all of the bars are closed.
00325   float time = frame_data.get_end();
00326   for (pi = _page_data.begin(); pi != _page_data.end(); ++pi) {
00327     (*pi).second.finish(time);
00328   }
00329 }

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