Panda3D
textMonitor.cxx
1 // Filename: textMonitor.cxx
2 // Created by: drose (12Jul00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "textMonitor.h"
16 #include "textStats.h"
17 #include "pStatCollectorDef.h"
18 #include "pStatFrameData.h"
19 #include "indent.h"
20 #include <stdio.h> // sprintf
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: TextMonitor::Constructor
24 // Access: Public
25 // Description:
26 ////////////////////////////////////////////////////////////////////
27 TextMonitor::
28 TextMonitor(TextStats *server, ostream *outStream, bool show_raw_data ) : PStatMonitor(server) {
29  _outStream = outStream; //[PECI]
30  _show_raw_data = show_raw_data;
31 }
32 
33 ////////////////////////////////////////////////////////////////////
34 // Function: TextMonitor::get_server
35 // Access: Public
36 // Description: Returns the server that owns this monitor.
37 ////////////////////////////////////////////////////////////////////
41 }
42 
43 ////////////////////////////////////////////////////////////////////
44 // Function: TextMonitor::get_monitor_name
45 // Access: Public, Virtual
46 // Description: Should be redefined to return a descriptive name for
47 // the type of PStatsMonitor this is.
48 ////////////////////////////////////////////////////////////////////
49 string TextMonitor::
51  return "Text Stats";
52 }
53 
54 ////////////////////////////////////////////////////////////////////
55 // Function: TextMonitor::got_hello
56 // Access: Public, Virtual
57 // Description: Called when the "hello" message has been received
58 // from the client. At this time, the client's hostname
59 // and program name will be known.
60 ////////////////////////////////////////////////////////////////////
61 void TextMonitor::
63  nout << "Now connected to " << get_client_progname() << " on host "
64  << get_client_hostname() << "\n";
65 }
66 
67 ////////////////////////////////////////////////////////////////////
68 // Function: TextMonitor::got_bad_version
69 // Access: Public, Virtual
70 // Description: Like got_hello(), this is called when the "hello"
71 // message has been received from the client. At this
72 // time, the client's hostname and program name will be
73 // known. However, the client appears to be an
74 // incompatible version and the connection will be
75 // terminated; the monitor should issue a message to
76 // that effect.
77 ////////////////////////////////////////////////////////////////////
78 void TextMonitor::
79 got_bad_version(int client_major, int client_minor,
80  int server_major, int server_minor) {
81  nout
82  << "Rejected connection by " << get_client_progname()
83  << " from " << get_client_hostname()
84  << ". Client uses PStats version "
85  << client_major << "." << client_minor
86  << ", while server expects PStats version "
87  << server_major << "." << server_minor << ".\n";
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: TextMonitor::new_data
92 // Access: Public, Virtual
93 // Description: Called as each frame's data is made available. There
94 // is no gurantee the frames will arrive in order, or
95 // that all of them will arrive at all. The monitor
96 // should be prepared to accept frames received
97 // out-of-order or missing.
98 ////////////////////////////////////////////////////////////////////
99 void TextMonitor::
100 new_data(int thread_index, int frame_number) {
101  PStatView &view = get_view(thread_index);
102  const PStatThreadData *thread_data = view.get_thread_data();
103 
104  if (frame_number == thread_data->get_latest_frame_number()) {
105  view.set_to_frame(frame_number);
106 
107  if (view.all_collectors_known()) {
108  const PStatClientData *client_data = get_client_data();
109 
110  (*_outStream) << "\rThread "
111  << client_data->get_thread_name(thread_index)
112  << " frame " << frame_number << ", "
113  << view.get_net_value() * 1000.0 << " ms ("
114  << thread_data->get_frame_rate() << " Hz):\n";
115 
116  if (_show_raw_data) {
117  const PStatFrameData &frame_data = thread_data->get_frame(frame_number);
118  (*_outStream) << "raw data:\n";
119  int num_events = frame_data.get_num_events();
120  for (int i = 0; i < num_events; ++i) {
121  // The iomanipulators are much too clumsy.
122  char formatted[32];
123  sprintf(formatted, "%15.06lf", frame_data.get_time(i));
124  (*_outStream) << formatted;
125 
126  if (frame_data.is_start(i)) {
127  (*_outStream) << " start ";
128  } else {
129  (*_outStream) << " stop ";
130  }
131 
132  int collector_index = frame_data.get_time_collector(i);
133  (*_outStream) << client_data->get_collector_fullname(collector_index) << "\n";
134  }
135  }
136 
137  const PStatViewLevel *level = view.get_top_level();
138  int num_children = level->get_num_children();
139  for (int i = 0; i < num_children; i++) {
140  show_ms(level->get_child(i), 2);
141  }
142 
143  int num_toplevel_collectors = client_data->get_num_toplevel_collectors();
144  for (int tc = 0; tc < num_toplevel_collectors; tc++) {
145  int collector = client_data->get_toplevel_collector(tc);
146  if (client_data->has_collector(collector) &&
147  client_data->get_collector_has_level(collector, thread_index)) {
148 
149  PStatView &level_view = get_level_view(collector, thread_index);
150  level_view.set_to_frame(frame_number);
151  const PStatViewLevel *level = level_view.get_top_level();
152  show_level(level, 2);
153  }
154  }
155  }
156  }
157  _outStream->flush();
158 }
159 
160 
161 ////////////////////////////////////////////////////////////////////
162 // Function: TextMonitor::lost_connection
163 // Access: Public, Virtual
164 // Description: Called whenever the connection to the client has been
165 // lost. This is a permanent state change. The monitor
166 // should update its display to represent this, and may
167 // choose to close down automatically.
168 ////////////////////////////////////////////////////////////////////
169 void TextMonitor::
171  nout << "Lost connection.\n";
172 }
173 
174 ////////////////////////////////////////////////////////////////////
175 // Function: TextMonitor::is_thread_safe
176 // Access: Public, Virtual
177 // Description: Should be redefined to return true if this monitor
178 // class can handle running in a sub-thread.
179 //
180 // This is not related to the question of whether it can
181 // handle multiple different PStatThreadDatas; this is
182 // strictly a question of whether or not the monitor
183 // itself wants to run in a sub-thread.
184 ////////////////////////////////////////////////////////////////////
185 bool TextMonitor::
187  return false;
188 }
189 
190 ////////////////////////////////////////////////////////////////////
191 // Function: TextMonitor::show_ms
192 // Access: Public
193 // Description:
194 ////////////////////////////////////////////////////////////////////
195 void TextMonitor::
196 show_ms(const PStatViewLevel *level, int indent_level) {
197  int collector_index = level->get_collector();
198 
199  const PStatClientData *client_data = get_client_data();
200  const PStatCollectorDef &def = client_data->get_collector_def(collector_index);
201 
202  indent((*_outStream), indent_level)
203  << def._name << " = " << level->get_net_value() * 1000.0 << " ms\n" ;
204 
205  int num_children = level->get_num_children();
206  for (int i = 0; i < num_children; i++) {
207  show_ms(level->get_child(i), indent_level + 2);
208  }
209 }
210 
211 ////////////////////////////////////////////////////////////////////
212 // Function: TextMonitor::show_level
213 // Access: Public
214 // Description:
215 ////////////////////////////////////////////////////////////////////
216 void TextMonitor::
217 show_level(const PStatViewLevel *level, int indent_level) {
218  int collector_index = level->get_collector();
219 
220  const PStatClientData *client_data = get_client_data();
221  const PStatCollectorDef &def = client_data->get_collector_def(collector_index);
222 
223  indent((*_outStream), indent_level)
224  << def._name << " = " << level->get_net_value() << " "
225  << def._level_units << "\n";
226 
227  int num_children = level->get_num_children();
228  for (int i = 0; i < num_children; i++) {
229  show_level(level->get_child(i), indent_level + 2);
230  }
231 }
const PStatViewLevel * get_top_level()
Returns a pointer to the level that corresponds to the Collector we&#39;ve constrained to...
Definition: pStatView.cxx:270
int get_num_events() const
Returns the number of individual events stored in the FrameData.
int get_toplevel_collector(int index) const
Returns the collector index of the nth toplevel collector.
void set_to_frame(const PStatFrameData &frame_data)
Supplies the View with the data for the current frame.
Definition: pStatView.cxx:216
bool is_start(int n) const
Returns true if the nth event represents a start event, or false if it represents a stop event...
PStatView & get_level_view(int collector_index, int thread_index)
Returns a view on the level value (as opposed to elapsed time) for the given collector over the given...
const PStatViewLevel * get_child(int n) const
Returns the nth child of this Level/Collector.
const PStatFrameData & get_frame(int frame_number) const
Returns a FrameData structure associated with the indicated frame number.
The data associated with a particular client, but not with any one particular frame or thread: the li...
virtual string get_monitor_name()
Should be redefined to return a descriptive name for the type of PStatsMonitor this is...
Definition: textMonitor.cxx:50
const PStatCollectorDef & get_collector_def(int index) const
Returns the nth collector definition.
string get_collector_fullname(int index) const
Returns the "full name" of the indicated collector.
virtual void lost_connection()
Called whenever the connection to the client has been lost.
TextStats * get_server()
Returns the server that owns this monitor.
Definition: textMonitor.cxx:39
double get_net_value() const
Returns the total value accounted for by the frame (or by whatever Collector we are constrained to)...
Definition: pStatView.cxx:250
This is a single level value, or band of color, within a View.
A simple, scrolling-text stats server.
Definition: textStats.h:31
double get_net_value() const
Returns the total level value (or elapsed time) represented by this Collector, including all values i...
This is an abstract class that presents the interface to any number of different front-ends for the s...
Definition: pStatMonitor.h:43
bool has_collector(int index) const
Returns true if the indicated collector has been defined by the client already, false otherwise...
int get_time_collector(int n) const
Returns the index of the collector associated with the nth event.
virtual void got_bad_version(int client_major, int client_minor, int server_major, int server_minor)
Like got_hello(), this is called when the "hello" message has been received from the client...
Definition: textMonitor.cxx:79
PStatServer * get_server()
Returns the server that owns this monitor.
Definition: pStatMonitor.I:22
Contains the raw timing and level data for a single frame.
double get_frame_rate() const
Computes the average frame rate over the past pstats_average_time seconds, by counting up the number ...
A View boils down the frame data to a linear list of times spent in a number of different Collectors...
Definition: pStatView.h:34
PStatView & get_view(int thread_index)
Returns a view on the given thread index.
bool all_collectors_known() const
After a call to set_to_frame(), this returns true if all collectors in the FrameData are known by the...
Definition: pStatView.cxx:237
A collection of FrameData structures for recently-received frames within a particular thread...
const PStatThreadData * get_thread_data()
Returns the current PStatThreadData associated with the view.
Definition: pStatView.I:25
int get_collector() const
Returns the Collector index associated with this level.
double get_time(int n) const
Returns the timestamp of the nth event, in seconds elapsed since some undefined epoch (which is guara...
string get_client_progname() const
Returns the program name of the client we&#39;re connected to, if known.
Definition: pStatMonitor.I:86
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
Definition: pStatMonitor.I:32
int get_num_children() const
Returns the number of children of this Level/Collector.
virtual void got_hello()
Called when the "hello" message has been received from the client.
Definition: textMonitor.cxx:62
Defines the details about the Collectors: the name, the suggested color, etc.
virtual bool is_thread_safe()
Should be redefined to return true if this monitor class can handle running in a sub-thread.
virtual void new_data(int thread_index, int frame_number)
Called as each frame&#39;s data is made available.
int get_latest_frame_number() const
Returns the frame number of the most recent frame stored in the data.
string get_client_hostname() const
Returns the hostname of the client we&#39;re connected to, if known.
Definition: pStatMonitor.I:72
int get_num_toplevel_collectors() const
Returns the total number of collectors that are toplevel collectors.
string get_thread_name(int index) const
Returns the name of the indicated thread.
bool get_collector_has_level(int index, int thread_index) const
Returns whether the given collector has level data (and consequently, whether it should appear on the...