Panda3D
winStatsChartMenu.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 winStatsChartMenu.cxx
10  * @author drose
11  * @date 2004-01-08
12  */
13 
14 #include "winStatsChartMenu.h"
15 #include "winStatsMonitor.h"
16 
17 /**
18  *
19  */
20 WinStatsChartMenu::
21 WinStatsChartMenu(WinStatsMonitor *monitor, int thread_index) :
22  _monitor(monitor),
23  _thread_index(thread_index)
24 {
25  _menu = CreatePopupMenu();
26  do_update();
27 }
28 
29 /**
30  *
31  */
32 WinStatsChartMenu::
33 ~WinStatsChartMenu() {
34 }
35 
36 /**
37  * Returns the Windows menu handle for this particular menu.
38  */
41  return _menu;
42 }
43 
44 /**
45  * Adds the menu to the end of the indicated menu bar.
46  */
48 add_to_menu_bar(HMENU menu_bar, int before_menu_id) {
49  const PStatClientData *client_data = _monitor->get_client_data();
50  std::string thread_name;
51  if (_thread_index == 0) {
52  // A special case for the main thread.
53  thread_name = "Graphs";
54  } else {
55  thread_name = client_data->get_thread_name(_thread_index);
56  }
57 
58  MENUITEMINFO mii;
59  memset(&mii, 0, sizeof(mii));
60  mii.cbSize = sizeof(mii);
61 
62  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
63  mii.fType = MFT_STRING;
64  mii.hSubMenu = _menu;
65  mii.dwTypeData = (char *)thread_name.c_str();
66  InsertMenuItem(menu_bar, before_menu_id, FALSE, &mii);
67 }
68 
69 /**
70  * Checks to see if the menu needs to be updated (e.g. because of new data
71  * from the client), and updates it if necessary.
72  */
75  PStatView &view = _monitor->get_view(_thread_index);
76  if (view.get_level_index() != _last_level_index) {
77  do_update();
78  }
79 }
80 
81 /**
82  * Unconditionally updates the menu with the latest data from the client.
83  */
86  PStatView &view = _monitor->get_view(_thread_index);
87  _last_level_index = view.get_level_index();
88 
89  // First, remove all of the old entries from the menu.
90  int num_items = GetMenuItemCount(_menu);
91  for (int i = num_items - 1; i >= 0; i--) {
92  DeleteMenu(_menu, i, MF_BYPOSITION);
93  }
94 
95  // Now rebuild the menu with the new set of entries.
96 
97  // The menu item(s) for the thread's frame time goes first.
98  add_view(_menu, view.get_top_level(), false);
99 
100  bool needs_separator = true;
101  MENUITEMINFO mii;
102  memset(&mii, 0, sizeof(mii));
103  mii.cbSize = sizeof(mii);
104 
105  // And then the menu item(s) for each of the level values.
106  const PStatClientData *client_data = _monitor->get_client_data();
107  int num_toplevel_collectors = client_data->get_num_toplevel_collectors();
108  for (int tc = 0; tc < num_toplevel_collectors; tc++) {
109  int collector = client_data->get_toplevel_collector(tc);
110  if (client_data->has_collector(collector) &&
111  client_data->get_collector_has_level(collector, _thread_index)) {
112 
113  // We put a separator between the above frame collector and the first
114  // level collector.
115  if (needs_separator) {
116  mii.fMask = MIIM_FTYPE;
117  mii.fType = MFT_SEPARATOR;
118  InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
119 
120  needs_separator = false;
121  }
122 
123  PStatView &level_view = _monitor->get_level_view(collector, _thread_index);
124  add_view(_menu, level_view.get_top_level(), true);
125  }
126  }
127 
128  // Also a menu item for a piano roll (following a separator).
129  mii.fMask = MIIM_FTYPE;
130  mii.fType = MFT_SEPARATOR;
131  InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
132 
133  WinStatsMonitor::MenuDef menu_def(_thread_index, -1, false);
134  int menu_id = _monitor->get_menu_id(menu_def);
135 
136  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
137  mii.fType = MFT_STRING;
138  mii.wID = menu_id;
139  mii.dwTypeData = "Piano Roll";
140  InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
141 }
142 
143 /**
144  * Adds a new entry or entries to the menu for the indicated view and its
145  * children.
146  */
147 void WinStatsChartMenu::
148 add_view(HMENU parent_menu, const PStatViewLevel *view_level, bool show_level) {
149  int collector = view_level->get_collector();
150 
151  const PStatClientData *client_data = _monitor->get_client_data();
152  std::string collector_name = client_data->get_collector_name(collector);
153 
154  WinStatsMonitor::MenuDef menu_def(_thread_index, collector, show_level);
155  int menu_id = _monitor->get_menu_id(menu_def);
156 
157  MENUITEMINFO mii;
158  memset(&mii, 0, sizeof(mii));
159  mii.cbSize = sizeof(mii);
160 
161  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
162  mii.fType = MFT_STRING;
163  mii.wID = menu_id;
164  mii.dwTypeData = (char *)collector_name.c_str();
165  InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
166 
167  int num_children = view_level->get_num_children();
168  if (num_children > 1) {
169  // If the collector has more than one child, add a menu entry to go
170  // directly to each of its children.
171  HMENU submenu = CreatePopupMenu();
172  std::string submenu_name = collector_name + " components";
173 
174  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
175  mii.fType = MFT_STRING;
176  mii.hSubMenu = submenu;
177  mii.dwTypeData = (char *)submenu_name.c_str();
178  InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
179 
180  // Reverse the order since the menus are listed from the top down; we want
181  // to be visually consistent with the graphs, which list these labels from
182  // the bottom up.
183  for (int c = num_children - 1; c >= 0; c--) {
184  add_view(submenu, view_level->get_child(c), show_level);
185  }
186  }
187 }
const PStatViewLevel * get_top_level()
Returns a pointer to the level that corresponds to the Collector we've constrained to.
Definition: pStatView.cxx:239
int get_toplevel_collector(int index) const
Returns the collector index of the nth toplevel collector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PStatView & get_level_view(int collector_index, int thread_index)
Returns a view on the level value (as opposed to elapsed time) for the given collector over the given...
const PStatViewLevel * get_child(int n) const
Returns the nth child of this Level/Collector.
The data associated with a particular client, but not with any one particular frame or thread: the li...
void check_update()
Checks to see if the menu needs to be updated (e.g.
std::string get_collector_name(int index) const
Returns the name of the indicated collector.
This is a single level value, or band of color, within a View.
bool has_collector(int index) const
Returns true if the indicated collector has been defined by the client already, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A View boils down the frame data to a linear list of times spent in a number of different Collectors,...
Definition: pStatView.h:31
PStatView & get_view(int thread_index)
Returns a view on the given thread index.
void do_update()
Unconditionally updates the menu with the latest data from the client.
void add_to_menu_bar(HMENU menu_bar, int before_menu_id)
Adds the menu to the end of the indicated menu bar.
This class represents a connection to a PStatsClient and manages the data exchange with the client.
int get_collector() const
Returns the Collector index associated with this level.
int get_menu_id(const MenuDef &menu_def)
Returns the menu ID that is reserved for the indicated MenuDef properties.
HMENU get_menu_handle()
Returns the Windows menu handle for this particular menu.
int get_level_index() const
Returns an index number that can be used to determine when the set of known levels has changed.
Definition: pStatView.I:68
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
Definition: pStatMonitor.I:26
int get_num_children() const
Returns the number of children of this Level/Collector.
int get_num_toplevel_collectors() const
Returns the total number of collectors that are toplevel collectors.
std::string get_thread_name(int index) const
Returns the name of the indicated thread.
bool get_collector_has_level(int index, int thread_index) const
Returns whether the given collector has level data (and consequently, whether it should appear on the...