Panda3D
 All Classes Functions Variables Enumerations
textMonitor.cxx
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 }
 All Classes Functions Variables Enumerations