Panda3D
pStatCollector.I
1 // Filename: pStatCollector.I
2 // Created by: drose (10Jul00)
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 
16 #ifdef DO_PSTATS
17 
18 ////////////////////////////////////////////////////////////////////
19 // Function: PStatCollector::Constructor
20 // Access: Private
21 // Description: Normally, this constructor is called only from
22 // PStatClient. Use one of the constructors below to
23 // create your own Collector.
24 ////////////////////////////////////////////////////////////////////
25 INLINE PStatCollector::
26 PStatCollector(PStatClient *client, int index) :
27  _client(client),
28  _index(index),
29  _level(0.0f)
30 {
31 }
32 
33 ////////////////////////////////////////////////////////////////////
34 // Function: PStatCollector::Default Constructor
35 // Access: Public
36 // Description: Creates an invalid PStatCollector. Any attempt to
37 // use this collector will crash messily.
38 //
39 // You can reassign it to a different, valid one later.
40 ////////////////////////////////////////////////////////////////////
41 INLINE PStatCollector::
42 PStatCollector() :
43  _client(NULL),
44  _index(0),
45  _level(0.0f)
46 {
47 }
48 
49 ////////////////////////////////////////////////////////////////////
50 // Function: PStatCollector::Constructor
51 // Access: Published
52 // Description: Creates a new PStatCollector, ready to start
53 // accumulating data. The name of the collector
54 // uniquely identifies it among the other collectors; if
55 // two collectors share the same name then they are
56 // really the same collector.
57 //
58 // The name may also be a compound name, something like
59 // "Cull:Sort", which indicates that this is a collector
60 // named "Sort", a child of the collector named "Cull".
61 // The parent may also be named explicitly by reference
62 // in the other flavor of the constructor; see further
63 // comments on this for that constructor.
64 //
65 // If the client pointer is non-null, it specifies a
66 // particular client to register the collector with;
67 // otherwise, the global client is used.
68 ////////////////////////////////////////////////////////////////////
69 INLINE PStatCollector::
70 PStatCollector(const string &name, PStatClient *client) :
71  _level(0.0f)
72 {
73  if (client == (PStatClient *)NULL) {
74  client = PStatClient::get_global_pstats();
75  }
76  (*this) = client->make_collector_with_relname(0, name);
77 }
78 
79 ////////////////////////////////////////////////////////////////////
80 // Function: PStatCollector::Constructor
81 // Access: Published
82 // Description: Creates a new PStatCollector, ready to start
83 // accumulating data. The name of the collector
84 // uniquely identifies it among the other collectors; if
85 // two collectors share the same name then they are
86 // really the same collector.
87 //
88 // The parent is the collector that conceptually
89 // includes all of the time measured for this collector.
90 // For instance, a particular character's animation time
91 // is owned by the "Animation" collector, which is in
92 // turn owned by the "Frame" collector. It is not
93 // strictly necessary that all of the time spent in a
94 // particular collector is completely nested within time
95 // spent in its parent's collector. If parent is the
96 // empty string, the collector is owned by "Frame".
97 //
98 // This constructor does not take a client pointer; it
99 // always creates the new collector on the same client
100 // as its parent.
101 ////////////////////////////////////////////////////////////////////
102 INLINE PStatCollector::
103 PStatCollector(const PStatCollector &parent, const string &name) :
104  _level(0.0f)
105 {
106  nassertv(parent._client != (PStatClient *)NULL);
107  (*this) =
108  parent._client->make_collector_with_relname(parent._index, name);
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function: PStatCollector::Copy Constructor
113 // Access: Published
114 // Description:
115 ////////////////////////////////////////////////////////////////////
116 INLINE PStatCollector::
117 PStatCollector(const PStatCollector &copy) :
118  _client(copy._client),
119  _index(copy._index),
120  _level(0.0f)
121 {
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function: PStatCollector::Copy Assignment Operator
126 // Access: Published
127 // Description:
128 ////////////////////////////////////////////////////////////////////
129 INLINE void PStatCollector::
130 operator = (const PStatCollector &copy) {
131  _client = copy._client;
132  _index = copy._index;
133 }
134 
135 ////////////////////////////////////////////////////////////////////
136 // Function: PStatCollector::is_valid
137 // Access: Published
138 // Description: Returns true if collector is valid and may be used,
139 // or false if it was constructed with the default
140 // constructor (in which case any attempt to use it will
141 // crash).
142 ////////////////////////////////////////////////////////////////////
143 INLINE bool PStatCollector::
144 is_valid() const {
145  return (_client != (PStatClient *)NULL);
146 }
147 
148 ////////////////////////////////////////////////////////////////////
149 // Function: PStatCollector::get_name
150 // Access: Published
151 // Description: Returns the local name of this collector. This is
152 // the rightmost part of the fullname, after the
153 // rightmost colon.
154 ////////////////////////////////////////////////////////////////////
155 INLINE string PStatCollector::
156 get_name() const {
157  if (_client != (PStatClient *)NULL) {
158  return _client->get_collector_name(_index);
159  }
160  return string();
161 }
162 
163 ////////////////////////////////////////////////////////////////////
164 // Function: PStatCollector::get_fullname
165 // Access: Published
166 // Description: Returns the full name of this collector. This
167 // includes the names of all the collector's parents,
168 // concatenated together with colons.
169 ////////////////////////////////////////////////////////////////////
170 INLINE string PStatCollector::
171 get_fullname() const {
172  if (_client != (PStatClient *)NULL) {
173  return _client->get_collector_fullname(_index);
174  }
175  return string();
176 }
177 
178 ////////////////////////////////////////////////////////////////////
179 // Function: PStatCollector::output
180 // Access: Published
181 // Description:
182 ////////////////////////////////////////////////////////////////////
183 INLINE void PStatCollector::
184 output(ostream &out) const {
185  out << "PStatCollector(\"" << get_fullname() << "\")";
186 }
187 
188 ////////////////////////////////////////////////////////////////////
189 // Function: PStatCollector::is_active
190 // Access: Published
191 // Description: Returns true if this particular collector is active
192 // on the default thread, and we are currently
193 // transmitting PStats data.
194 ////////////////////////////////////////////////////////////////////
195 INLINE bool PStatCollector::
196 is_active() {
197 #ifndef HAVE_THREADS
198  return _client->is_active(_index, 0);
199 #else // HAVE_THREADS
200  return is_active(_client->get_current_thread());
201 #endif // HAVE_THREADS
202 }
203 
204 ////////////////////////////////////////////////////////////////////
205 // Function: PStatCollector::is_started
206 // Access: Published
207 // Description: Returns true if this particular collector has been
208 // started on the default thread, or false otherwise.
209 ////////////////////////////////////////////////////////////////////
210 INLINE bool PStatCollector::
211 is_started() {
212 #ifndef HAVE_THREADS
213  return _client->is_started(_index, 0);
214 #else // HAVE_THREADS
215  return is_started(_client->get_current_thread());
216 #endif // HAVE_THREADS
217 }
218 
219 ////////////////////////////////////////////////////////////////////
220 // Function: PStatCollector::start
221 // Access: Published
222 // Description: Starts this particular timer ticking. This should be
223 // called before the code you want to measure.
224 ////////////////////////////////////////////////////////////////////
225 INLINE void PStatCollector::
226 start() {
227 #ifndef HAVE_THREADS
228  _client->start(_index, 0);
229 #else // HAVE_THREADS
230  start(_client->get_current_thread());
231 #endif // HAVE_THREADS
232 }
233 
234 ////////////////////////////////////////////////////////////////////
235 // Function: PStatCollector::stop
236 // Access: Published
237 // Description: Stops this timer. This should be called after the
238 // code you want to measure.
239 ////////////////////////////////////////////////////////////////////
240 INLINE void PStatCollector::
241 stop() {
242 #ifndef HAVE_THREADS
243  _client->stop(_index, 0);
244 #else // HAVE_THREADS
245  stop(_client->get_current_thread());
246 #endif // HAVE_THREADS
247 }
248 
249 ////////////////////////////////////////////////////////////////////
250 // Function: PStatCollector::clear_level
251 // Access: Published
252 // Description: Removes the level setting associated with this
253 // collector for the main thread. The collector
254 // will no longer show up on any level graphs in the
255 // main thread. This implicitly calls flush_level().
256 ////////////////////////////////////////////////////////////////////
257 INLINE void PStatCollector::
258 clear_level() {
259  _client->clear_level(_index, 0);
260  _level = 0.0f;
261 }
262 
263 ////////////////////////////////////////////////////////////////////
264 // Function: PStatCollector::set_level
265 // Access: Published
266 // Description: Sets the level setting associated with this
267 // collector for the main thread to the indicated
268 // value. This implicitly calls flush_level().
269 ////////////////////////////////////////////////////////////////////
270 INLINE void PStatCollector::
271 set_level(double level) {
272  _client->set_level(_index, 0, level);
273  _level = 0.0f;
274 }
275 
276 ////////////////////////////////////////////////////////////////////
277 // Function: PStatCollector::add_level
278 // Access: Published
279 // Description: Adds the indicated increment (which may be negative)
280 // to the level setting associated with this collector
281 // for the main thread. If the collector did not
282 // already have a level setting for the main thread, it
283 // is initialized to 0.
284 //
285 // As an optimization, the data is not immediately set
286 // to the PStatClient. It will be sent the next time
287 // flush_level() is called.
288 ////////////////////////////////////////////////////////////////////
289 INLINE void PStatCollector::
290 add_level(double increment) {
291  _level += increment;
292 }
293 
294 ////////////////////////////////////////////////////////////////////
295 // Function: PStatCollector::sub_level
296 // Access: Published
297 // Description: Subtracts the indicated decrement (which may be
298 // negative) to the level setting associated with this
299 // collector for the main thread. If the collector did
300 // not already have a level setting for the main thread,
301 // it is initialized to 0.
302 //
303 // As an optimization, the data is not immediately set
304 // to the PStatClient. It will be sent the next time
305 // flush_level() is called.
306 ////////////////////////////////////////////////////////////////////
307 INLINE void PStatCollector::
308 sub_level(double decrement) {
309  _level -= decrement;
310 }
311 
312 ////////////////////////////////////////////////////////////////////
313 // Function: PStatCollector::add_level_now
314 // Access: Published
315 // Description: Calls add_level() and immediately calls flush_level().
316 ////////////////////////////////////////////////////////////////////
317 INLINE void PStatCollector::
318 add_level_now(double increment) {
319  add_level(increment);
320  flush_level();
321 }
322 
323 ////////////////////////////////////////////////////////////////////
324 // Function: PStatCollector::sub_level_now
325 // Access: Published
326 // Description: Calls sub_level() and immediately calls flush_level().
327 ////////////////////////////////////////////////////////////////////
328 INLINE void PStatCollector::
329 sub_level_now(double decrement) {
330  sub_level(decrement);
331  flush_level();
332 }
333 
334 ////////////////////////////////////////////////////////////////////
335 // Function: PStatCollector::flush_level
336 // Access: Published
337 // Description: Updates the PStatClient with the recent results from
338 // add_level() and sub_level().
339 ////////////////////////////////////////////////////////////////////
340 INLINE void PStatCollector::
341 flush_level() {
342  if (_level != 0.0f) {
343  _client->add_level(_index, 0, _level);
344  _level = 0.0f;
345  }
346 }
347 
348 ////////////////////////////////////////////////////////////////////
349 // Function: PStatCollector::get_level
350 // Access: Published
351 // Description: Returns the current level value of the given
352 // collector in the main thread. This implicitly calls
353 // flush_level().
354 ////////////////////////////////////////////////////////////////////
355 INLINE double PStatCollector::
356 get_level() {
357  flush_level();
358  return _client->get_level(_index, 0);
359 }
360 
361 ////////////////////////////////////////////////////////////////////
362 // Function: PStatCollector::clear_thread_level
363 // Access: Published
364 // Description: Removes the level setting associated with this
365 // collector for the current thread. The collector
366 // will no longer show up on any level graphs in the
367 // current thread.
368 ////////////////////////////////////////////////////////////////////
369 INLINE void PStatCollector::
370 clear_thread_level() {
371 #ifndef HAVE_THREADS
372  _client->clear_level(_index, 0);
373 #else // HAVE_THREADS
374  clear_level(_client->get_current_thread());
375 #endif // HAVE_THREADS
376 }
377 
378 ////////////////////////////////////////////////////////////////////
379 // Function: PStatCollector::set_thread_level
380 // Access: Published
381 // Description: Sets the level setting associated with this
382 // collector for the current thread to the indicated
383 // value.
384 ////////////////////////////////////////////////////////////////////
385 INLINE void PStatCollector::
386 set_thread_level(double level) {
387 #ifndef HAVE_THREADS
388  _client->set_level(_index, 0, level);
389 #else // HAVE_THREADS
390  set_level(_client->get_current_thread(), level);
391 #endif // HAVE_THREADS
392 }
393 
394 ////////////////////////////////////////////////////////////////////
395 // Function: PStatCollector::add_thread_level
396 // Access: Published
397 // Description: Adds the indicated increment (which may be negative)
398 // to the level setting associated with this collector
399 // for the current thread. If the collector did not
400 // already have a level setting for the current thread,
401 // it is initialized to 0.
402 ////////////////////////////////////////////////////////////////////
403 INLINE void PStatCollector::
404 add_thread_level(double increment) {
405 #ifndef HAVE_THREADS
406  _client->add_level(_index, 0, increment);
407 #else // HAVE_THREADS
408  add_level(_client->get_current_thread(), increment);
409 #endif // HAVE_THREADS
410 }
411 
412 ////////////////////////////////////////////////////////////////////
413 // Function: PStatCollector::sub_thread_level
414 // Access: Published
415 // Description: Subtracts the indicated decrement (which may be
416 // negative) to the level setting associated with this
417 // collector for the current thread. If the collector
418 // did not already have a level setting for the current
419 // thread, it is initialized to 0.
420 ////////////////////////////////////////////////////////////////////
421 INLINE void PStatCollector::
422 sub_thread_level(double decrement) {
423 #ifndef HAVE_THREADS
424  _client->add_level(_index, 0, -decrement);
425 #else // HAVE_THREADS
426  sub_level(_client->get_current_thread(), decrement);
427 #endif // HAVE_THREADS
428 }
429 
430 ////////////////////////////////////////////////////////////////////
431 // Function: PStatCollector::get_thread_level
432 // Access: Published
433 // Description: Returns the current level value of the given
434 // collector in the current thread.
435 ////////////////////////////////////////////////////////////////////
436 INLINE double PStatCollector::
437 get_thread_level() {
438 #ifndef HAVE_THREADS
439  return _client->get_level(_index, 0);
440 #else // HAVE_THREADS
441  return get_level(_client->get_current_thread());
442 #endif // HAVE_THREADS
443 }
444 
445 ////////////////////////////////////////////////////////////////////
446 // Function: PStatCollector::is_active
447 // Access: Published
448 // Description: Returns true if this particular collector is active
449 // on the indicated thread, and we are currently
450 // transmitting PStats data.
451 ////////////////////////////////////////////////////////////////////
452 INLINE bool PStatCollector::
453 is_active(const PStatThread &thread) {
454  return _client->is_active(_index, thread._index);
455 }
456 
457 ////////////////////////////////////////////////////////////////////
458 // Function: PStatCollector::is_started
459 // Access: Published
460 // Description: Returns true if this particular collector has been
461 // started on the indicated thread, or false otherwise.
462 ////////////////////////////////////////////////////////////////////
463 INLINE bool PStatCollector::
464 is_started(const PStatThread &thread) {
465  return _client->is_started(_index, thread._index);
466 }
467 
468 ////////////////////////////////////////////////////////////////////
469 // Function: PStatCollector::start
470 // Access: Published
471 // Description: Starts this timer ticking within a particular thread.
472 ////////////////////////////////////////////////////////////////////
473 INLINE void PStatCollector::
474 start(const PStatThread &thread) {
475  nassertv(_client != NULL);
476  _client->start(_index, thread._index);
477 }
478 
479 ////////////////////////////////////////////////////////////////////
480 // Function: PStatCollector::start
481 // Access: Published
482 // Description: Marks that the timer should have been started as of
483 // the indicated time. This must be a time based on the
484 // PStatClient's clock (see PStatClient::get_clock()),
485 // and care should be taken that all such calls exhibit
486 // a monotonically increasing series of time values.
487 ////////////////////////////////////////////////////////////////////
488 INLINE void PStatCollector::
489 start(const PStatThread &thread, double as_of) {
490  _client->start(_index, thread._index, as_of);
491 }
492 
493 ////////////////////////////////////////////////////////////////////
494 // Function: PStatCollector::stop
495 // Access: Published
496 // Description: Stops this timer within a particular thread.
497 ////////////////////////////////////////////////////////////////////
498 INLINE void PStatCollector::
499 stop(const PStatThread &thread) {
500  _client->stop(_index, thread._index);
501 }
502 
503 ////////////////////////////////////////////////////////////////////
504 // Function: PStatCollector::stop
505 // Access: Published
506 // Description: Marks that the timer should have been stopped as of
507 // the indicated time. This must be a time based on the
508 // PStatClient's clock (see PStatClient::get_clock()),
509 // and care should be taken that all such calls exhibit
510 // a monotonically increasing series of time values.
511 ////////////////////////////////////////////////////////////////////
512 INLINE void PStatCollector::
513 stop(const PStatThread &thread, double as_of) {
514  _client->stop(_index, thread._index, as_of);
515 }
516 
517 ////////////////////////////////////////////////////////////////////
518 // Function: PStatCollector::clear_level
519 // Access: Published
520 // Description: Removes the level setting associated with this
521 // collector for the indicated thread. The collector
522 // will no longer show up on any level graphs in this
523 // thread.
524 ////////////////////////////////////////////////////////////////////
525 INLINE void PStatCollector::
526 clear_level(const PStatThread &thread) {
527  _client->clear_level(_index, thread._index);
528 }
529 
530 ////////////////////////////////////////////////////////////////////
531 // Function: PStatCollector::set_level
532 // Access: Published
533 // Description: Sets the level setting associated with this
534 // collector for the indicated thread to the indicated
535 // value.
536 ////////////////////////////////////////////////////////////////////
537 INLINE void PStatCollector::
538 set_level(const PStatThread &thread, double level) {
539  _client->set_level(_index, thread._index, level);
540 }
541 
542 ////////////////////////////////////////////////////////////////////
543 // Function: PStatCollector::add_level
544 // Access: Published
545 // Description: Adds the indicated increment (which may be negative)
546 // to the level setting associated with this collector
547 // for the indicated thread. If the collector did not
548 // already have a level setting for this thread, it is
549 // initialized to 0.
550 ////////////////////////////////////////////////////////////////////
551 INLINE void PStatCollector::
552 add_level(const PStatThread &thread, double increment) {
553  _client->add_level(_index, thread._index, increment);
554 }
555 
556 ////////////////////////////////////////////////////////////////////
557 // Function: PStatCollector::sub_level
558 // Access: Published
559 // Description: Subtracts the indicated decrement (which may be
560 // negative) to the level setting associated with this
561 // collector for the indicated thread. If the collector
562 // did not already have a level setting for this thread,
563 // it is initialized to 0.
564 ////////////////////////////////////////////////////////////////////
565 INLINE void PStatCollector::
566 sub_level(const PStatThread &thread, double decrement) {
567  _client->add_level(_index, thread._index, -decrement);
568 }
569 
570 ////////////////////////////////////////////////////////////////////
571 // Function: PStatCollector::get_level
572 // Access: Published
573 // Description: Returns the current level value of the given collector.
574 ////////////////////////////////////////////////////////////////////
575 INLINE double PStatCollector::
576 get_level(const PStatThread &thread) {
577  return _client->get_level(_index, thread._index);
578 }
579 
580 ////////////////////////////////////////////////////////////////////
581 // Function: PStatCollector::get_index
582 // Access: Published
583 // Description: Returns the index number of this particular collector
584 // within the PStatClient.
585 ////////////////////////////////////////////////////////////////////
586 INLINE int PStatCollector::
587 get_index() const {
588  return _index;
589 }
590 
591 #else // DO_PSTATS
592 
593 ////////////////////////////////////////////////////////////////////
594 // Function: PStatCollector::Default Constructor
595 // Access: Public
596 // Description: Creates an invalid PStatCollector. Any attempt to
597 // use this collector will crash messily.
598 //
599 // You can reassign it to a different, valid one later.
600 ////////////////////////////////////////////////////////////////////
601 INLINE PStatCollector::
603 {
604 }
605 
606 ////////////////////////////////////////////////////////////////////
607 // Function: PStatCollector::Constructor
608 // Access: Published
609 // Description: This bogus version of the function is only defined if
610 // DO_PSTATS is not defined, meaning all these functions
611 // should compile to nothing.
612 ////////////////////////////////////////////////////////////////////
613 INLINE PStatCollector::
614 PStatCollector(const string &, PStatClient *client) {
615  // We need this bogus comparison just to prevent the SGI compiler
616  // from dumping core. It's perfectly meaningless.
617 #ifdef mips
618  if (client == (PStatClient *)NULL) {
619  return;
620  }
621 #endif
622 }
623 
624 ////////////////////////////////////////////////////////////////////
625 // Function: PStatCollector::Constructor
626 // Access: Published
627 // Description: This bogus version of the function is only defined if
628 // DO_PSTATS is not defined, meaning all these functions
629 // should compile to nothing.
630 ////////////////////////////////////////////////////////////////////
631 INLINE PStatCollector::
632 PStatCollector(const PStatCollector &parent, const string &) {
633  // We need this bogus comparison just to prevent the SGI compiler
634  // from dumping core. It's perfectly meaningless.
635 #ifdef mips
636  if (&parent == (const PStatCollector *)NULL) {
637  return;
638  }
639 #endif
640 }
641 
642 
643 #endif // DO_PSTATS
A lightweight class that represents a single element that may be timed and/or counted via stats...
A lightweight class that represents a single thread of execution to PStats.
Definition: pStatThread.h:31
PStatCollector()
Creates an invalid PStatCollector.
Manages the communications to report statistics via a network connection to a remote PStatServer...
Definition: pStatClient.h:261