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