Panda3D
|
00001 // Filename: pStatMonitor.cxx 00002 // Created by: drose (09Jul00) 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 "pStatMonitor.h" 00016 00017 #include "pStatCollectorDef.h" 00018 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: PStatMonitor::Constructor 00022 // Access: Public 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 PStatMonitor:: 00026 PStatMonitor(PStatServer *server) : _server(server) { 00027 _client_known = false; 00028 } 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: PStatMonitor::Destructor 00032 // Access: Public, Virtual 00033 // Description: 00034 //////////////////////////////////////////////////////////////////// 00035 PStatMonitor:: 00036 ~PStatMonitor() { 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: PStatMonitor::hello_from 00041 // Access: Public 00042 // Description: Called shortly after startup time with the greeting 00043 // from the client. This indicates the client's 00044 // reported hostname and program name. 00045 //////////////////////////////////////////////////////////////////// 00046 void PStatMonitor:: 00047 hello_from(const string &hostname, const string &progname) { 00048 _client_known = true; 00049 _client_hostname = hostname; 00050 _client_progname = progname; 00051 got_hello(); 00052 } 00053 00054 //////////////////////////////////////////////////////////////////// 00055 // Function: PStatMonitor::bad_version 00056 // Access: Public 00057 // Description: Called shortly after startup time with the greeting 00058 // from the client. In this case, the client seems to 00059 // have an incompatible version and will be 00060 // automatically disconnected; the server should issue a 00061 // message to that effect. 00062 //////////////////////////////////////////////////////////////////// 00063 void PStatMonitor:: 00064 bad_version(const string &hostname, const string &progname, 00065 int client_major, int client_minor, 00066 int server_major, int server_minor) { 00067 _client_known = true; 00068 _client_hostname = hostname; 00069 _client_progname = progname; 00070 got_bad_version(client_major, client_minor, 00071 server_major, server_minor); 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function: PStatMonitor::set_client_data 00076 // Access: Public 00077 // Description: Called by the PStatServer at setup time to set the 00078 // new data pointer for the first time. 00079 //////////////////////////////////////////////////////////////////// 00080 void PStatMonitor:: 00081 set_client_data(PStatClientData *client_data) { 00082 _client_data = client_data; 00083 initialized(); 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Function: PStatMonitor::is_alive 00088 // Access: Public 00089 // Description: Returns true if the client is alive and connected, 00090 // false otherwise. 00091 //////////////////////////////////////////////////////////////////// 00092 bool PStatMonitor:: 00093 is_alive() const { 00094 if (_client_data.is_null()) { 00095 // Not yet, but in a second probably. 00096 return false; 00097 } 00098 return _client_data->is_alive(); 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: PStatMonitor::close 00103 // Access: Public 00104 // Description: Closes the client connection if it is active. 00105 //////////////////////////////////////////////////////////////////// 00106 void PStatMonitor:: 00107 close() { 00108 if (!_client_data.is_null()) { 00109 _client_data->close(); 00110 } 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: PStatMonitor::get_collector_color 00115 // Access: Public 00116 // Description: Returns the color associated with the indicated 00117 // collector. If the collector has no associated color, 00118 // or is unknown, a new color will be made up on the 00119 // spot and associated with this collector for the rest 00120 // of the session. 00121 //////////////////////////////////////////////////////////////////// 00122 const LRGBColor &PStatMonitor:: 00123 get_collector_color(int collector_index) { 00124 Colors::iterator ci; 00125 ci = _colors.find(collector_index); 00126 if (ci != _colors.end()) { 00127 return (*ci).second; 00128 } 00129 00130 // Ask the client data about the color. 00131 if (!_client_data.is_null() && 00132 _client_data->has_collector(collector_index)) { 00133 const PStatCollectorDef &def = 00134 _client_data->get_collector_def(collector_index); 00135 00136 LRGBColor sc(def._suggested_color.r, 00137 def._suggested_color.g, 00138 def._suggested_color.b); 00139 if (sc != LRGBColor::zero()) { 00140 ci = _colors.insert(Colors::value_type(collector_index, sc)).first; 00141 return (*ci).second; 00142 } 00143 00144 // Use the fullname of the collector as a hash to seed the random 00145 // number generator (consulted below), so we get the same color 00146 // for a given name across sessions. 00147 string fullname = _client_data->get_collector_fullname(collector_index); 00148 unsigned int hash = 0; 00149 for (string::const_iterator ci = fullname.begin(); ci != fullname.end(); ++ci) { 00150 hash = hash * 37 + (unsigned int)(*ci); 00151 } 00152 srand(hash); 00153 } 00154 00155 // We didn't have a color for the collector; make one up. 00156 LRGBColor random_color; 00157 random_color[0] = (double)rand() / (double)RAND_MAX; 00158 random_color[1] = (double)rand() / (double)RAND_MAX; 00159 random_color[2] = (double)rand() / (double)RAND_MAX; 00160 00161 ci = _colors.insert(Colors::value_type(collector_index, random_color)).first; 00162 return (*ci).second; 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: PStatMonitor::get_view 00167 // Access: Public 00168 // Description: Returns a view on the given thread index. If there 00169 // is no such view already for the indicated thread, 00170 // this will create one. This view can be used to 00171 // examine the accumulated data for the given thread. 00172 //////////////////////////////////////////////////////////////////// 00173 PStatView &PStatMonitor:: 00174 get_view(int thread_index) { 00175 Views::iterator vi; 00176 vi = _views.find(thread_index); 00177 if (vi == _views.end()) { 00178 vi = _views.insert(Views::value_type(thread_index, PStatView())).first; 00179 (*vi).second.set_thread_data(_client_data->get_thread_data(thread_index)); 00180 } 00181 return (*vi).second; 00182 } 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // Function: PStatMonitor::get_level_view 00186 // Access: Public 00187 // Description: Returns a view on the level value (as opposed to 00188 // elapsed time) for the given collector over the given 00189 // thread. If there is no such view already for the 00190 // indicated thread, this will create one. 00191 //////////////////////////////////////////////////////////////////// 00192 PStatView &PStatMonitor:: 00193 get_level_view(int collector_index, int thread_index) { 00194 LevelViews::iterator lvi; 00195 lvi = _level_views.find(collector_index); 00196 if (lvi == _level_views.end()) { 00197 lvi = _level_views.insert(LevelViews::value_type(collector_index, Views())).first; 00198 } 00199 Views &views = (*lvi).second; 00200 00201 Views::iterator vi; 00202 vi = views.find(thread_index); 00203 if (vi == views.end()) { 00204 vi = views.insert(Views::value_type(thread_index, PStatView())).first; 00205 (*vi).second.set_thread_data(_client_data->get_thread_data(thread_index)); 00206 (*vi).second.constrain(collector_index, true); 00207 } 00208 return (*vi).second; 00209 } 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: PStatMonitor::initialized 00213 // Access: Public, Virtual 00214 // Description: Called after the monitor has been fully set up. At 00215 // this time, it will have a valid _client_data pointer, 00216 // and things like is_alive() and close() will be 00217 // meaningful. However, we may not yet know who we're 00218 // connected to (is_client_known() may return false), 00219 // and we may not know anything about the threads or 00220 // collectors we're about to get data on. 00221 //////////////////////////////////////////////////////////////////// 00222 void PStatMonitor:: 00223 initialized() { 00224 } 00225 00226 //////////////////////////////////////////////////////////////////// 00227 // Function: PStatMonitor::got_hello 00228 // Access: Public, Virtual 00229 // Description: Called when the "hello" message has been received 00230 // from the client. At this time, the client's hostname 00231 // and program name will be known. 00232 //////////////////////////////////////////////////////////////////// 00233 void PStatMonitor:: 00234 got_hello() { 00235 } 00236 00237 //////////////////////////////////////////////////////////////////// 00238 // Function: PStatMonitor::got_bad_version 00239 // Access: Public, Virtual 00240 // Description: Like got_hello(), this is called when the "hello" 00241 // message has been received from the client. At this 00242 // time, the client's hostname and program name will be 00243 // known. However, the client appears to be an 00244 // incompatible version and the connection will be 00245 // terminated; the monitor should issue a message to 00246 // that effect. 00247 //////////////////////////////////////////////////////////////////// 00248 void PStatMonitor:: 00249 got_bad_version(int, int, int, int) { 00250 } 00251 00252 //////////////////////////////////////////////////////////////////// 00253 // Function: PStatMonitor::new_collector 00254 // Access: Public, Virtual 00255 // Description: Called whenever a new Collector definition is 00256 // received from the client. Generally, the client will 00257 // send all of its collectors over shortly after 00258 // connecting, but there's no guarantee that they will 00259 // all be received before the first frames are received. 00260 // The monitor should be prepared to accept new Collector 00261 // definitions midstream. 00262 //////////////////////////////////////////////////////////////////// 00263 void PStatMonitor:: 00264 new_collector(int) { 00265 } 00266 00267 //////////////////////////////////////////////////////////////////// 00268 // Function: PStatMonitor::new_thread 00269 // Access: Public, Virtual 00270 // Description: Called whenever a new Thread definition is 00271 // received from the client. Generally, the client will 00272 // send all of its threads over shortly after 00273 // connecting, but there's no guarantee that they will 00274 // all be received before the first frames are received. 00275 // The monitor should be prepared to accept new Thread 00276 // definitions midstream. 00277 //////////////////////////////////////////////////////////////////// 00278 void PStatMonitor:: 00279 new_thread(int) { 00280 } 00281 00282 //////////////////////////////////////////////////////////////////// 00283 // Function: PStatMonitor::new_data 00284 // Access: Public, Virtual 00285 // Description: Called as each frame's data is made available. There 00286 // is no guarantee the frames will arrive in order, or 00287 // that all of them will arrive at all. The monitor 00288 // should be prepared to accept frames received 00289 // out-of-order or missing. The use of the 00290 // PStatFrameData / PStatView objects to report the data 00291 // will facilitate this. 00292 //////////////////////////////////////////////////////////////////// 00293 void PStatMonitor:: 00294 new_data(int, int) { 00295 } 00296 00297 //////////////////////////////////////////////////////////////////// 00298 // Function: PStatMonitor::lost_connection 00299 // Access: Public, Virtual 00300 // Description: Called whenever the connection to the client has been 00301 // lost. This is a permanent state change. The monitor 00302 // should update its display to represent this, and may 00303 // choose to close down automatically. 00304 //////////////////////////////////////////////////////////////////// 00305 void PStatMonitor:: 00306 lost_connection() { 00307 } 00308 00309 //////////////////////////////////////////////////////////////////// 00310 // Function: PStatMonitor::idle 00311 // Access: Public, Virtual 00312 // Description: If has_idle() returns true, this will be called 00313 // periodically to allow the monitor to update its 00314 // display or whatever it needs to do. 00315 //////////////////////////////////////////////////////////////////// 00316 void PStatMonitor:: 00317 idle() { 00318 } 00319 00320 //////////////////////////////////////////////////////////////////// 00321 // Function: PStatMonitor::has_idle 00322 // Access: Public, Virtual 00323 // Description: Should be redefined to return true if you want to 00324 // redefine idle() and expect it to be called. 00325 //////////////////////////////////////////////////////////////////// 00326 bool PStatMonitor:: 00327 has_idle() { 00328 return false; 00329 } 00330 00331 //////////////////////////////////////////////////////////////////// 00332 // Function: PStatMonitor::is_thread_safe 00333 // Access: Public, Virtual 00334 // Description: Should be redefined to return true if this monitor 00335 // class can handle running in a sub-thread. 00336 // 00337 // This is not related to the question of whether it can 00338 // handle multiple different PStatThreadDatas; this is 00339 // strictly a question of whether or not the monitor 00340 // itself wants to run in a sub-thread. 00341 //////////////////////////////////////////////////////////////////// 00342 bool PStatMonitor:: 00343 is_thread_safe() { 00344 return false; 00345 } 00346 00347 //////////////////////////////////////////////////////////////////// 00348 // Function: PStatMonitor::user_guide_bars_changed 00349 // Access: Public, Virtual 00350 // Description: Called when the user guide bars have been changed. 00351 //////////////////////////////////////////////////////////////////// 00352 void PStatMonitor:: 00353 user_guide_bars_changed() { 00354 }