Panda3D

pStatMonitor.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file pStatMonitor.cxx
10 * @author drose
11 * @date 2000-07-09
12 */
13
14 #include "pStatMonitor.h"
15
16 #include "pStatCollectorDef.h"
17
18 using std::string;
19
20
21 /**
22 *
23 */
24 PStatMonitor::
25 PStatMonitor(PStatServer *server) : _server(server) {
26 _client_known = false;
27 }
28
29 /**
30 *
31 */
32 PStatMonitor::
33 ~PStatMonitor() {
34 }
35
36 /**
37 * Called shortly after startup time with the greeting from the client. This
38 * indicates the client's reported hostname and program name.
39 */
40 void PStatMonitor::
41 hello_from(const string &hostname, const string &progname) {
42 _client_known = true;
43 _client_hostname = hostname;
44 _client_progname = progname;
45 got_hello();
46 }
47
48 /**
49 * Called shortly after startup time with the greeting from the client. In
50 * this case, the client seems to have an incompatible version and will be
51 * automatically disconnected; the server should issue a message to that
52 * effect.
53 */
54 void PStatMonitor::
55 bad_version(const string &hostname, const string &progname,
56 int client_major, int client_minor,
57 int server_major, int server_minor) {
58 _client_known = true;
59 _client_hostname = hostname;
60 _client_progname = progname;
61 got_bad_version(client_major, client_minor,
62 server_major, server_minor);
63 }
64
65 /**
66 * Called by the PStatServer at setup time to set the new data pointer for the
67 * first time.
68 */
69 void PStatMonitor::
70 set_client_data(PStatClientData *client_data) {
71 _client_data = client_data;
72 initialized();
73 }
74
75 /**
76 * Returns true if the client is alive and connected, false otherwise.
77 */
78 bool PStatMonitor::
79 is_alive() const {
80 if (_client_data.is_null()) {
81 // Not yet, but in a second probably.
82 return false;
83 }
84 return _client_data->is_alive();
85 }
86
87 /**
88 * Closes the client connection if it is active.
89 */
90 void PStatMonitor::
91 close() {
92 if (!_client_data.is_null()) {
93 _client_data->close();
94 }
95 }
96
97 /**
98 * Returns the color associated with the indicated collector. If the
99 * collector has no associated color, or is unknown, a new color will be made
100 * up on the spot and associated with this collector for the rest of the
101 * session.
102 */
103 const LRGBColor &PStatMonitor::
104 get_collector_color(int collector_index) {
105 Colors::iterator ci;
106 ci = _colors.find(collector_index);
107 if (ci != _colors.end()) {
108 return (*ci).second;
109 }
110
111 // Ask the client data about the color.
112 if (!_client_data.is_null() &&
113 _client_data->has_collector(collector_index)) {
114 const PStatCollectorDef &def =
115 _client_data->get_collector_def(collector_index);
116
117 LRGBColor sc(def._suggested_color.r,
118 def._suggested_color.g,
119 def._suggested_color.b);
120 if (sc != LRGBColor::zero()) {
121 ci = _colors.insert(Colors::value_type(collector_index, sc)).first;
122 return (*ci).second;
123 }
124
125 // Use the fullname of the collector as a hash to seed the random number
126 // generator (consulted below), so we get the same color for a given name
127 // across sessions.
128 string fullname = _client_data->get_collector_fullname(collector_index);
129 unsigned int hash = 0;
130 for (string::const_iterator ci = fullname.begin(); ci != fullname.end(); ++ci) {
131 hash = hash * 37 + (unsigned int)(*ci);
132 }
133 srand(hash);
134 }
135
136 // We didn't have a color for the collector; make one up.
137 LRGBColor random_color;
138 random_color[0] = (double)rand() / (double)RAND_MAX;
139 random_color[1] = (double)rand() / (double)RAND_MAX;
140 random_color[2] = (double)rand() / (double)RAND_MAX;
141
142 ci = _colors.insert(Colors::value_type(collector_index, random_color)).first;
143 return (*ci).second;
144 }
145
146 /**
147 * Returns a view on the given thread index. If there is no such view already
148 * for the indicated thread, this will create one. This view can be used to
149 * examine the accumulated data for the given thread.
150 */
151 PStatView &PStatMonitor::
152 get_view(int thread_index) {
153 Views::iterator vi;
154 vi = _views.find(thread_index);
155 if (vi == _views.end()) {
156 vi = _views.insert(Views::value_type(thread_index, PStatView())).first;
157 (*vi).second.set_thread_data(_client_data->get_thread_data(thread_index));
158 }
159 return (*vi).second;
160 }
161
162 /**
163 * Returns a view on the level value (as opposed to elapsed time) for the
164 * given collector over the given thread. If there is no such view already
165 * for the indicated thread, this will create one.
166 */
167 PStatView &PStatMonitor::
168 get_level_view(int collector_index, int thread_index) {
169 LevelViews::iterator lvi;
170 lvi = _level_views.find(collector_index);
171 if (lvi == _level_views.end()) {
172 lvi = _level_views.insert(LevelViews::value_type(collector_index, Views())).first;
173 }
174 Views &views = (*lvi).second;
175
176 Views::iterator vi;
177 vi = views.find(thread_index);
178 if (vi == views.end()) {
179 vi = views.insert(Views::value_type(thread_index, PStatView())).first;
180 (*vi).second.set_thread_data(_client_data->get_thread_data(thread_index));
181 (*vi).second.constrain(collector_index, true);
182 }
183 return (*vi).second;
184 }
185
186 /**
187 * Called after the monitor has been fully set up. At this time, it will have
188 * a valid _client_data pointer, and things like is_alive() and close() will
189 * be meaningful. However, we may not yet know who we're connected to
190 * (is_client_known() may return false), and we may not know anything about
191 * the threads or collectors we're about to get data on.
192 */
193 void PStatMonitor::
194 initialized() {
195 }
196
197 /**
198 * Called when the "hello" message has been received from the client. At this
199 * time, the client's hostname and program name will be known.
200 */
201 void PStatMonitor::
202 got_hello() {
203 }
204
205 /**
206 * Like got_hello(), this is called when the "hello" message has been received
207 * from the client. At this time, the client's hostname and program name will
208 * be known. However, the client appears to be an incompatible version and
209 * the connection will be terminated; the monitor should issue a message to
210 * that effect.
211 */
212 void PStatMonitor::
213 got_bad_version(int, int, int, int) {
214 }
215
216 /**
217 * Called whenever a new Collector definition is received from the client.
218 * Generally, the client will send all of its collectors over shortly after
219 * connecting, but there's no guarantee that they will all be received before
220 * the first frames are received. The monitor should be prepared to accept
221 * new Collector definitions midstream.
222 */
223 void PStatMonitor::
224 new_collector(int) {
225 }
226
227 /**
228 * Called whenever a new Thread definition is received from the client.
229 * Generally, the client will send all of its threads over shortly after
230 * connecting, but there's no guarantee that they will all be received before
231 * the first frames are received. The monitor should be prepared to accept
232 * new Thread definitions midstream.
233 */
234 void PStatMonitor::
235 new_thread(int) {
236 }
237
238 /**
239 * Called as each frame's data is made available. There is no guarantee the
240 * frames will arrive in order, or that all of them will arrive at all. The
241 * monitor should be prepared to accept frames received out-of-order or
242 * missing. The use of the PStatFrameData / PStatView objects to report the
243 * data will facilitate this.
244 */
245 void PStatMonitor::
246 new_data(int, int) {
247 }
248
249 /**
250 * Called whenever the connection to the client has been lost. This is a
251 * permanent state change. The monitor should update its display to represent
252 * this, and may choose to close down automatically.
253 */
254 void PStatMonitor::
255 lost_connection() {
256 }
257
258 /**
259 * If has_idle() returns true, this will be called periodically to allow the
260 * monitor to update its display or whatever it needs to do.
261 */
262 void PStatMonitor::
263 idle() {
264 }
265
266 /**
267 * Should be redefined to return true if you want to redefine idle() and
268 * expect it to be called.
269 */
270 bool PStatMonitor::
271 has_idle() {
272 return false;
273 }
274
275 /**
276 * Should be redefined to return true if this monitor class can handle running
277 * in a sub-thread.
278 *
279 * This is not related to the question of whether it can handle multiple
280 * different PStatThreadDatas; this is strictly a question of whether or not
281 * the monitor itself wants to run in a sub-thread.
282 */
283 bool PStatMonitor::
284 is_thread_safe() {
285 return false;
286 }
287
288 /**
289 * Called when the user guide bars have been changed.
290 */
291 void PStatMonitor::
292 user_guide_bars_changed() {
293 }
PStatClientData
The data associated with a particular client, but not with any one particular frame or thread: the li...
Definition: pStatClientData.h:36
PStatCollectorDef
Defines the details about the Collectors: the name, the suggested color, etc.
Definition: pStatCollectorDef.h:29
PStatMonitor::lost_connection
virtual void lost_connection()
Called whenever the connection to the client has been lost.
Definition: pStatMonitor.cxx:255
PStatMonitor::got_hello
virtual void got_hello()
Called when the "hello" message has been received from the client.
Definition: pStatMonitor.cxx:202
PStatMonitor::idle
virtual void idle()
If has_idle() returns true, this will be called periodically to allow the monitor to update its displ...
Definition: pStatMonitor.cxx:263
PStatMonitor::get_level_view
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...
Definition: pStatMonitor.cxx:168
PStatMonitor::set_client_data
void set_client_data(PStatClientData *client_data)
Called by the PStatServer at setup time to set the new data pointer for the first time.
Definition: pStatMonitor.cxx:70
PStatMonitor::new_data
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
Definition: pStatMonitor.cxx:246
PStatMonitor::initialized
virtual void initialized()
Called after the monitor has been fully set up.
Definition: pStatMonitor.cxx:194
PStatMonitor::user_guide_bars_changed
virtual void user_guide_bars_changed()
Called when the user guide bars have been changed.
Definition: pStatMonitor.cxx:292
PStatMonitor::has_idle
virtual bool has_idle()
Should be redefined to return true if you want to redefine idle() and expect it to be called.
Definition: pStatMonitor.cxx:271
PStatMonitor::close
void close()
Closes the client connection if it is active.
Definition: pStatMonitor.cxx:91
PStatMonitor::new_collector
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
Definition: pStatMonitor.cxx:224
PStatMonitor::got_bad_version
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: pStatMonitor.cxx:213
PStatMonitor::hello_from
void hello_from(const std::string &hostname, const std::string &progname)
Called shortly after startup time with the greeting from the client.
Definition: pStatMonitor.cxx:41
PStatMonitor::is_alive
bool is_alive() const
Returns true if the client is alive and connected, false otherwise.
Definition: pStatMonitor.cxx:79
PStatMonitor::bad_version
void bad_version(const std::string &hostname, const std::string &progname, int client_major, int client_minor, int server_major, int server_minor)
Called shortly after startup time with the greeting from the client.
Definition: pStatMonitor.cxx:55
PStatMonitor::new_thread
virtual void new_thread(int thread_index)
Called whenever a new Thread definition is received from the client.
Definition: pStatMonitor.cxx:235
PStatMonitor::is_thread_safe
virtual bool is_thread_safe()
Should be redefined to return true if this monitor class can handle running in a sub-thread.
Definition: pStatMonitor.cxx:284
PStatMonitor::get_view
PStatView & get_view(int thread_index)
Returns a view on the given thread index.
Definition: pStatMonitor.cxx:152
PStatMonitor::get_collector_color
const LRGBColor & get_collector_color(int collector_index)
Returns the color associated with the indicated collector.
Definition: pStatMonitor.cxx:104
PStatServer
The overall manager of the network connections.
Definition: pStatServer.h:36
PStatView
A View boils down the frame data to a linear list of times spent in a number of different Collectors,...
Definition: pStatView.h:31
pmap< int, PStatView >
pStatCollectorDef.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pStatMonitor.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.