Panda3D
 All Classes Functions Variables Enumerations
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 }
string get_thread_name(int index) const
Returns the name of the indicated thread.
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
string get_client_progname() const
Returns the program name of the client we&#39;re connected to, if known.
Definition: pStatMonitor.I:86
const PStatViewLevel * get_child(int n) const
Returns the nth child of this Level/Collector.
void set_to_frame(const PStatFrameData &frame_data)
Supplies the View with the data for the current frame.
Definition: pStatView.cxx:216
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...
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
string get_collector_fullname(int index) const
Returns the &quot;full name&quot; of the indicated collector.
virtual void lost_connection()
Called whenever the connection to the client has been lost.
int get_time_collector(int n) const
Returns the index of the collector associated with the nth event.
TextStats * get_server()
Returns the server that owns this monitor.
Definition: textMonitor.cxx:39
bool has_collector(int index) const
Returns true if the indicated collector has been defined by the client already, false otherwise...
This is a single level value, or band of color, within a View.
A simple, scrolling-text stats server.
Definition: textStats.h:31
This is an abstract class that presents the interface to any number of different front-ends for the s...
Definition: pStatMonitor.h:43
bool is_start(int n) const
Returns true if the nth event represents a start event, or false if it represents a stop 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 &quot;hello&quot; message has been received from the client...
Definition: textMonitor.cxx:79
int get_num_events() const
Returns the number of individual events stored in the FrameData.
string get_client_hostname() const
Returns the hostname of the client we&#39;re connected to, if known.
Definition: pStatMonitor.I:72
PStatServer * get_server()
Returns the server that owns this monitor.
Definition: pStatMonitor.I:22
const PStatCollectorDef & get_collector_def(int index) const
Returns the nth collector definition.
Contains the raw timing and level data for a single frame.
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...
int get_toplevel_collector(int index) const
Returns the collector index of the nth toplevel collector.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
Definition: pStatMonitor.I:32
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
const PStatThreadData * get_thread_data()
Returns the current PStatThreadData associated with the view.
Definition: pStatView.I:25
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...
int get_num_children() const
Returns the number of children of this Level/Collector.
double get_net_value() const
Returns the total level value (or elapsed time) represented by this Collector, including all values i...
double get_time(int n) const
Returns the timestamp of the nth event, in seconds elapsed since some undefined epoch (which is guara...
int get_num_toplevel_collectors() const
Returns the total number of collectors that are toplevel collectors.
const PStatFrameData & get_frame(int frame_number) const
Returns a FrameData structure associated with the indicated frame number.
virtual void got_hello()
Called when the &quot;hello&quot; 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.
int get_collector() const
Returns the Collector index associated with this level.
virtual void new_data(int thread_index, int frame_number)
Called as each frame&#39;s data is made available.
double get_frame_rate() const
Computes the average frame rate over the past pstats_average_time seconds, by counting up the number ...
int get_latest_frame_number() const
Returns the frame number of the most recent frame stored in the data.