Panda3D
Loading...
Searching...
No Matches
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
24bool WinStatsMonitor::_window_class_registered = false;
25const char * const WinStatsMonitor::_window_class_name = "monitor";
26
27/**
28 *
29 */
30WinStatsMonitor::
31WinStatsMonitor(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 */
45WinStatsMonitor::
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 */
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 */
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 */
95got_hello() {
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 */
108got_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 */
137new_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 */
159new_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 */
173new_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 */
202idle() {
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 */
231has_idle() {
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);
244 }
245}
246
247/**
248 * Returns the window handle to the monitor's window.
249 */
251get_window() const {
252 return _window;
253}
254
255/**
256 * Opens a new strip chart showing the indicated data.
257 */
259open_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 */
273open_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 */
287lookup_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 */
300get_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 */
321set_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 */
351set_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 */
392set_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 */
415void WinStatsMonitor::
416add_graph(WinStatsGraph *graph) {
417 _graphs.insert(graph);
418}
419
420/**
421 * Deletes the indicated graph.
422 */
423void WinStatsMonitor::
424remove_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 */
435void WinStatsMonitor::
436create_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 */
479void WinStatsMonitor::
480setup_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 */
517void WinStatsMonitor::
518setup_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
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 */
577void WinStatsMonitor::
578setup_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 */
594void WinStatsMonitor::
595register_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 */
625LONG WINAPI WinStatsMonitor::
626static_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 */
638LONG WinStatsMonitor::
639window_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 */
663void WinStatsMonitor::
664handle_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:
679 break;
680
681 case MI_speed_2:
683 break;
684
685 case MI_speed_3:
687 break;
688
689 case MI_speed_6:
691 break;
692
693 case MI_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}
const PStatThreadData * get_thread_data(int index) const
Returns the data associated with the indicated thread.
This is an abstract class that presents the interface to any number of different front-ends for the s...
std::string get_client_progname() const
Returns the program name of the client we're connected to, if known.
std::string get_client_hostname() const
Returns the hostname of the client we're connected to, if known.
void close()
Closes the client connection if it is active.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
A collection of FrameData structures for recently-received frames within a particular thread.
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.
void add_to_menu_bar(HMENU menu_bar, int before_menu_id)
Adds the menu to the end of the indicated menu bar.
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
void set_pause(bool pause)
Changes the pause flag for the graph.
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...
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 ...
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
void user_guide_bars_changed()
Called when the user guide bars have been changed.
virtual void new_data(int thread_index, int frame_number)
Called whenever new data arrives.
This class represents a connection to a PStatsClient and manages the data exchange with the client.
virtual bool has_idle()
Should be redefined to return true if you want to redefine idle() and expect it to be called.
void open_strip_chart(int thread_index, int collector_index, bool show_level)
Opens a new strip chart showing the indicated data.
int get_menu_id(const MenuDef &menu_def)
Returns the menu ID that is reserved for the indicated MenuDef properties.
void set_pause(bool pause)
Called when the user selects a pause on or pause off option from the menu.
virtual void got_hello()
Called when the "hello" message has been received from the client.
virtual void idle()
If has_idle() returns true, this will be called periodically to allow the monitor to update its displ...
virtual void user_guide_bars_changed()
Called when the user guide bars have been changed.
virtual std::string get_monitor_name()
Should be redefined to return a descriptive name for the type of PStatsMonitor this is.
HWND get_window() const
Returns the window handle to the monitor's window.
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.
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
virtual void initialized()
Called after the monitor has been fully set up.
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
virtual void new_thread(int thread_index)
Called whenever a new Thread definition is received from the client.
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 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 open_piano_roll(int thread_index)
Opens a new piano roll showing the indicated data.
const MenuDef & lookup_menu(int menu_id) const
Returns the MenuDef properties associated with the indicated menu ID.
virtual void lost_connection()
Called whenever the connection to the client has been lost.
A window that draws a piano-roll style chart, which shows the collectors explicitly stopping and star...
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 ...
The class that owns the main loop, waiting for client connections.
A window that draws a strip chart, given a view.
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...
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 ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.