Panda3D
|
00001 // Filename: textMonitor.cxx 00002 // Created by: drose (12Jul00) 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 "textMonitor.h" 00016 #include "textStats.h" 00017 #include "pStatCollectorDef.h" 00018 #include "pStatFrameData.h" 00019 #include "indent.h" 00020 #include <stdio.h> // sprintf 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: TextMonitor::Constructor 00024 // Access: Public 00025 // Description: 00026 //////////////////////////////////////////////////////////////////// 00027 TextMonitor:: 00028 TextMonitor(TextStats *server, ostream *outStream, bool show_raw_data ) : PStatMonitor(server) { 00029 _outStream = outStream; //[PECI] 00030 _show_raw_data = show_raw_data; 00031 } 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: TextMonitor::get_server 00035 // Access: Public 00036 // Description: Returns the server that owns this monitor. 00037 //////////////////////////////////////////////////////////////////// 00038 TextStats *TextMonitor:: 00039 get_server() { 00040 return (TextStats *)PStatMonitor::get_server(); 00041 } 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Function: TextMonitor::get_monitor_name 00045 // Access: Public, Virtual 00046 // Description: Should be redefined to return a descriptive name for 00047 // the type of PStatsMonitor this is. 00048 //////////////////////////////////////////////////////////////////// 00049 string TextMonitor:: 00050 get_monitor_name() { 00051 return "Text Stats"; 00052 } 00053 00054 //////////////////////////////////////////////////////////////////// 00055 // Function: TextMonitor::got_hello 00056 // Access: Public, Virtual 00057 // Description: Called when the "hello" message has been received 00058 // from the client. At this time, the client's hostname 00059 // and program name will be known. 00060 //////////////////////////////////////////////////////////////////// 00061 void TextMonitor:: 00062 got_hello() { 00063 nout << "Now connected to " << get_client_progname() << " on host " 00064 << get_client_hostname() << "\n"; 00065 } 00066 00067 //////////////////////////////////////////////////////////////////// 00068 // Function: TextMonitor::got_bad_version 00069 // Access: Public, Virtual 00070 // Description: Like got_hello(), this is called when the "hello" 00071 // message has been received from the client. At this 00072 // time, the client's hostname and program name will be 00073 // known. However, the client appears to be an 00074 // incompatible version and the connection will be 00075 // terminated; the monitor should issue a message to 00076 // that effect. 00077 //////////////////////////////////////////////////////////////////// 00078 void TextMonitor:: 00079 got_bad_version(int client_major, int client_minor, 00080 int server_major, int server_minor) { 00081 nout 00082 << "Rejected connection by " << get_client_progname() 00083 << " from " << get_client_hostname() 00084 << ". Client uses PStats version " 00085 << client_major << "." << client_minor 00086 << ", while server expects PStats version " 00087 << server_major << "." << server_minor << ".\n"; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: TextMonitor::new_data 00092 // Access: Public, Virtual 00093 // Description: Called as each frame's data is made available. There 00094 // is no gurantee the frames will arrive in order, or 00095 // that all of them will arrive at all. The monitor 00096 // should be prepared to accept frames received 00097 // out-of-order or missing. 00098 //////////////////////////////////////////////////////////////////// 00099 void TextMonitor:: 00100 new_data(int thread_index, int frame_number) { 00101 PStatView &view = get_view(thread_index); 00102 const PStatThreadData *thread_data = view.get_thread_data(); 00103 00104 if (frame_number == thread_data->get_latest_frame_number()) { 00105 view.set_to_frame(frame_number); 00106 00107 if (view.all_collectors_known()) { 00108 const PStatClientData *client_data = get_client_data(); 00109 00110 (*_outStream) << "\rThread " 00111 << client_data->get_thread_name(thread_index) 00112 << " frame " << frame_number << ", " 00113 << view.get_net_value() * 1000.0 << " ms (" 00114 << thread_data->get_frame_rate() << " Hz):\n"; 00115 00116 if (_show_raw_data) { 00117 const PStatFrameData &frame_data = thread_data->get_frame(frame_number); 00118 (*_outStream) << "raw data:\n"; 00119 int num_events = frame_data.get_num_events(); 00120 for (int i = 0; i < num_events; ++i) { 00121 // The iomanipulators are much too clumsy. 00122 char formatted[32]; 00123 sprintf(formatted, "%15.06lf", frame_data.get_time(i)); 00124 (*_outStream) << formatted; 00125 00126 if (frame_data.is_start(i)) { 00127 (*_outStream) << " start "; 00128 } else { 00129 (*_outStream) << " stop "; 00130 } 00131 00132 int collector_index = frame_data.get_time_collector(i); 00133 (*_outStream) << client_data->get_collector_fullname(collector_index) << "\n"; 00134 } 00135 } 00136 00137 const PStatViewLevel *level = view.get_top_level(); 00138 int num_children = level->get_num_children(); 00139 for (int i = 0; i < num_children; i++) { 00140 show_ms(level->get_child(i), 2); 00141 } 00142 00143 int num_toplevel_collectors = client_data->get_num_toplevel_collectors(); 00144 for (int tc = 0; tc < num_toplevel_collectors; tc++) { 00145 int collector = client_data->get_toplevel_collector(tc); 00146 if (client_data->has_collector(collector) && 00147 client_data->get_collector_has_level(collector, thread_index)) { 00148 00149 PStatView &level_view = get_level_view(collector, thread_index); 00150 level_view.set_to_frame(frame_number); 00151 const PStatViewLevel *level = level_view.get_top_level(); 00152 show_level(level, 2); 00153 } 00154 } 00155 } 00156 } 00157 _outStream->flush(); 00158 } 00159 00160 00161 //////////////////////////////////////////////////////////////////// 00162 // Function: TextMonitor::lost_connection 00163 // Access: Public, Virtual 00164 // Description: Called whenever the connection to the client has been 00165 // lost. This is a permanent state change. The monitor 00166 // should update its display to represent this, and may 00167 // choose to close down automatically. 00168 //////////////////////////////////////////////////////////////////// 00169 void TextMonitor:: 00170 lost_connection() { 00171 nout << "Lost connection.\n"; 00172 } 00173 00174 //////////////////////////////////////////////////////////////////// 00175 // Function: TextMonitor::is_thread_safe 00176 // Access: Public, Virtual 00177 // Description: Should be redefined to return true if this monitor 00178 // class can handle running in a sub-thread. 00179 // 00180 // This is not related to the question of whether it can 00181 // handle multiple different PStatThreadDatas; this is 00182 // strictly a question of whether or not the monitor 00183 // itself wants to run in a sub-thread. 00184 //////////////////////////////////////////////////////////////////// 00185 bool TextMonitor:: 00186 is_thread_safe() { 00187 return false; 00188 } 00189 00190 //////////////////////////////////////////////////////////////////// 00191 // Function: TextMonitor::show_ms 00192 // Access: Public 00193 // Description: 00194 //////////////////////////////////////////////////////////////////// 00195 void TextMonitor:: 00196 show_ms(const PStatViewLevel *level, int indent_level) { 00197 int collector_index = level->get_collector(); 00198 00199 const PStatClientData *client_data = get_client_data(); 00200 const PStatCollectorDef &def = client_data->get_collector_def(collector_index); 00201 00202 indent((*_outStream), indent_level) 00203 << def._name << " = " << level->get_net_value() * 1000.0 << " ms\n" ; 00204 00205 int num_children = level->get_num_children(); 00206 for (int i = 0; i < num_children; i++) { 00207 show_ms(level->get_child(i), indent_level + 2); 00208 } 00209 } 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: TextMonitor::show_level 00213 // Access: Public 00214 // Description: 00215 //////////////////////////////////////////////////////////////////// 00216 void TextMonitor:: 00217 show_level(const PStatViewLevel *level, int indent_level) { 00218 int collector_index = level->get_collector(); 00219 00220 const PStatClientData *client_data = get_client_data(); 00221 const PStatCollectorDef &def = client_data->get_collector_def(collector_index); 00222 00223 indent((*_outStream), indent_level) 00224 << def._name << " = " << level->get_net_value() << " " 00225 << def._level_units << "\n"; 00226 00227 int num_children = level->get_num_children(); 00228 for (int i = 0; i < num_children; i++) { 00229 show_level(level->get_child(i), indent_level + 2); 00230 } 00231 }