00001 // Filename: gtkStatsMonitor.cxx 00002 // Created by: drose (14Jul00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "gtkStatsMonitor.h" 00020 #include "gtkStatsWindow.h" 00021 #include "gtkStatsStripWindow.h" 00022 #include "gtkStatsBadVersionWindow.h" 00023 00024 #include <luse.h> 00025 #include <pStatCollectorDef.h> 00026 00027 #include <gdk--.h> 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: GtkStatsMonitor::Constructor 00031 // Access: Public 00032 // Description: 00033 //////////////////////////////////////////////////////////////////// 00034 GtkStatsMonitor:: 00035 GtkStatsMonitor() { 00036 _destructing = false; 00037 _new_collector = false; 00038 } 00039 00040 //////////////////////////////////////////////////////////////////// 00041 // Function: GtkStatsMonitor::Destructor 00042 // Access: Public 00043 // Description: 00044 //////////////////////////////////////////////////////////////////// 00045 GtkStatsMonitor:: 00046 ~GtkStatsMonitor() { 00047 _destructing = true; 00048 00049 Windows::iterator wi; 00050 for (wi = _windows.begin(); wi != _windows.end(); ++wi) { 00051 GtkStatsWindow *window = (*wi); 00052 window->destruct(); 00053 } 00054 } 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Function: GtkStatsMonitor::close_all_windows 00058 // Access: Public 00059 // Description: Closes all the windows associated with this client. 00060 // This returns a PointerTo itself, just to guarantee 00061 // that the monitor won't destruct until the function 00062 // returns (as it might, if there were no other pointers 00063 // to it). 00064 //////////////////////////////////////////////////////////////////// 00065 PT(PStatMonitor) GtkStatsMonitor:: 00066 close_all_windows() { 00067 PT(PStatMonitor) temp = this; 00068 Windows::iterator wi; 00069 for (wi = _windows.begin(); wi != _windows.end(); ++wi) { 00070 GtkStatsWindow *window = (*wi); 00071 window->destruct(); 00072 } 00073 return temp; 00074 } 00075 00076 //////////////////////////////////////////////////////////////////// 00077 // Function: GtkStatsMonitor::get_monitor_name 00078 // Access: Public, Virtual 00079 // Description: Should be redefined to return a descriptive name for 00080 // the type of PStatsMonitor this is. 00081 //////////////////////////////////////////////////////////////////// 00082 string GtkStatsMonitor:: 00083 get_monitor_name() { 00084 return "Gtk Stats"; 00085 } 00086 00087 //////////////////////////////////////////////////////////////////// 00088 // Function: GtkStatsMonitor::initialized 00089 // Access: Public, Virtual 00090 // Description: Called after the monitor has been fully set up. At 00091 // this time, it will have a valid _client_data pointer, 00092 // and things like is_alive() and close() will be 00093 // meaningful. However, we may not yet know who we're 00094 // connected to (is_client_known() may return false), 00095 // and we may not know anything about the threads or 00096 // collectors we're about to get data on. 00097 //////////////////////////////////////////////////////////////////// 00098 void GtkStatsMonitor:: 00099 initialized() { 00100 // Create a default window: a strip chart for the main thread. 00101 new GtkStatsStripWindow(this, 0, 0, false, 400, 100); 00102 } 00103 00104 //////////////////////////////////////////////////////////////////// 00105 // Function: GtkStatsMonitor::got_hello 00106 // Access: Public, Virtual 00107 // Description: Called when the "hello" message has been received 00108 // from the client. At this time, the client's hostname 00109 // and program name will be known. 00110 //////////////////////////////////////////////////////////////////// 00111 void GtkStatsMonitor:: 00112 got_hello() { 00113 Windows::iterator wi; 00114 for (wi = _windows.begin(); wi != _windows.end(); ++wi) { 00115 (*wi)->update_title(); 00116 } 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: GtkStatsMonitor::got_bad_version 00121 // Access: Public, Virtual 00122 // Description: Like got_hello(), this is called when the "hello" 00123 // message has been received from the client. At this 00124 // time, the client's hostname and program name will be 00125 // known. However, the client appears to be an 00126 // incompatible version and the connection will be 00127 // terminated; the monitor should issue a message to 00128 // that effect. 00129 //////////////////////////////////////////////////////////////////// 00130 void GtkStatsMonitor:: 00131 got_bad_version(int client_major, int client_minor, 00132 int server_major, int server_minor) { 00133 new GtkStatsBadVersionWindow(this, client_major, client_minor, 00134 server_major, server_minor); 00135 close_all_windows(); 00136 } 00137 00138 //////////////////////////////////////////////////////////////////// 00139 // Function: GtkStatsMonitor::new_collector 00140 // Access: Public, Virtual 00141 // Description: Called whenever a new Collector definition is 00142 // received from the client. Generally, the client will 00143 // send all of its collectors over shortly after 00144 // connecting, but there's no guarantee that they will 00145 // all be received before the first frames are received. 00146 // The monitor should be prepared to accept new Collector 00147 // definitions midstream. 00148 //////////////////////////////////////////////////////////////////// 00149 void GtkStatsMonitor:: 00150 new_collector(int) { 00151 _new_collector = true; 00152 } 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Function: GtkStatsMonitor::new_data 00156 // Access: Public, Virtual 00157 // Description: Called as each frame's data is made available. There 00158 // is no gurantee the frames will arrive in order, or 00159 // that all of them will arrive at all. The monitor 00160 // should be prepared to accept frames received 00161 // out-of-order or missing. 00162 //////////////////////////////////////////////////////////////////// 00163 void GtkStatsMonitor:: 00164 new_data(int thread_index, int frame_number) { 00165 } 00166 00167 00168 //////////////////////////////////////////////////////////////////// 00169 // Function: GtkStatsMonitor::lost_connection 00170 // Access: Public, Virtual 00171 // Description: Called whenever the connection to the client has been 00172 // lost. This is a permanent state change. The monitor 00173 // should update its display to represent this, and may 00174 // choose to close down automatically. 00175 //////////////////////////////////////////////////////////////////// 00176 void GtkStatsMonitor:: 00177 lost_connection() { 00178 Windows::iterator wi; 00179 for (wi = _windows.begin(); wi != _windows.end(); ++wi) { 00180 (*wi)->mark_dead(); 00181 } 00182 } 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // Function: GtkStatsMonitor::idle 00186 // Access: Public, Virtual 00187 // Description: If has_idle() returns true, this will be called 00188 // periodically to allow the monitor to update its 00189 // display or whatever it needs to do. 00190 //////////////////////////////////////////////////////////////////// 00191 void GtkStatsMonitor:: 00192 idle() { 00193 Windows::iterator wi; 00194 for (wi = _windows.begin(); wi != _windows.end(); ++wi) { 00195 (*wi)->idle(); 00196 } 00197 _new_collector = false; 00198 } 00199 00200 //////////////////////////////////////////////////////////////////// 00201 // Function: GtkStatsMonitor::has_idle 00202 // Access: Public, Virtual 00203 // Description: Should be redefined to return true if you want to 00204 // redefine idle() and expect it to be called. 00205 //////////////////////////////////////////////////////////////////// 00206 bool GtkStatsMonitor:: 00207 has_idle() { 00208 return true; 00209 } 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: GtkStatsMonitor::is_thread_safe 00213 // Access: Public, Virtual 00214 // Description: Should be redefined to return true if this monitor 00215 // class can handle running in a sub-thread. 00216 // 00217 // This is not related to the question of whether it can 00218 // handle multiple different PStatThreadDatas; this is 00219 // strictly a question of whether or not the monitor 00220 // itself wants to run in a sub-thread. 00221 //////////////////////////////////////////////////////////////////// 00222 bool GtkStatsMonitor:: 00223 is_thread_safe() { 00224 return true; 00225 } 00226 00227 //////////////////////////////////////////////////////////////////// 00228 // Function: GtkStatsMonitor::add_window 00229 // Access: Public 00230 // Description: Called only from the GtkStatsWindow constructor, this 00231 // indicates a new window that we should track. 00232 //////////////////////////////////////////////////////////////////// 00233 void GtkStatsMonitor:: 00234 add_window(GtkStatsWindow *window) { 00235 nassertv(!_destructing); 00236 bool inserted = _windows.insert(window).second; 00237 nassertv(inserted); 00238 } 00239 00240 //////////////////////////////////////////////////////////////////// 00241 // Function: GtkStatsMonitor::remove_window 00242 // Access: Public 00243 // Description: Called only from the GtkStatsWindow destructor, this 00244 // indicates the end of a window that we should now no 00245 // longer track. 00246 // 00247 // When the last window is deleted, this automatically 00248 // closes the connection. 00249 //////////////////////////////////////////////////////////////////// 00250 void GtkStatsMonitor:: 00251 remove_window(GtkStatsWindow *window) { 00252 if (!_destructing) { 00253 bool removed = (_windows.erase(window) != 0); 00254 nassertv(removed); 00255 00256 if (_windows.empty()) { 00257 close(); 00258 } 00259 } 00260 }