Panda3D
 All Classes Functions Variables Enumerations
winStatsChartMenu.cxx
00001 // Filename: winStatsChartMenu.cxx
00002 // Created by:  drose (08Jan04)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "winStatsChartMenu.h"
00016 #include "winStatsMonitor.h"
00017 
00018 ////////////////////////////////////////////////////////////////////
00019 //     Function: WinStatsChartMenu::Constructor
00020 //       Access: Public
00021 //  Description:
00022 ////////////////////////////////////////////////////////////////////
00023 WinStatsChartMenu::
00024 WinStatsChartMenu(WinStatsMonitor *monitor, int thread_index) :
00025   _monitor(monitor),
00026   _thread_index(thread_index)
00027 {
00028   _menu = CreatePopupMenu();
00029   do_update();
00030 }
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //     Function: WinStatsChartMenu::Destructor
00034 //       Access: Public
00035 //  Description:
00036 ////////////////////////////////////////////////////////////////////
00037 WinStatsChartMenu::
00038 ~WinStatsChartMenu() {
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: WinStatsChartMenu::get_menu_handle
00043 //       Access: Public
00044 //  Description: Returns the Windows menu handle for this particular
00045 //               menu.
00046 ////////////////////////////////////////////////////////////////////
00047 HMENU WinStatsChartMenu::
00048 get_menu_handle() {
00049   return _menu;
00050 }
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: WinStatsChartMenu::add_to_menu_bar
00054 //       Access: Public
00055 //  Description: Adds the menu to the end of the indicated menu bar.
00056 ////////////////////////////////////////////////////////////////////
00057 void WinStatsChartMenu::
00058 add_to_menu_bar(HMENU menu_bar, int before_menu_id) {
00059   const PStatClientData *client_data = _monitor->get_client_data();
00060   string thread_name;
00061   if (_thread_index == 0) {
00062     // A special case for the main thread.
00063     thread_name = "Graphs";
00064   } else {
00065     thread_name = client_data->get_thread_name(_thread_index);
00066   }
00067 
00068   MENUITEMINFO mii;
00069   memset(&mii, 0, sizeof(mii));
00070   mii.cbSize = sizeof(mii);
00071 
00072   mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU; 
00073   mii.fType = MFT_STRING; 
00074   mii.hSubMenu = _menu; 
00075   mii.dwTypeData = (char *)thread_name.c_str(); 
00076   InsertMenuItem(menu_bar, before_menu_id, FALSE, &mii);
00077 }
00078 
00079 ////////////////////////////////////////////////////////////////////
00080 //     Function: WinStatsChartMenu::check_update
00081 //       Access: Public
00082 //  Description: Checks to see if the menu needs to be updated
00083 //               (e.g. because of new data from the client), and
00084 //               updates it if necessary.
00085 ////////////////////////////////////////////////////////////////////
00086 void WinStatsChartMenu::
00087 check_update() {
00088   PStatView &view = _monitor->get_view(_thread_index);
00089   if (view.get_level_index() != _last_level_index) {
00090     do_update();
00091   }
00092 }
00093  
00094 ////////////////////////////////////////////////////////////////////
00095 //     Function: WinStatsChartMenu::do_update
00096 //       Access: Public
00097 //  Description: Unconditionally updates the menu with the latest data
00098 //               from the client.
00099 ////////////////////////////////////////////////////////////////////
00100 void WinStatsChartMenu::
00101 do_update() {
00102   PStatView &view = _monitor->get_view(_thread_index);
00103   _last_level_index = view.get_level_index();
00104 
00105   // First, remove all of the old entries from the menu.
00106   int num_items = GetMenuItemCount(_menu);
00107   for (int i = num_items - 1; i >= 0; i--) {
00108     DeleteMenu(_menu, i, MF_BYPOSITION);
00109   }
00110 
00111   // Now rebuild the menu with the new set of entries.
00112 
00113   // The menu item(s) for the thread's frame time goes first.
00114   add_view(_menu, view.get_top_level(), false);
00115 
00116   bool needs_separator = true;
00117   MENUITEMINFO mii;
00118   memset(&mii, 0, sizeof(mii));
00119   mii.cbSize = sizeof(mii);
00120 
00121   // And then the menu item(s) for each of the level values.
00122   const PStatClientData *client_data = _monitor->get_client_data();
00123   int num_toplevel_collectors = client_data->get_num_toplevel_collectors();
00124   for (int tc = 0; tc < num_toplevel_collectors; tc++) {
00125     int collector = client_data->get_toplevel_collector(tc);
00126     if (client_data->has_collector(collector) && 
00127         client_data->get_collector_has_level(collector, _thread_index)) {
00128 
00129       // We put a separator between the above frame collector and the
00130       // first level collector.
00131       if (needs_separator) {
00132         mii.fMask = MIIM_FTYPE; 
00133         mii.fType = MFT_SEPARATOR; 
00134         InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
00135 
00136         needs_separator = false;
00137       }
00138 
00139       PStatView &level_view = _monitor->get_level_view(collector, _thread_index);
00140       add_view(_menu, level_view.get_top_level(), true);
00141     }
00142   }
00143 
00144   // Also a menu item for a piano roll (following a separator).
00145   mii.fMask = MIIM_FTYPE; 
00146   mii.fType = MFT_SEPARATOR; 
00147   InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
00148 
00149   WinStatsMonitor::MenuDef menu_def(_thread_index, -1, false);
00150   int menu_id = _monitor->get_menu_id(menu_def);
00151 
00152   mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID; 
00153   mii.fType = MFT_STRING; 
00154   mii.wID = menu_id;
00155   mii.dwTypeData = "Piano Roll";
00156   InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
00157 }
00158 
00159 ////////////////////////////////////////////////////////////////////
00160 //     Function: WinStatsChartMenu::add_view
00161 //       Access: Private
00162 //  Description: Adds a new entry or entries to the menu for the
00163 //               indicated view and its children.
00164 ////////////////////////////////////////////////////////////////////
00165 void WinStatsChartMenu::
00166 add_view(HMENU parent_menu, const PStatViewLevel *view_level, bool show_level) {
00167   int collector = view_level->get_collector();
00168 
00169   const PStatClientData *client_data = _monitor->get_client_data();
00170   string collector_name = client_data->get_collector_name(collector);
00171 
00172   WinStatsMonitor::MenuDef menu_def(_thread_index, collector, show_level);
00173   int menu_id = _monitor->get_menu_id(menu_def);
00174 
00175   MENUITEMINFO mii;
00176   memset(&mii, 0, sizeof(mii));
00177   mii.cbSize = sizeof(mii);
00178 
00179   mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID; 
00180   mii.fType = MFT_STRING; 
00181   mii.wID = menu_id;
00182   mii.dwTypeData = (char *)collector_name.c_str(); 
00183   InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
00184 
00185   int num_children = view_level->get_num_children();
00186   if (num_children > 1) {
00187     // If the collector has more than one child, add a menu entry to go
00188     // directly to each of its children.
00189     HMENU submenu = CreatePopupMenu();
00190     string submenu_name = collector_name + " components";
00191 
00192     mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
00193     mii.fType = MFT_STRING; 
00194     mii.hSubMenu = submenu;
00195     mii.dwTypeData = (char *)submenu_name.c_str(); 
00196     InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
00197 
00198     // Reverse the order since the menus are listed from the top down;
00199     // we want to be visually consistent with the graphs, which list
00200     // these labels from the bottom up.
00201     for (int c = num_children - 1; c >= 0; c--) {
00202       add_view(submenu, view_level->get_child(c), show_level);
00203     }
00204   }
00205 }
 All Classes Functions Variables Enumerations