188 lines
5.4 KiB
C++
188 lines
5.4 KiB
C++
/**
|
|
* PANDA 3D SOFTWARE
|
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
*
|
|
* All use of this software is subject to the terms of the revised BSD
|
|
* license. You should have received a copy of this license along
|
|
* with this source code in a file named "LICENSE."
|
|
*
|
|
* @file winStatsChartMenu.cxx
|
|
* @author drose
|
|
* @date 2004-01-08
|
|
*/
|
|
|
|
#include "winStatsChartMenu.h"
|
|
#include "winStatsMonitor.h"
|
|
|
|
/**
|
|
*
|
|
*/
|
|
WinStatsChartMenu::
|
|
WinStatsChartMenu(WinStatsMonitor *monitor, int thread_index) :
|
|
_monitor(monitor),
|
|
_thread_index(thread_index)
|
|
{
|
|
_menu = CreatePopupMenu();
|
|
do_update();
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
WinStatsChartMenu::
|
|
~WinStatsChartMenu() {
|
|
}
|
|
|
|
/**
|
|
* Returns the Windows menu handle for this particular menu.
|
|
*/
|
|
HMENU WinStatsChartMenu::
|
|
get_menu_handle() {
|
|
return _menu;
|
|
}
|
|
|
|
/**
|
|
* Adds the menu to the end of the indicated menu bar.
|
|
*/
|
|
void WinStatsChartMenu::
|
|
add_to_menu_bar(HMENU menu_bar, int before_menu_id) {
|
|
const PStatClientData *client_data = _monitor->get_client_data();
|
|
std::string thread_name;
|
|
if (_thread_index == 0) {
|
|
// A special case for the main thread.
|
|
thread_name = "Graphs";
|
|
} else {
|
|
thread_name = client_data->get_thread_name(_thread_index);
|
|
}
|
|
|
|
MENUITEMINFO mii;
|
|
memset(&mii, 0, sizeof(mii));
|
|
mii.cbSize = sizeof(mii);
|
|
|
|
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
|
|
mii.fType = MFT_STRING;
|
|
mii.hSubMenu = _menu;
|
|
mii.dwTypeData = (char *)thread_name.c_str();
|
|
InsertMenuItem(menu_bar, before_menu_id, FALSE, &mii);
|
|
}
|
|
|
|
/**
|
|
* Checks to see if the menu needs to be updated (e.g. because of new data
|
|
* from the client), and updates it if necessary.
|
|
*/
|
|
void WinStatsChartMenu::
|
|
check_update() {
|
|
PStatView &view = _monitor->get_view(_thread_index);
|
|
if (view.get_level_index() != _last_level_index) {
|
|
do_update();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unconditionally updates the menu with the latest data from the client.
|
|
*/
|
|
void WinStatsChartMenu::
|
|
do_update() {
|
|
PStatView &view = _monitor->get_view(_thread_index);
|
|
_last_level_index = view.get_level_index();
|
|
|
|
// First, remove all of the old entries from the menu.
|
|
int num_items = GetMenuItemCount(_menu);
|
|
for (int i = num_items - 1; i >= 0; i--) {
|
|
DeleteMenu(_menu, i, MF_BYPOSITION);
|
|
}
|
|
|
|
// Now rebuild the menu with the new set of entries.
|
|
|
|
// The menu item(s) for the thread's frame time goes first.
|
|
add_view(_menu, view.get_top_level(), false);
|
|
|
|
bool needs_separator = true;
|
|
MENUITEMINFO mii;
|
|
memset(&mii, 0, sizeof(mii));
|
|
mii.cbSize = sizeof(mii);
|
|
|
|
// And then the menu item(s) for each of the level values.
|
|
const PStatClientData *client_data = _monitor->get_client_data();
|
|
int num_toplevel_collectors = client_data->get_num_toplevel_collectors();
|
|
for (int tc = 0; tc < num_toplevel_collectors; tc++) {
|
|
int collector = client_data->get_toplevel_collector(tc);
|
|
if (client_data->has_collector(collector) &&
|
|
client_data->get_collector_has_level(collector, _thread_index)) {
|
|
|
|
// We put a separator between the above frame collector and the first
|
|
// level collector.
|
|
if (needs_separator) {
|
|
mii.fMask = MIIM_FTYPE;
|
|
mii.fType = MFT_SEPARATOR;
|
|
InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
|
|
|
|
needs_separator = false;
|
|
}
|
|
|
|
PStatView &level_view = _monitor->get_level_view(collector, _thread_index);
|
|
add_view(_menu, level_view.get_top_level(), true);
|
|
}
|
|
}
|
|
|
|
// Also a menu item for a piano roll (following a separator).
|
|
mii.fMask = MIIM_FTYPE;
|
|
mii.fType = MFT_SEPARATOR;
|
|
InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
|
|
|
|
WinStatsMonitor::MenuDef menu_def(_thread_index, -1, false);
|
|
int menu_id = _monitor->get_menu_id(menu_def);
|
|
|
|
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
|
|
mii.fType = MFT_STRING;
|
|
mii.wID = menu_id;
|
|
mii.dwTypeData = "Piano Roll";
|
|
InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
|
|
}
|
|
|
|
/**
|
|
* Adds a new entry or entries to the menu for the indicated view and its
|
|
* children.
|
|
*/
|
|
void WinStatsChartMenu::
|
|
add_view(HMENU parent_menu, const PStatViewLevel *view_level, bool show_level) {
|
|
int collector = view_level->get_collector();
|
|
|
|
const PStatClientData *client_data = _monitor->get_client_data();
|
|
std::string collector_name = client_data->get_collector_name(collector);
|
|
|
|
WinStatsMonitor::MenuDef menu_def(_thread_index, collector, show_level);
|
|
int menu_id = _monitor->get_menu_id(menu_def);
|
|
|
|
MENUITEMINFO mii;
|
|
memset(&mii, 0, sizeof(mii));
|
|
mii.cbSize = sizeof(mii);
|
|
|
|
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
|
|
mii.fType = MFT_STRING;
|
|
mii.wID = menu_id;
|
|
mii.dwTypeData = (char *)collector_name.c_str();
|
|
InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
|
|
|
|
int num_children = view_level->get_num_children();
|
|
if (num_children > 1) {
|
|
// If the collector has more than one child, add a menu entry to go
|
|
// directly to each of its children.
|
|
HMENU submenu = CreatePopupMenu();
|
|
std::string submenu_name = collector_name + " components";
|
|
|
|
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
|
|
mii.fType = MFT_STRING;
|
|
mii.hSubMenu = submenu;
|
|
mii.dwTypeData = (char *)submenu_name.c_str();
|
|
InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
|
|
|
|
// Reverse the order since the menus are listed from the top down; we want
|
|
// to be visually consistent with the graphs, which list these labels from
|
|
// the bottom up.
|
|
for (int c = num_children - 1; c >= 0; c--) {
|
|
add_view(submenu, view_level->get_child(c), show_level);
|
|
}
|
|
}
|
|
}
|