Panda3D
winStatsMonitor.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file winStatsMonitor.cxx
10  * @author drose
11  * @date 2003-12-02
12  */
13 
14 #include "winStatsMonitor.h"
15 #include "winStatsServer.h"
16 #include "winStatsStripChart.h"
17 #include "winStatsPianoRoll.h"
18 #include "winStatsChartMenu.h"
19 #include "winStatsMenuId.h"
20 #include "pStatGraph.h"
21 #include "pStatCollectorDef.h"
22 #include "indent.h"
23 
24 bool WinStatsMonitor::_window_class_registered = false;
25 const char * const WinStatsMonitor::_window_class_name = "monitor";
26 
27 /**
28  *
29  */
30 WinStatsMonitor::
31 WinStatsMonitor(WinStatsServer *server) : PStatMonitor(server) {
32  _window = 0;
33  _menu_bar = 0;
34  _options_menu = 0;
35 
36  // These will be filled in later when the menu is created.
37  _time_units = 0;
38  _scroll_speed = 0.0;
39  _pause = false;
40 }
41 
42 /**
43  *
44  */
45 WinStatsMonitor::
46 ~WinStatsMonitor() {
47  Graphs::iterator gi;
48  for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
49  delete (*gi);
50  }
51  _graphs.clear();
52 
53  ChartMenus::iterator mi;
54  for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
55  delete (*mi);
56  }
57  _chart_menus.clear();
58 
59  if (_window) {
60  DestroyWindow(_window);
61  _window = 0;
62  }
63 
64 #ifdef DEVELOP_WINSTATS
65  // For Winstats developers, exit when the first monitor closes.
66  exit(0);
67 #endif
68 }
69 
70 /**
71  * Should be redefined to return a descriptive name for the type of
72  * PStatsMonitor this is.
73  */
74 std::string WinStatsMonitor::
76  return "WinStats";
77 }
78 
79 /**
80  * Called after the monitor has been fully set up. At this time, it will have
81  * a valid _client_data pointer, and things like is_alive() and close() will
82  * be meaningful. However, we may not yet know who we're connected to
83  * (is_client_known() may return false), and we may not know anything about
84  * the threads or collectors we're about to get data on.
85  */
88 }
89 
90 /**
91  * Called when the "hello" message has been received from the client. At this
92  * time, the client's hostname and program name will be known.
93  */
96  create_window();
97  open_strip_chart(0, 0, false);
98 }
99 
100 /**
101  * Like got_hello(), this is called when the "hello" message has been received
102  * from the client. At this time, the client's hostname and program name will
103  * be known. However, the client appears to be an incompatible version and
104  * the connection will be terminated; the monitor should issue a message to
105  * that effect.
106  */
108 got_bad_version(int client_major, int client_minor,
109  int server_major, int server_minor) {
110  std::ostringstream str;
111  str << "Unable to honor connection attempt from "
112  << get_client_progname() << " on " << get_client_hostname()
113  << ": unsupported PStats version "
114  << client_major << "." << client_minor;
115 
116  if (server_minor == 0) {
117  str << " (server understands version " << server_major
118  << "." << server_minor << " only).";
119  } else {
120  str << " (server understands versions " << server_major
121  << ".0 through " << server_major << "." << server_minor << ").";
122  }
123 
124  std::string message = str.str();
125  MessageBox(nullptr, message.c_str(), "Bad version",
126  MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND);
127 }
128 
129 /**
130  * Called whenever a new Collector definition is received from the client.
131  * Generally, the client will send all of its collectors over shortly after
132  * connecting, but there's no guarantee that they will all be received before
133  * the first frames are received. The monitor should be prepared to accept
134  * new Collector definitions midstream.
135  */
137 new_collector(int collector_index) {
138  Graphs::iterator gi;
139  for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
140  WinStatsGraph *graph = (*gi);
141  graph->new_collector(collector_index);
142  }
143 
144  // We might need to update our menus.
145  ChartMenus::iterator mi;
146  for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
147  (*mi)->do_update();
148  }
149 }
150 
151 /**
152  * Called whenever a new Thread definition is received from the client.
153  * Generally, the client will send all of its threads over shortly after
154  * connecting, but there's no guarantee that they will all be received before
155  * the first frames are received. The monitor should be prepared to accept
156  * new Thread definitions midstream.
157  */
159 new_thread(int thread_index) {
160  WinStatsChartMenu *chart_menu = new WinStatsChartMenu(this, thread_index);
161  chart_menu->add_to_menu_bar(_menu_bar, MI_frame_rate_label);
162  _chart_menus.push_back(chart_menu);
163  DrawMenuBar(_window);
164 }
165 
166 /**
167  * Called as each frame's data is made available. There is no guarantee the
168  * frames will arrive in order, or that all of them will arrive at all. The
169  * monitor should be prepared to accept frames received out-of-order or
170  * missing.
171  */
173 new_data(int thread_index, int frame_number) {
174  Graphs::iterator gi;
175  for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
176  WinStatsGraph *graph = (*gi);
177  graph->new_data(thread_index, frame_number);
178  }
179 }
180 
181 
182 /**
183  * Called whenever the connection to the client has been lost. This is a
184  * permanent state change. The monitor should update its display to represent
185  * this, and may choose to close down automatically.
186  */
189  nout << "Lost connection to " << get_client_hostname() << "\n";
190 
191  if (_window) {
192  DestroyWindow(_window);
193  _window = 0;
194  }
195 }
196 
197 /**
198  * If has_idle() returns true, this will be called periodically to allow the
199  * monitor to update its display or whatever it needs to do.
200  */
202 idle() {
203  // Check if any of our chart menus need updating.
204  ChartMenus::iterator mi;
205  for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
206  (*mi)->check_update();
207  }
208 
209  // Update the frame rate label from the main thread (thread 0).
210  const PStatThreadData *thread_data = get_client_data()->get_thread_data(0);
211  double frame_rate = thread_data->get_frame_rate();
212  if (frame_rate != 0.0f) {
213  char buffer[128];
214  sprintf(buffer, "%0.1f ms / %0.1f Hz", 1000.0f / frame_rate, frame_rate);
215 
216  MENUITEMINFO mii;
217  memset(&mii, 0, sizeof(mii));
218  mii.cbSize = sizeof(mii);
219  mii.fMask = MIIM_STRING;
220  mii.dwTypeData = buffer;
221  SetMenuItemInfo(_menu_bar, MI_frame_rate_label, FALSE, &mii);
222  DrawMenuBar(_window);
223  }
224 }
225 
226 /**
227  * Should be redefined to return true if you want to redefine idle() and
228  * expect it to be called.
229  */
232  return true;
233 }
234 
235 /**
236  * Called when the user guide bars have been changed.
237  */
240  Graphs::iterator gi;
241  for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
242  WinStatsGraph *graph = (*gi);
243  graph->user_guide_bars_changed();
244  }
245 }
246 
247 /**
248  * Returns the window handle to the monitor's window.
249  */
251 get_window() const {
252  return _window;
253 }
254 
255 /**
256  * Opens a new strip chart showing the indicated data.
257  */
259 open_strip_chart(int thread_index, int collector_index, bool show_level) {
260  WinStatsStripChart *graph =
261  new WinStatsStripChart(this, thread_index, collector_index, show_level);
262  add_graph(graph);
263 
264  graph->set_time_units(_time_units);
265  graph->set_scroll_speed(_scroll_speed);
266  graph->set_pause(_pause);
267 }
268 
269 /**
270  * Opens a new piano roll showing the indicated data.
271  */
273 open_piano_roll(int thread_index) {
274  WinStatsPianoRoll *graph = new WinStatsPianoRoll(this, thread_index);
275  add_graph(graph);
276 
277  graph->set_time_units(_time_units);
278  graph->set_scroll_speed(_scroll_speed);
279  graph->set_pause(_pause);
280 }
281 
282 /**
283  * Returns the MenuDef properties associated with the indicated menu ID. This
284  * specifies what we expect to do when the given menu has been selected.
285  */
287 lookup_menu(int menu_id) const {
288  static MenuDef invalid(0, 0, false);
289  int menu_index = menu_id - MI_new_chart;
290  nassertr(menu_index >= 0 && menu_index < (int)_menu_by_id.size(), invalid);
291  return _menu_by_id[menu_index];
292 }
293 
294 /**
295  * Returns the menu ID that is reserved for the indicated MenuDef properties.
296  * If this is the first time these particular properties have been requested,
297  * a new menu ID is returned; otherwise, the existing menu ID is returned.
298  */
300 get_menu_id(const MenuDef &menu_def) {
301  MenuByDef::iterator mi;
302  mi = _menu_by_def.find(menu_def);
303  if (mi != _menu_by_def.end()) {
304  return (*mi).second;
305  }
306 
307  // Slot a new id.
308  int menu_id = (int)_menu_by_id.size() + MI_new_chart;
309  _menu_by_id.push_back(menu_def);
310  _menu_by_def[menu_def] = menu_id;
311 
312  return menu_id;
313 }
314 
315 /**
316  * Called when the user selects a new time units from the monitor pulldown
317  * menu, this should adjust the units for all graphs to the indicated mask if
318  * it is a time-based graph.
319  */
321 set_time_units(int unit_mask) {
322  _time_units = unit_mask;
323 
324  // First, change all of the open graphs appropriately.
325  Graphs::iterator gi;
326  for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
327  WinStatsGraph *graph = (*gi);
328  graph->set_time_units(_time_units);
329  }
330 
331  // Now change the checkmark on the pulldown menu.
332  MENUITEMINFO mii;
333  memset(&mii, 0, sizeof(mii));
334  mii.cbSize = sizeof(mii);
335  mii.fMask = MIIM_STATE;
336 
337  mii.fState = ((_time_units & PStatGraph::GBU_ms) != 0) ?
338  MFS_CHECKED : MFS_UNCHECKED;
339  SetMenuItemInfo(_options_menu, MI_time_ms, FALSE, &mii);
340 
341  mii.fState = ((_time_units & PStatGraph::GBU_hz) != 0) ?
342  MFS_CHECKED : MFS_UNCHECKED;
343  SetMenuItemInfo(_options_menu, MI_time_hz, FALSE, &mii);
344 }
345 
346 /**
347  * Called when the user selects a new scroll speed from the monitor pulldown
348  * menu, this should adjust the speeds for all graphs to the indicated value.
349  */
351 set_scroll_speed(double scroll_speed) {
352  _scroll_speed = scroll_speed;
353 
354  // First, change all of the open graphs appropriately.
355  Graphs::iterator gi;
356  for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
357  WinStatsGraph *graph = (*gi);
358  graph->set_scroll_speed(_scroll_speed);
359  }
360 
361  // Now change the checkmark on the pulldown menu.
362  MENUITEMINFO mii;
363  memset(&mii, 0, sizeof(mii));
364  mii.cbSize = sizeof(mii);
365  mii.fMask = MIIM_STATE;
366 
367  mii.fState = IS_THRESHOLD_EQUAL(_scroll_speed, 1.0, 0.1) ?
368  MFS_CHECKED : MFS_UNCHECKED;
369  SetMenuItemInfo(_speed_menu, MI_speed_1, FALSE, &mii);
370 
371  mii.fState = IS_THRESHOLD_EQUAL(_scroll_speed, 2.0, 0.1) ?
372  MFS_CHECKED : MFS_UNCHECKED;
373  SetMenuItemInfo(_speed_menu, MI_speed_2, FALSE, &mii);
374 
375  mii.fState = IS_THRESHOLD_EQUAL(_scroll_speed, 3.0, 0.1) ?
376  MFS_CHECKED : MFS_UNCHECKED;
377  SetMenuItemInfo(_speed_menu, MI_speed_3, FALSE, &mii);
378 
379  mii.fState = IS_THRESHOLD_EQUAL(_scroll_speed, 6.0, 0.1) ?
380  MFS_CHECKED : MFS_UNCHECKED;
381  SetMenuItemInfo(_speed_menu, MI_speed_6, FALSE, &mii);
382 
383  mii.fState = IS_THRESHOLD_EQUAL(_scroll_speed, 12.0, 0.1) ?
384  MFS_CHECKED : MFS_UNCHECKED;
385  SetMenuItemInfo(_speed_menu, MI_speed_12, FALSE, &mii);
386 }
387 
388 /**
389  * Called when the user selects a pause on or pause off option from the menu.
390  */
392 set_pause(bool pause) {
393  _pause = pause;
394 
395  // First, change all of the open graphs appropriately.
396  Graphs::iterator gi;
397  for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
398  WinStatsGraph *graph = (*gi);
399  graph->set_pause(_pause);
400  }
401 
402  // Now change the checkmark on the pulldown menu.
403  MENUITEMINFO mii;
404  memset(&mii, 0, sizeof(mii));
405  mii.cbSize = sizeof(mii);
406  mii.fMask = MIIM_STATE;
407 
408  mii.fState = _pause ? MFS_CHECKED : MFS_UNCHECKED;
409  SetMenuItemInfo(_speed_menu, MI_pause, FALSE, &mii);
410 }
411 
412 /**
413  * Adds the newly-created graph to the list of managed graphs.
414  */
415 void WinStatsMonitor::
416 add_graph(WinStatsGraph *graph) {
417  _graphs.insert(graph);
418 }
419 
420 /**
421  * Deletes the indicated graph.
422  */
423 void WinStatsMonitor::
424 remove_graph(WinStatsGraph *graph) {
425  Graphs::iterator gi = _graphs.find(graph);
426  if (gi != _graphs.end()) {
427  _graphs.erase(gi);
428  delete graph;
429  }
430 }
431 
432 /**
433  * Creates the window for this monitor.
434  */
435 void WinStatsMonitor::
436 create_window() {
437  if (_window) {
438  return;
439  }
440 
441  HINSTANCE application = GetModuleHandle(nullptr);
442  register_window_class(application);
443 
444  _menu_bar = CreateMenu();
445 
446  setup_options_menu();
447  setup_speed_menu();
448  setup_frame_rate_label();
449 
450  ChartMenus::iterator mi;
451  for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
452  (*mi)->add_to_menu_bar(_menu_bar, MI_frame_rate_label);
453  }
454 
455  _window_title = get_client_progname() + " on " + get_client_hostname();
456  DWORD window_style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
457  WS_CLIPSIBLINGS | WS_VISIBLE;
458 
459  _window =
460  CreateWindow(_window_class_name, _window_title.c_str(), window_style,
461  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
462  nullptr, _menu_bar, application, 0);
463  if (!_window) {
464  nout << "Could not create monitor window!\n";
465  exit(1);
466  }
467 
468  SetWindowLongPtr(_window, 0, (LONG_PTR)this);
469 
470  // For some reason, SW_SHOWNORMAL doesn't always work, but SW_RESTORE seems
471  // to.
472  ShowWindow(_window, SW_RESTORE);
473  SetForegroundWindow(_window);
474 }
475 
476 /**
477  * Creates the "Options" pulldown menu.
478  */
479 void WinStatsMonitor::
480 setup_options_menu() {
481  _options_menu = CreatePopupMenu();
482 
483  MENUITEMINFO mii;
484  memset(&mii, 0, sizeof(mii));
485  mii.cbSize = sizeof(mii);
486 
487  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
488  mii.fType = MFT_STRING;
489  mii.hSubMenu = _options_menu;
490 
491  // One day, when there is more than one option here, we will actually
492  // present this to the user as the "Options" menu. For now, the only option
493  // we have is time units. mii.dwTypeData = "Options";
494  mii.dwTypeData = "Units";
495  InsertMenuItem(_menu_bar, GetMenuItemCount(_menu_bar), TRUE, &mii);
496 
497 
498  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_CHECKMARKS | MIIM_STATE;
499  mii.fType = MFT_STRING | MFT_RADIOCHECK;
500  mii.hbmpChecked = nullptr;
501  mii.hbmpUnchecked = nullptr;
502  mii.fState = MFS_UNCHECKED;
503  mii.wID = MI_time_ms;
504  mii.dwTypeData = "ms";
505  InsertMenuItem(_options_menu, GetMenuItemCount(_options_menu), TRUE, &mii);
506 
507  mii.wID = MI_time_hz;
508  mii.dwTypeData = "Hz";
509  InsertMenuItem(_options_menu, GetMenuItemCount(_options_menu), TRUE, &mii);
510 
511  set_time_units(PStatGraph::GBU_ms);
512 }
513 
514 /**
515  * Creates the "Speed" pulldown menu.
516  */
517 void WinStatsMonitor::
518 setup_speed_menu() {
519  _speed_menu = CreatePopupMenu();
520 
521  MENUITEMINFO mii;
522  memset(&mii, 0, sizeof(mii));
523  mii.cbSize = sizeof(mii);
524 
525  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
526  mii.fType = MFT_STRING;
527  mii.hSubMenu = _speed_menu;
528  mii.dwTypeData = "Speed";
529  InsertMenuItem(_menu_bar, GetMenuItemCount(_menu_bar), TRUE, &mii);
530 
531 
532  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_CHECKMARKS | MIIM_STATE;
533  mii.fType = MFT_STRING | MFT_RADIOCHECK;
534  mii.hbmpChecked = nullptr;
535  mii.hbmpUnchecked = nullptr;
536  mii.fState = MFS_UNCHECKED;
537  mii.wID = MI_speed_1;
538  mii.dwTypeData = "1";
539  InsertMenuItem(_speed_menu, GetMenuItemCount(_speed_menu), TRUE, &mii);
540 
541  mii.wID = MI_speed_2;
542  mii.dwTypeData = "2";
543  InsertMenuItem(_speed_menu, GetMenuItemCount(_speed_menu), TRUE, &mii);
544 
545  mii.wID = MI_speed_3;
546  mii.dwTypeData = "3";
547  InsertMenuItem(_speed_menu, GetMenuItemCount(_speed_menu), TRUE, &mii);
548 
549  mii.wID = MI_speed_6;
550  mii.dwTypeData = "6";
551  InsertMenuItem(_speed_menu, GetMenuItemCount(_speed_menu), TRUE, &mii);
552 
553  mii.wID = MI_speed_12;
554  mii.dwTypeData = "12";
555  InsertMenuItem(_speed_menu, GetMenuItemCount(_speed_menu), TRUE, &mii);
556 
557  mii.fMask = MIIM_FTYPE;
558  mii.fType = MFT_SEPARATOR;
559  InsertMenuItem(_speed_menu, GetMenuItemCount(_speed_menu), TRUE, &mii);
560 
561  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_CHECKMARKS | MIIM_STATE;
562  mii.fType = MFT_STRING;
563  mii.wID = MI_pause;
564  mii.dwTypeData = "pause";
565  InsertMenuItem(_speed_menu, GetMenuItemCount(_speed_menu), TRUE, &mii);
566 
567  set_scroll_speed(3);
568  set_pause(false);
569 }
570 
571 /**
572  * Creates the frame rate label on the right end of the menu bar. This is
573  * used as a text label to display the main thread's frame rate to the user,
574  * although it is implemented as a right-justified toplevel menu item that
575  * doesn't open to anything.
576  */
577 void WinStatsMonitor::
578 setup_frame_rate_label() {
579  MENUITEMINFO mii;
580  memset(&mii, 0, sizeof(mii));
581  mii.cbSize = sizeof(mii);
582 
583  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
584  mii.fType = MFT_STRING | MFT_RIGHTJUSTIFY;
585  mii.wID = MI_frame_rate_label;
586  mii.dwTypeData = "";
587  InsertMenuItem(_menu_bar, GetMenuItemCount(_menu_bar), TRUE, &mii);
588 }
589 
590 /**
591  * Registers the window class for the monitor window, if it has not already
592  * been registered.
593  */
594 void WinStatsMonitor::
595 register_window_class(HINSTANCE application) {
596  if (_window_class_registered) {
597  return;
598  }
599 
600  WNDCLASS wc;
601 
602  ZeroMemory(&wc, sizeof(WNDCLASS));
603  wc.style = 0;
604  wc.lpfnWndProc = (WNDPROC)static_window_proc;
605  wc.hInstance = application;
606  wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
607  wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
608  wc.lpszMenuName = nullptr;
609  wc.lpszClassName = _window_class_name;
610 
611  // Reserve space to associate the this pointer with the window.
612  wc.cbWndExtra = sizeof(WinStatsMonitor *);
613 
614  if (!RegisterClass(&wc)) {
615  nout << "Could not register monitor window class!\n";
616  exit(1);
617  }
618 
619  _window_class_registered = true;
620 }
621 
622 /**
623  *
624  */
625 LONG WINAPI WinStatsMonitor::
626 static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
627  WinStatsMonitor *self = (WinStatsMonitor *)GetWindowLongPtr(hwnd, 0);
628  if (self != nullptr && self->_window == hwnd) {
629  return self->window_proc(hwnd, msg, wparam, lparam);
630  } else {
631  return DefWindowProc(hwnd, msg, wparam, lparam);
632  }
633 }
634 
635 /**
636  *
637  */
638 LONG WinStatsMonitor::
639 window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
640  switch (msg) {
641  case WM_DESTROY:
642  close();
643  break;
644 
645  case WM_COMMAND:
646  if (HIWORD(wparam) <= 1) {
647  int menu_id = LOWORD(wparam);
648  handle_menu_command(menu_id);
649  return 0;
650  }
651  break;
652 
653  default:
654  break;
655  }
656 
657  return DefWindowProc(hwnd, msg, wparam, lparam);
658 }
659 
660 /**
661  *
662  */
663 void WinStatsMonitor::
664 handle_menu_command(int menu_id) {
665  switch (menu_id) {
666  case MI_none:
667  break;
668 
669  case MI_time_ms:
670  set_time_units(PStatGraph::GBU_ms);
671  break;
672 
673  case MI_time_hz:
674  set_time_units(PStatGraph::GBU_hz);
675  break;
676 
677  case MI_speed_1:
678  set_scroll_speed(1);
679  break;
680 
681  case MI_speed_2:
682  set_scroll_speed(2);
683  break;
684 
685  case MI_speed_3:
686  set_scroll_speed(3);
687  break;
688 
689  case MI_speed_6:
690  set_scroll_speed(6);
691  break;
692 
693  case MI_speed_12:
694  set_scroll_speed(12);
695  break;
696 
697  case MI_pause:
698  set_pause(!_pause);
699  break;
700 
701  default:
702  if (menu_id >= MI_new_chart) {
703  const MenuDef &menu_def = lookup_menu(menu_id);
704  if (menu_def._collector_index < 0) {
705  open_piano_roll(menu_def._thread_index);
706  } else {
707  open_strip_chart(menu_def._thread_index, menu_def._collector_index,
708  menu_def._show_level);
709  }
710  }
711  }
712 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
A window that draws a strip chart, given a view.
The class that owns the main loop, waiting for client connections.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_time_units(int unit_mask)
Called when the user selects a new time units from the monitor pulldown menu, this should adjust the ...
virtual void set_scroll_speed(double scroll_speed)
Called when the user selects a new scroll speed from the monitor pulldown menu, this should adjust th...
void close()
Closes the client connection if it is active.
virtual void new_thread(int thread_index)
Called whenever a new Thread definition is received from the client.
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
virtual void set_time_units(int unit_mask)
Called when the user selects a new time units from the monitor pulldown menu, this should adjust the ...
void user_guide_bars_changed()
Called when the user guide bars have been changed.
std::string get_client_hostname() const
Returns the hostname of the client we're connected to, if known.
Definition: pStatMonitor.I:58
void open_strip_chart(int thread_index, int collector_index, bool show_level)
Opens a new strip chart showing the indicated data.
virtual void lost_connection()
Called whenever the connection to the client has been lost.
virtual bool has_idle()
Should be redefined to return true if you want to redefine idle() and expect it to be called.
void set_scroll_speed(double scroll_speed)
Called when the user selects a new scroll speed from the monitor pulldown menu, this should adjust th...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void set_time_units(int unit_mask)
Called when the user selects a new time units from the monitor pulldown menu, this should adjust the ...
This is an abstract class that presents the interface to any number of different front-ends for the s...
Definition: pStatMonitor.h:39
virtual void set_scroll_speed(double scroll_speed)
Called when the user selects a new scroll speed from the monitor pulldown menu, this should adjust th...
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
Definition: winStatsGraph.h:29
virtual void got_bad_version(int client_major, int client_minor, int server_major, int server_minor)
Like got_hello(), this is called when the "hello" message has been received from the client.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_pause(bool pause)
Called when the user selects a pause on or pause off option from the menu.
virtual void initialized()
Called after the monitor has been fully set up.
double get_frame_rate() const
Computes the average frame rate over the past pstats_average_time seconds, by counting up the number ...
A pulldown menu of charts available for a particular thread.
std::string get_client_progname() const
Returns the program name of the client we're connected to, if known.
Definition: pStatMonitor.I:69
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
virtual void set_time_units(int unit_mask)
Called when the user selects a new time units from the monitor pulldown menu, this should adjust the ...
void add_to_menu_bar(HMENU menu_bar, int before_menu_id)
Adds the menu to the end of the indicated menu bar.
A collection of FrameData structures for recently-received frames within a particular thread.
This class represents a connection to a PStatsClient and manages the data exchange with the client.
virtual std::string get_monitor_name()
Should be redefined to return a descriptive name for the type of PStatsMonitor this is.
const PStatThreadData * get_thread_data(int index) const
Returns the data associated with the indicated thread.
void set_pause(bool pause)
Changes the pause flag for the graph.
A window that draws a piano-roll style chart, which shows the collectors explicitly stopping and star...
virtual void idle()
If has_idle() returns true, this will be called periodically to allow the monitor to update its displ...
virtual void new_data(int thread_index, int frame_number)
Called whenever new data arrives.
const MenuDef & lookup_menu(int menu_id) const
Returns the MenuDef properties associated with the indicated menu ID.
int get_menu_id(const MenuDef &menu_def)
Returns the menu ID that is reserved for the indicated MenuDef properties.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void open_piano_roll(int thread_index)
Opens a new piano roll showing the indicated data.
virtual void user_guide_bars_changed()
Called when the user guide bars have been changed.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
Definition: pStatMonitor.I:26
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
HWND get_window() const
Returns the window handle to the monitor's window.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void got_hello()
Called when the "hello" message has been received from the client.