00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "gtkStatsMonitor.h"
00016 #include "gtkStats.h"
00017 #include "gtkStatsServer.h"
00018 #include "gtkStatsStripChart.h"
00019 #include "gtkStatsChartMenu.h"
00020 #include "gtkStatsPianoRoll.h"
00021 #include "gtkStatsMenuId.h"
00022 #include "pStatGraph.h"
00023 #include "pStatCollectorDef.h"
00024 #include "indent.h"
00025
00026 typedef void vc();
00027
00028 GtkItemFactoryEntry GtkStatsMonitor::menu_entries[] = {
00029 { "/Options", NULL, NULL, 0, "<Branch>" },
00030 { "/Options/Units", NULL, NULL, 0, "<Branch>" },
00031 { "/Options/Units/ms", NULL, (vc *)&handle_menu_command, MI_time_ms, "<RadioItem>" },
00032 { "/Options/Units/Hz", NULL, (vc *)&handle_menu_command, MI_time_hz, "/Options/Units/ms" },
00033 { "/Speed", NULL, NULL, 0, "<Branch>" },
00034 { "/Speed/1", NULL, (vc *)&handle_menu_command, MI_speed_1, "<RadioItem>" },
00035 { "/Speed/2", NULL, (vc *)&handle_menu_command, MI_speed_2, "/Speed/1" },
00036 { "/Speed/3", NULL, (vc *)&handle_menu_command, MI_speed_3, "/Speed/1" },
00037 { "/Speed/6", NULL, (vc *)&handle_menu_command, MI_speed_6, "/Speed/1" },
00038 { "/Speed/12", NULL, (vc *)&handle_menu_command, MI_speed_12, "/Speed/1" },
00039 { "/Speed/sep", NULL, NULL, 0, "<Separator>" },
00040 { "/Speed/pause", NULL, (vc *)&handle_menu_command, MI_pause, "<CheckItem>" },
00041 };
00042 int GtkStatsMonitor::num_menu_entries = sizeof(menu_entries) / sizeof(GtkItemFactoryEntry);
00043
00044
00045
00046
00047
00048
00049
00050 GtkStatsMonitor::
00051 GtkStatsMonitor(GtkStatsServer *server) : PStatMonitor(server) {
00052 _window = NULL;
00053 _item_factory = NULL;
00054
00055
00056 _time_units = 0;
00057 _scroll_speed = 0.0;
00058 _pause = false;
00059 }
00060
00061
00062
00063
00064
00065
00066 GtkStatsMonitor::
00067 ~GtkStatsMonitor() {
00068 shutdown();
00069 }
00070
00071
00072
00073
00074
00075
00076
00077 string GtkStatsMonitor::
00078 get_monitor_name() {
00079 return "GtkStats";
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 void GtkStatsMonitor::
00094 initialized() {
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104 void GtkStatsMonitor::
00105 got_hello() {
00106 create_window();
00107 open_strip_chart(0, 0, false);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 void GtkStatsMonitor::
00122 got_bad_version(int client_major, int client_minor,
00123 int server_major, int server_minor) {
00124 ostringstream str;
00125 str << "Unable to honor connection attempt from "
00126 << get_client_progname() << " on " << get_client_hostname()
00127 << ": unsupported PStats version "
00128 << client_major << "." << client_minor;
00129
00130 if (server_minor == 0) {
00131 str << " (server understands version " << server_major
00132 << "." << server_minor << " only).";
00133 } else {
00134 str << " (server understands versions " << server_major
00135 << ".0 through " << server_major << "." << server_minor << ").";
00136 }
00137
00138 string message = str.str();
00139 GtkWidget *dialog =
00140 gtk_message_dialog_new(GTK_WINDOW(main_window),
00141 GTK_DIALOG_DESTROY_WITH_PARENT,
00142 GTK_MESSAGE_ERROR,
00143 GTK_BUTTONS_CLOSE,
00144 message.c_str());
00145 gtk_dialog_run(GTK_DIALOG(dialog));
00146 gtk_widget_destroy(dialog);
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 void GtkStatsMonitor::
00161 new_collector(int collector_index) {
00162 Graphs::iterator gi;
00163 for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00164 GtkStatsGraph *graph = (*gi);
00165 graph->new_collector(collector_index);
00166 }
00167
00168
00169 ChartMenus::iterator mi;
00170 for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
00171 (*mi)->do_update();
00172 }
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 void GtkStatsMonitor::
00187 new_thread(int thread_index) {
00188 GtkStatsChartMenu *chart_menu = new GtkStatsChartMenu(this, thread_index);
00189 GtkWidget *menu_bar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
00190 chart_menu->add_to_menu_bar(menu_bar, _next_chart_index);
00191 ++_next_chart_index;
00192 _chart_menus.push_back(chart_menu);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 void GtkStatsMonitor::
00205 new_data(int thread_index, int frame_number) {
00206 Graphs::iterator gi;
00207 for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00208 GtkStatsGraph *graph = (*gi);
00209 graph->new_data(thread_index, frame_number);
00210 }
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 void GtkStatsMonitor::
00223 lost_connection() {
00224 nout << "Lost connection to " << get_client_hostname() << "\n";
00225
00226 shutdown();
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 void GtkStatsMonitor::
00237 idle() {
00238
00239 ChartMenus::iterator mi;
00240 for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
00241 (*mi)->check_update();
00242 }
00243
00244
00245 const PStatThreadData *thread_data = get_client_data()->get_thread_data(0);
00246 double frame_rate = thread_data->get_frame_rate();
00247 if (frame_rate != 0.0f) {
00248 char buffer[128];
00249 sprintf(buffer, "%0.1f ms / %0.1f Hz", 1000.0f / frame_rate, frame_rate);
00250
00251 gtk_label_set_text(GTK_LABEL(_frame_rate_label), buffer);
00252 }
00253 }
00254
00255
00256
00257
00258
00259
00260
00261 bool GtkStatsMonitor::
00262 has_idle() {
00263 return true;
00264 }
00265
00266
00267
00268
00269
00270
00271 void GtkStatsMonitor::
00272 user_guide_bars_changed() {
00273 Graphs::iterator gi;
00274 for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00275 GtkStatsGraph *graph = (*gi);
00276 graph->user_guide_bars_changed();
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285 GtkWidget *GtkStatsMonitor::
00286 get_window() const {
00287 return _window;
00288 }
00289
00290
00291
00292
00293
00294
00295 void GtkStatsMonitor::
00296 open_strip_chart(int thread_index, int collector_index, bool show_level) {
00297 GtkStatsStripChart *graph =
00298 new GtkStatsStripChart(this, thread_index, collector_index, show_level);
00299 add_graph(graph);
00300
00301 graph->set_time_units(_time_units);
00302 graph->set_scroll_speed(_scroll_speed);
00303 graph->set_pause(_pause);
00304 }
00305
00306
00307
00308
00309
00310
00311 void GtkStatsMonitor::
00312 open_piano_roll(int thread_index) {
00313 GtkStatsPianoRoll *graph = new GtkStatsPianoRoll(this, thread_index);
00314 add_graph(graph);
00315
00316 graph->set_time_units(_time_units);
00317 graph->set_scroll_speed(_scroll_speed);
00318 graph->set_pause(_pause);
00319 }
00320
00321
00322
00323
00324
00325
00326
00327 const GtkStatsMonitor::MenuDef *GtkStatsMonitor::
00328 add_menu(const MenuDef &menu_def) {
00329 pair<Menus::iterator, bool> result = _menus.insert(menu_def);
00330 Menus::iterator mi = result.first;
00331 const GtkStatsMonitor::MenuDef &new_menu_def = (*mi);
00332 if (result.second) {
00333
00334 ((GtkStatsMonitor::MenuDef &)new_menu_def)._monitor = this;
00335 }
00336 return &new_menu_def;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 void GtkStatsMonitor::
00348 set_time_units(int unit_mask) {
00349 _time_units = unit_mask;
00350
00351
00352 Graphs::iterator gi;
00353 for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00354 GtkStatsGraph *graph = (*gi);
00355 graph->set_time_units(_time_units);
00356 }
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366 void GtkStatsMonitor::
00367 set_scroll_speed(double scroll_speed) {
00368 _scroll_speed = scroll_speed;
00369
00370
00371 Graphs::iterator gi;
00372 for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00373 GtkStatsGraph *graph = (*gi);
00374 graph->set_scroll_speed(_scroll_speed);
00375 }
00376 }
00377
00378
00379
00380
00381
00382
00383
00384 void GtkStatsMonitor::
00385 set_pause(bool pause) {
00386 _pause = pause;
00387
00388
00389 Graphs::iterator gi;
00390 for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00391 GtkStatsGraph *graph = (*gi);
00392 graph->set_pause(_pause);
00393 }
00394 }
00395
00396
00397
00398
00399
00400
00401
00402 void GtkStatsMonitor::
00403 add_graph(GtkStatsGraph *graph) {
00404 _graphs.insert(graph);
00405 }
00406
00407
00408
00409
00410
00411
00412 void GtkStatsMonitor::
00413 remove_graph(GtkStatsGraph *graph) {
00414 Graphs::iterator gi = _graphs.find(graph);
00415 if (gi != _graphs.end()) {
00416 _graphs.erase(gi);
00417 delete graph;
00418 }
00419 }
00420
00421
00422
00423
00424
00425
00426 void GtkStatsMonitor::
00427 create_window() {
00428 if (_window != NULL) {
00429 return;
00430 }
00431
00432 _window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00433
00434 g_signal_connect(G_OBJECT(_window), "delete_event",
00435 G_CALLBACK(window_delete_event), this);
00436 g_signal_connect(G_OBJECT(_window), "destroy",
00437 G_CALLBACK(window_destroy), this);
00438
00439 _window_title = get_client_progname() + " on " + get_client_hostname();
00440 gtk_window_set_title(GTK_WINDOW(_window), _window_title.c_str());
00441
00442 gtk_window_set_default_size(GTK_WINDOW(_window), 500, 360);
00443
00444
00445 GtkAccelGroup *accel_group = gtk_accel_group_new();
00446 _item_factory =
00447 gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<PStats>", accel_group);
00448 gtk_item_factory_create_items(_item_factory, num_menu_entries, menu_entries,
00449 this);
00450 gtk_window_add_accel_group(GTK_WINDOW(_window), accel_group);
00451 GtkWidget *menu_bar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
00452 _next_chart_index = 2;
00453
00454 setup_frame_rate_label();
00455
00456 ChartMenus::iterator mi;
00457 for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
00458 (*mi)->add_to_menu_bar(menu_bar, _next_chart_index);
00459 ++_next_chart_index;
00460 }
00461
00462
00463 GtkWidget *main_vbox = gtk_vbox_new(FALSE, 1);
00464 gtk_container_add(GTK_CONTAINER(_window), main_vbox);
00465 gtk_box_pack_start(GTK_BOX(main_vbox), menu_bar, FALSE, TRUE, 0);
00466
00467 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(_item_factory, "/Speed/3")),
00468 TRUE);
00469 set_scroll_speed(3);
00470
00471 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(_item_factory, "/Options/Units/ms")),
00472 TRUE);
00473 set_time_units(PStatGraph::GBU_ms);
00474
00475 gtk_widget_show_all(_window);
00476 gtk_widget_show(_window);
00477
00478 set_pause(false);
00479 }
00480
00481
00482
00483
00484
00485
00486 void GtkStatsMonitor::
00487 shutdown() {
00488 Graphs::iterator gi;
00489 for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
00490 delete (*gi);
00491 }
00492 _graphs.clear();
00493
00494 ChartMenus::iterator mi;
00495 for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
00496 delete (*mi);
00497 }
00498 _chart_menus.clear();
00499
00500 if (_window != NULL) {
00501 gtk_widget_destroy(_window);
00502 _window = NULL;
00503 }
00504
00505 #ifdef DEVELOP_GTKSTATS
00506
00507 gtk_main_quit();
00508 #endif
00509 }
00510
00511
00512
00513
00514
00515
00516 gboolean GtkStatsMonitor::
00517 window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
00518
00519
00520 return FALSE;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529 void GtkStatsMonitor::
00530 window_destroy(GtkWidget *widget, gpointer data) {
00531 GtkStatsMonitor *self = (GtkStatsMonitor *)data;
00532 self->close();
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 void GtkStatsMonitor::
00545 setup_frame_rate_label() {
00546 GtkWidget *menu_bar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
00547
00548 _frame_rate_menu_item = gtk_menu_item_new();
00549 _frame_rate_label = gtk_label_new("");
00550 gtk_container_add(GTK_CONTAINER(_frame_rate_menu_item), _frame_rate_label);
00551
00552 gtk_widget_show(_frame_rate_menu_item);
00553 gtk_widget_show(_frame_rate_label);
00554 gtk_menu_item_right_justify(GTK_MENU_ITEM(_frame_rate_menu_item));
00555
00556 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), _frame_rate_menu_item);
00557 }
00558
00559
00560
00561
00562
00563
00564 void GtkStatsMonitor::
00565 handle_menu_command(gpointer callback_data, guint menu_id, GtkWidget *widget) {
00566 GtkStatsMonitor *self = (GtkStatsMonitor *)callback_data;
00567 switch (menu_id) {
00568 case MI_none:
00569 break;
00570
00571 case MI_time_ms:
00572 self->set_time_units(PStatGraph::GBU_ms);
00573 break;
00574
00575 case MI_time_hz:
00576 self->set_time_units(PStatGraph::GBU_hz);
00577 break;
00578
00579 case MI_speed_1:
00580 self->set_scroll_speed(1);
00581 break;
00582
00583 case MI_speed_2:
00584 self->set_scroll_speed(2);
00585 break;
00586
00587 case MI_speed_3:
00588 self->set_scroll_speed(3);
00589 break;
00590
00591 case MI_speed_6:
00592 self->set_scroll_speed(6);
00593 break;
00594
00595 case MI_speed_12:
00596 self->set_scroll_speed(12);
00597 break;
00598
00599 case MI_pause:
00600 self->set_pause(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
00601 break;
00602 }
00603 }