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

pandatool/src/gtk-stats/gtkStatsStripWindow.cxx

Go to the documentation of this file.
00001 // Filename: gtkStatsStripWindow.cxx
00002 // Created by:  drose (14Jul00)
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 "gtkStatsStripWindow.h"
00020 #include "gtkStatsStripChart.h"
00021 #include "gtkStatsGuide.h"
00022 
00023 #include <pStatCollectorDef.h>
00024 #include <string_utils.h>
00025 
00026 #include <stdio.h>  // for sprintf
00027 
00028 
00029 using Gtk::Menu_Helpers::MenuElem;
00030 using Gtk::Menu_Helpers::SeparatorElem;
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //     Function: GtkStatsStripWindow::Constructor
00034 //       Access: Public
00035 //  Description:
00036 ////////////////////////////////////////////////////////////////////
00037 GtkStatsStripWindow::
00038 GtkStatsStripWindow(GtkStatsMonitor *monitor, int thread_index,
00039                     int collector_index, bool show_level,
00040                     int chart_xsize, int chart_ysize) :
00041   GtkStatsWindow(monitor),
00042   _thread_index(thread_index),
00043   _collector_index(collector_index),
00044   _show_level(show_level)
00045 {
00046   _title_unknown = false;
00047   _setup_scale_menu = false;
00048 
00049   setup_menu();
00050   layout_window(chart_xsize, chart_ysize);
00051 
00052   new_collector();  // To set up the menus in case we can.
00053   show();
00054 }
00055 
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: GtkStatsStripWindow::mark_dead
00059 //       Access: Public, Virtual
00060 //  Description: Called when the client's connection has been lost,
00061 //               this should update the window in some obvious way to
00062 //               indicate that the window is no longer live.
00063 ////////////////////////////////////////////////////////////////////
00064 void GtkStatsStripWindow::
00065 mark_dead() {
00066   GtkStatsWindow::mark_dead();
00067   _chart->mark_dead();
00068 }
00069 
00070 ////////////////////////////////////////////////////////////////////
00071 //     Function: GtkStatsStripWindow::new_collector
00072 //       Access: Public, Virtual
00073 //  Description: Called when a new collector has become known.
00074 //
00075 //               For the GtkStatsStripWindow, this forces a rebuild of
00076 //               the menu that selects the collectors available for
00077 //               picking levels.
00078 ////////////////////////////////////////////////////////////////////
00079 void GtkStatsStripWindow::
00080 new_collector() {
00081   const PStatClientData *client_data = _monitor->get_client_data();
00082 
00083   // Determine the set of collectors that display level data.  We'll
00084   // want to put these on the "Levels" pull-down menu.
00085 
00086   pset<int> levels;
00087 
00088   int num_collectors = client_data->get_num_collectors();
00089   for (int i = 0; i < num_collectors; i++) {
00090     if (client_data->has_collector(i) &&
00091         client_data->get_collector_has_level(i)) {
00092       // We only put top-level entries on the menu.  Thus, walk up
00093       // from this collector to its top level (the one below Frame).
00094       int collector_index = i;
00095       const PStatCollectorDef &def =
00096         client_data->get_collector_def(collector_index);
00097       int parent_index = def._parent_index;
00098 
00099       while (parent_index != 0) {
00100         collector_index = parent_index;
00101         const PStatCollectorDef &def =
00102           client_data->get_collector_def(collector_index);
00103         parent_index = def._parent_index;
00104       }
00105 
00106       levels.insert(collector_index);
00107     }
00108   }
00109 
00110   // Now put the collectors we found on the menu.
00111   _levels_menu->items().clear();
00112   pset<int>::const_iterator li;
00113   for (li = levels.begin(); li != levels.end(); ++li) {
00114     int collector_index = (*li);
00115     _levels_menu->items().push_back
00116       (MenuElem(client_data->get_collector_name(collector_index),
00117                 bind(slot(this, &GtkStatsStripWindow::menu_show_levels), collector_index)));
00118   }
00119 
00120   // Also re-set-up the scale menu, in case the properties have changed.
00121   setup_scale_menu();
00122 }
00123 
00124 ////////////////////////////////////////////////////////////////////
00125 //     Function: GtkStatsStripWindow::idle
00126 //       Access: Public, Virtual
00127 //  Description:
00128 ////////////////////////////////////////////////////////////////////
00129 void GtkStatsStripWindow::
00130 idle() {
00131   GtkStatsWindow::idle();
00132   _chart->update();
00133 
00134   const PStatThreadData *thread_data = _chart->get_view().get_thread_data();
00135   if (!thread_data->is_empty()) {
00136     float frame_rate = thread_data->get_frame_rate();
00137     char buffer[128];
00138     sprintf(buffer, "Frame rate: %0.1f Hz", frame_rate);
00139     _frame_rate_label->set_text(buffer);
00140   }
00141 
00142   if (_title_unknown) {
00143     _title_label->set_text(get_title_text());
00144   }
00145 }
00146 
00147 ////////////////////////////////////////////////////////////////////
00148 //     Function: GtkStatsStripWindow::setup_menu
00149 //       Access: Protected, Virtual
00150 //  Description:
00151 ////////////////////////////////////////////////////////////////////
00152 void GtkStatsStripWindow::
00153 setup_menu() {
00154   GtkStatsWindow::setup_menu();
00155 
00156   Gtk::Menu *speed_menu = new Gtk::Menu;
00157 
00158   speed_menu->items().push_back
00159     (MenuElem("1",  // 1 chart width scrolls by per minute.
00160               bind(slot(this, &GtkStatsStripWindow::menu_hscale), 1.0f)));
00161   speed_menu->items().push_back
00162     (MenuElem("2",  // 2 chart widths scroll by per minute.
00163               bind(slot(this, &GtkStatsStripWindow::menu_hscale), 2.0f)));
00164   speed_menu->items().push_back
00165     (MenuElem("3",
00166               bind(slot(this, &GtkStatsStripWindow::menu_hscale), 3.0f)));
00167   speed_menu->items().push_back
00168     (MenuElem("6",
00169               bind(slot(this, &GtkStatsStripWindow::menu_hscale), 6.0f)));
00170   speed_menu->items().push_back
00171     (MenuElem("12",
00172               bind(slot(this, &GtkStatsStripWindow::menu_hscale), 12.0f)));
00173 
00174   _menu->items().push_back(MenuElem("Speed", *manage(speed_menu)));
00175 
00176 
00177   _scale_menu = new Gtk::Menu;
00178   _scale_menu->items().push_back
00179     (MenuElem("Auto scale",
00180               slot(this, &GtkStatsStripWindow::menu_auto_vscale)));
00181 
00182   _menu->items().push_back(MenuElem("Scale", *manage(_scale_menu)));
00183 
00184   _levels_menu = new Gtk::Menu;
00185   _menu->items().push_back(MenuElem("Levels", *manage(_levels_menu)));
00186 }
00187 
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: GtkStatsStripWindow::setup_scale_menu
00191 //       Access: Protected
00192 //  Description: Sets up the options on the scale menu.  We can't do
00193 //               this until we have initialized the _chart member and
00194 //               we have gotten our first collector_index.
00195 ////////////////////////////////////////////////////////////////////
00196 void GtkStatsStripWindow::
00197 setup_scale_menu() {
00198   if (_setup_scale_menu) {
00199     // Already done it.
00200     return;
00201   }
00202 
00203   const PStatClientData *client_data = _monitor->get_client_data();
00204   if (!client_data->has_collector(_collector_index)) {
00205     // Can't set up the scale menu yet.
00206     return;
00207   }
00208 
00209   const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
00210   float base_scale = 1.0;
00211   string unit_name = def._level_units;
00212 
00213   if (_show_level) {
00214     _chart->set_guide_bar_unit_name(unit_name);
00215     _chart->set_guide_bar_units(PStatGraph::GBU_named);
00216 
00217   } else {
00218     _chart->set_guide_bar_units(PStatGraph::GBU_ms);
00219   }
00220 
00221   if (def._suggested_scale != 0.0) {
00222     base_scale = def._suggested_scale;
00223   } else if (!_show_level) {
00224     base_scale = 1.0 / _chart->get_target_frame_rate();
00225   }
00226 
00227   static const float scales[] = {
00228     50.0,
00229     10.0,
00230     5.0,
00231     2.0,
00232     1.0,
00233     0.5,
00234     0.2,
00235     0.1,
00236     0.02,
00237   };
00238   static const int num_scales = sizeof(scales) / sizeof(float);
00239 
00240   for (int i = 0; i < num_scales; i++) {
00241     float scale = base_scale * scales[i];
00242     string label;
00243 
00244     if (_show_level) {
00245       label = _chart->format_number(scale, PStatGraph::GBU_named | PStatGraph::GBU_show_units, unit_name);
00246     } else {
00247       label = _chart->format_number(scale, PStatGraph::GBU_ms | PStatGraph::GBU_hz | PStatGraph::GBU_show_units);
00248     }
00249 
00250     _scale_menu->items().push_back
00251       (MenuElem(label,
00252                 bind(slot(this, &GtkStatsStripWindow::menu_vscale), scale)));
00253   }
00254 
00255   _setup_scale_menu = true;
00256 }
00257 
00258 ////////////////////////////////////////////////////////////////////
00259 //     Function: GtkStatsStripWindow::menu_new_window
00260 //       Access: Protected, Virtual
00261 //  Description:
00262 ////////////////////////////////////////////////////////////////////
00263 void GtkStatsStripWindow::
00264 menu_new_window() {
00265   new GtkStatsStripWindow(_monitor, _thread_index, _collector_index,
00266                           _show_level,
00267                           _chart->get_xsize(), _chart->get_ysize());
00268 }
00269 
00270 ////////////////////////////////////////////////////////////////////
00271 //     Function: GtkStatsStripWindow::menu_hscale
00272 //       Access: Protected
00273 //  Description: Selects a new horizontal scale for the strip chart.
00274 //               This is done from the menu called "Speed", since
00275 //               changing the horizontal scale most obviously affects
00276 //               the scrolling speed.
00277 //
00278 //               The units is in chart width per minute.
00279 ////////////////////////////////////////////////////////////////////
00280 void GtkStatsStripWindow::
00281 menu_hscale(float wpm) {
00282   _chart->set_horizontal_scale(60.0 / wpm);
00283 }
00284 
00285 ////////////////////////////////////////////////////////////////////
00286 //     Function: GtkStatsStripWindow::menu_vscale
00287 //       Access: Protected
00288 //  Description: Selects a new vertical scale for the strip chart.
00289 //               This is done from the menu called "Scale".
00290 //
00291 //               The units is in seconds, or whatever the units
00292 //               of choice are.
00293 ////////////////////////////////////////////////////////////////////
00294 void GtkStatsStripWindow::
00295 menu_vscale(float max_height) {
00296   _chart->set_vertical_scale(max_height);
00297 }
00298 
00299 ////////////////////////////////////////////////////////////////////
00300 //     Function: GtkStatsStripWindow::menu_auto_vscale
00301 //       Access: Protected
00302 //  Description: Selects a suitable vertical scale based on the data
00303 //               already visible in the chart.
00304 ////////////////////////////////////////////////////////////////////
00305 void GtkStatsStripWindow::
00306 menu_auto_vscale() {
00307   _chart->set_auto_vertical_scale();
00308 }
00309 
00310 ////////////////////////////////////////////////////////////////////
00311 //     Function: GtkStatsStripWindow::menu_show_levels
00312 //       Access: Protected
00313 //  Description: Shows the level values known for the indicated
00314 //               collector.
00315 ////////////////////////////////////////////////////////////////////
00316 void GtkStatsStripWindow::
00317 menu_show_levels(int collector_index) {
00318   new GtkStatsStripWindow(_monitor, _thread_index, collector_index,
00319                           true,
00320                           _chart->get_xsize(), _chart->get_ysize());
00321 }
00322 
00323 ////////////////////////////////////////////////////////////////////
00324 //     Function: GtkStatsStripWindow::open_subchart
00325 //       Access: Protected
00326 //  Description: This is called in response to the collector_picked
00327 //               signal from the strip chart, which is generated when
00328 //               the user double-clicks on a band of color or a label.
00329 //
00330 //               This opens up a new window focusing just on the
00331 //               indicated collector.
00332 ////////////////////////////////////////////////////////////////////
00333 void GtkStatsStripWindow::
00334 open_subchart(int collector_index) {
00335   new GtkStatsStripWindow(_monitor, _thread_index, collector_index,
00336                           _show_level,
00337                           _chart->get_xsize(), _chart->get_ysize());
00338 }
00339 
00340 ////////////////////////////////////////////////////////////////////
00341 //     Function: GtkStatsStripWindow::layout_window
00342 //       Access: Public
00343 //  Description:
00344 ////////////////////////////////////////////////////////////////////
00345 void GtkStatsStripWindow::
00346 layout_window(int chart_xsize, int chart_ysize) {
00347   Gtk::HBox *hbox = new Gtk::HBox;
00348   hbox = new Gtk::HBox;
00349   hbox->show();
00350   _main_box->pack_start(*manage(hbox), true, true, 8);
00351 
00352   Gtk::Table *chart_table = new Gtk::Table(3, 2);
00353   chart_table->show();
00354   hbox->pack_start(*manage(chart_table), true, true, 8);
00355 
00356   Gtk::HBox *title_hbox = new Gtk::HBox;
00357   title_hbox->show();
00358   chart_table->attach(*manage(title_hbox), 1, 2, 0, 1,
00359                       (GTK_FILL|GTK_EXPAND), 0);
00360 
00361   _title_label = new Gtk::Label(get_title_text());
00362   if (_collector_index != 0 || _thread_index != 0) {
00363     _title_label->show();
00364     _title_label->set_alignment(0.0, 0.5);
00365     title_hbox->pack_start(*manage(_title_label), true, true);
00366   }
00367 
00368   _frame_rate_label = new Gtk::Label;
00369   if (_collector_index == 0) {
00370     _frame_rate_label->show();
00371     _frame_rate_label->set_alignment(1.0, 0.5);
00372     title_hbox->pack_start(*manage(_frame_rate_label), true, true);
00373   }
00374 
00375   Gtk::Frame *frame = new Gtk::Frame;
00376   frame->set_shadow_type(GTK_SHADOW_ETCHED_OUT);
00377   frame->show();
00378   chart_table->attach(*manage(frame), 1, 2, 1, 2);
00379 
00380   if (_show_level) {
00381     _chart = new GtkStatsStripChart(_monitor,
00382                                     _monitor->get_level_view(_collector_index, _thread_index),
00383                                     _collector_index,
00384                                     chart_xsize, chart_ysize);
00385   } else {
00386     _chart = new GtkStatsStripChart(_monitor,
00387                                     _monitor->get_view(_thread_index),
00388                                     _collector_index,
00389                                     chart_xsize, chart_ysize);
00390   }
00391 
00392   _chart->collector_picked.
00393     connect(slot(this, &GtkStatsStripWindow::open_subchart));
00394   frame->add(*manage(_chart));
00395 
00396   chart_table->attach(*_chart->get_labels(), 0, 1, 1, 2,
00397                       0, (GTK_FILL|GTK_EXPAND), 4, 0);
00398   chart_table->attach(*_chart->get_guide(), 2, 3, 1, 2,
00399                       0, (GTK_FILL|GTK_EXPAND), 4, 0);
00400   _chart->show();
00401 }
00402 
00403 
00404 ////////////////////////////////////////////////////////////////////
00405 //     Function: GtkStatsStripWindow::get_title_text
00406 //       Access: Private
00407 //  Description: Returns the text suitable for the title label on the
00408 //               top line.
00409 ////////////////////////////////////////////////////////////////////
00410 string GtkStatsStripWindow::
00411 get_title_text() {
00412   string text;
00413 
00414   _title_unknown = false;
00415 
00416   const PStatClientData *client_data = _monitor->get_client_data();
00417   if (client_data->has_collector(_collector_index)) {
00418     const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
00419     if (_show_level) {
00420       if (def._level_units.empty()) {
00421         text = def._name;
00422       } else {
00423         text = def._name + " (" + def._level_units + ")";
00424       }
00425     } else {
00426       text = def._name + " time";
00427     }
00428   } else {
00429     _title_unknown = true;
00430   }
00431 
00432   if (_thread_index != 0) {
00433     if (client_data->has_thread(_thread_index)) {
00434       text += "(" + client_data->get_thread_name(_thread_index) + " thread)";
00435     } else {
00436       _title_unknown = true;
00437     }
00438   }
00439 
00440   return text;
00441 }
00442 

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