00001 // Filename: pStatCollector.I 00002 // Created by: drose (10Jul00) 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 00016 #ifdef DO_PSTATS 00017 00018 //////////////////////////////////////////////////////////////////// 00019 // Function: PStatCollector::Constructor 00020 // Access: Private 00021 // Description: Normally, this constructor is called only from 00022 // PStatClient. Use one of the constructors below to 00023 // create your own Collector. 00024 //////////////////////////////////////////////////////////////////// 00025 INLINE PStatCollector:: 00026 PStatCollector(PStatClient *client, int index) : 00027 _client(client), 00028 _index(index), 00029 _level(0.0f) 00030 { 00031 } 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: PStatCollector::Default Constructor 00035 // Access: Public 00036 // Description: Creates an invalid PStatCollector. Any attempt to 00037 // use this collector will crash messily. 00038 // 00039 // You can reassign it to a different, valid one later. 00040 //////////////////////////////////////////////////////////////////// 00041 INLINE PStatCollector:: 00042 PStatCollector() : 00043 _client(NULL), 00044 _index(0), 00045 _level(0.0f) 00046 { 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: PStatCollector::Constructor 00051 // Access: Published 00052 // Description: Creates a new PStatCollector, ready to start 00053 // accumulating data. The name of the collector 00054 // uniquely identifies it among the other collectors; if 00055 // two collectors share the same name then they are 00056 // really the same collector. 00057 // 00058 // The name may also be a compound name, something like 00059 // "Cull:Sort", which indicates that this is a collector 00060 // named "Sort", a child of the collector named "Cull". 00061 // The parent may also be named explicitly by reference 00062 // in the other flavor of the constructor; see further 00063 // comments on this for that constructor. 00064 // 00065 // If the client pointer is non-null, it specifies a 00066 // particular client to register the collector with; 00067 // otherwise, the global client is used. 00068 //////////////////////////////////////////////////////////////////// 00069 INLINE PStatCollector:: 00070 PStatCollector(const string &name, PStatClient *client) : 00071 _level(0.0f) 00072 { 00073 if (client == (PStatClient *)NULL) { 00074 client = PStatClient::get_global_pstats(); 00075 } 00076 (*this) = client->make_collector_with_relname(0, name); 00077 } 00078 00079 //////////////////////////////////////////////////////////////////// 00080 // Function: PStatCollector::Constructor 00081 // Access: Published 00082 // Description: Creates a new PStatCollector, ready to start 00083 // accumulating data. The name of the collector 00084 // uniquely identifies it among the other collectors; if 00085 // two collectors share the same name then they are 00086 // really the same collector. 00087 // 00088 // The parent is the collector that conceptually 00089 // includes all of the time measured for this collector. 00090 // For instance, a particular character's animation time 00091 // is owned by the "Animation" collector, which is in 00092 // turn owned by the "Frame" collector. It is not 00093 // strictly necessary that all of the time spent in a 00094 // particular collector is completely nested within time 00095 // spent in its parent's collector. If parent is the 00096 // empty string, the collector is owned by "Frame". 00097 // 00098 // This constructor does not take a client pointer; it 00099 // always creates the new collector on the same client 00100 // as its parent. 00101 //////////////////////////////////////////////////////////////////// 00102 INLINE PStatCollector:: 00103 PStatCollector(const PStatCollector &parent, const string &name) : 00104 _level(0.0f) 00105 { 00106 nassertv(parent._client != (PStatClient *)NULL); 00107 (*this) = 00108 parent._client->make_collector_with_relname(parent._index, name); 00109 } 00110 00111 //////////////////////////////////////////////////////////////////// 00112 // Function: PStatCollector::Copy Constructor 00113 // Access: Published 00114 // Description: 00115 //////////////////////////////////////////////////////////////////// 00116 INLINE PStatCollector:: 00117 PStatCollector(const PStatCollector ©) : 00118 _client(copy._client), 00119 _index(copy._index), 00120 _level(0.0f) 00121 { 00122 } 00123 00124 //////////////////////////////////////////////////////////////////// 00125 // Function: PStatCollector::Copy Assignment Operator 00126 // Access: Published 00127 // Description: 00128 //////////////////////////////////////////////////////////////////// 00129 INLINE void PStatCollector:: 00130 operator = (const PStatCollector ©) { 00131 _client = copy._client; 00132 _index = copy._index; 00133 } 00134 00135 //////////////////////////////////////////////////////////////////// 00136 // Function: PStatCollector::is_valid 00137 // Access: Published 00138 // Description: Returns true if collector is valid and may be used, 00139 // or false if it was constructed with the default 00140 // constructor (in which case any attempt to use it will 00141 // crash). 00142 //////////////////////////////////////////////////////////////////// 00143 INLINE bool PStatCollector:: 00144 is_valid() const { 00145 return (_client != (PStatClient *)NULL); 00146 } 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: PStatCollector::get_name 00150 // Access: Published 00151 // Description: Returns the local name of this collector. This is 00152 // the rightmost part of the fullname, after the 00153 // rightmost colon. 00154 //////////////////////////////////////////////////////////////////// 00155 INLINE string PStatCollector:: 00156 get_name() const { 00157 if (_client != (PStatClient *)NULL) { 00158 return _client->get_collector_name(_index); 00159 } 00160 return string(); 00161 } 00162 00163 //////////////////////////////////////////////////////////////////// 00164 // Function: PStatCollector::get_fullname 00165 // Access: Published 00166 // Description: Returns the full name of this collector. This 00167 // includes the names of all the collector's parents, 00168 // concatenated together with colons. 00169 //////////////////////////////////////////////////////////////////// 00170 INLINE string PStatCollector:: 00171 get_fullname() const { 00172 if (_client != (PStatClient *)NULL) { 00173 return _client->get_collector_fullname(_index); 00174 } 00175 return string(); 00176 } 00177 00178 //////////////////////////////////////////////////////////////////// 00179 // Function: PStatCollector::output 00180 // Access: Published 00181 // Description: 00182 //////////////////////////////////////////////////////////////////// 00183 INLINE void PStatCollector:: 00184 output(ostream &out) const { 00185 out << "PStatCollector(\"" << get_fullname() << "\")"; 00186 } 00187 00188 //////////////////////////////////////////////////////////////////// 00189 // Function: PStatCollector::is_active 00190 // Access: Published 00191 // Description: Returns true if this particular collector is active 00192 // on the default thread, and we are currently 00193 // transmitting PStats data. 00194 //////////////////////////////////////////////////////////////////// 00195 INLINE bool PStatCollector:: 00196 is_active() { 00197 #ifndef HAVE_THREADS 00198 return _client->is_active(_index, 0); 00199 #else // HAVE_THREADS 00200 return is_active(_client->get_current_thread()); 00201 #endif // HAVE_THREADS 00202 } 00203 00204 //////////////////////////////////////////////////////////////////// 00205 // Function: PStatCollector::is_started 00206 // Access: Published 00207 // Description: Returns true if this particular collector has been 00208 // started on the default thread, or false otherwise. 00209 //////////////////////////////////////////////////////////////////// 00210 INLINE bool PStatCollector:: 00211 is_started() { 00212 #ifndef HAVE_THREADS 00213 return _client->is_started(_index, 0); 00214 #else // HAVE_THREADS 00215 return is_started(_client->get_current_thread()); 00216 #endif // HAVE_THREADS 00217 } 00218 00219 //////////////////////////////////////////////////////////////////// 00220 // Function: PStatCollector::start 00221 // Access: Published 00222 // Description: Starts this particular timer ticking. This should be 00223 // called before the code you want to measure. 00224 //////////////////////////////////////////////////////////////////// 00225 INLINE void PStatCollector:: 00226 start() { 00227 #ifndef HAVE_THREADS 00228 _client->start(_index, 0); 00229 #else // HAVE_THREADS 00230 start(_client->get_current_thread()); 00231 #endif // HAVE_THREADS 00232 } 00233 00234 //////////////////////////////////////////////////////////////////// 00235 // Function: PStatCollector::stop 00236 // Access: Published 00237 // Description: Stops this timer. This should be called after the 00238 // code you want to measure. 00239 //////////////////////////////////////////////////////////////////// 00240 INLINE void PStatCollector:: 00241 stop() { 00242 #ifndef HAVE_THREADS 00243 _client->stop(_index, 0); 00244 #else // HAVE_THREADS 00245 stop(_client->get_current_thread()); 00246 #endif // HAVE_THREADS 00247 } 00248 00249 //////////////////////////////////////////////////////////////////// 00250 // Function: PStatCollector::clear_level 00251 // Access: Published 00252 // Description: Removes the level setting associated with this 00253 // collector for the main thread. The collector 00254 // will no longer show up on any level graphs in the 00255 // main thread. This implicitly calls flush_level(). 00256 //////////////////////////////////////////////////////////////////// 00257 INLINE void PStatCollector:: 00258 clear_level() { 00259 _client->clear_level(_index, 0); 00260 _level = 0.0f; 00261 } 00262 00263 //////////////////////////////////////////////////////////////////// 00264 // Function: PStatCollector::set_level 00265 // Access: Published 00266 // Description: Sets the level setting associated with this 00267 // collector for the main thread to the indicated 00268 // value. This implicitly calls flush_level(). 00269 //////////////////////////////////////////////////////////////////// 00270 INLINE void PStatCollector:: 00271 set_level(double level) { 00272 _client->set_level(_index, 0, level); 00273 _level = 0.0f; 00274 } 00275 00276 //////////////////////////////////////////////////////////////////// 00277 // Function: PStatCollector::add_level 00278 // Access: Published 00279 // Description: Adds the indicated increment (which may be negative) 00280 // to the level setting associated with this collector 00281 // for the main thread. If the collector did not 00282 // already have a level setting for the main thread, it 00283 // is initialized to 0. 00284 // 00285 // As an optimization, the data is not immediately set 00286 // to the PStatClient. It will be sent the next time 00287 // flush_level() is called. 00288 //////////////////////////////////////////////////////////////////// 00289 INLINE void PStatCollector:: 00290 add_level(double increment) { 00291 _level += increment; 00292 } 00293 00294 //////////////////////////////////////////////////////////////////// 00295 // Function: PStatCollector::sub_level 00296 // Access: Published 00297 // Description: Subtracts the indicated decrement (which may be 00298 // negative) to the level setting associated with this 00299 // collector for the main thread. If the collector did 00300 // not already have a level setting for the main thread, 00301 // it is initialized to 0. 00302 // 00303 // As an optimization, the data is not immediately set 00304 // to the PStatClient. It will be sent the next time 00305 // flush_level() is called. 00306 //////////////////////////////////////////////////////////////////// 00307 INLINE void PStatCollector:: 00308 sub_level(double decrement) { 00309 _level -= decrement; 00310 } 00311 00312 //////////////////////////////////////////////////////////////////// 00313 // Function: PStatCollector::add_level_now 00314 // Access: Published 00315 // Description: Calls add_level() and immediately calls flush_level(). 00316 //////////////////////////////////////////////////////////////////// 00317 INLINE void PStatCollector:: 00318 add_level_now(double increment) { 00319 add_level(increment); 00320 flush_level(); 00321 } 00322 00323 //////////////////////////////////////////////////////////////////// 00324 // Function: PStatCollector::sub_level_now 00325 // Access: Published 00326 // Description: Calls sub_level() and immediately calls flush_level(). 00327 //////////////////////////////////////////////////////////////////// 00328 INLINE void PStatCollector:: 00329 sub_level_now(double decrement) { 00330 sub_level(decrement); 00331 flush_level(); 00332 } 00333 00334 //////////////////////////////////////////////////////////////////// 00335 // Function: PStatCollector::flush_level 00336 // Access: Published 00337 // Description: Updates the PStatClient with the recent results from 00338 // add_level() and sub_level(). 00339 //////////////////////////////////////////////////////////////////// 00340 INLINE void PStatCollector:: 00341 flush_level() { 00342 if (_level != 0.0f) { 00343 _client->add_level(_index, 0, _level); 00344 _level = 0.0f; 00345 } 00346 } 00347 00348 //////////////////////////////////////////////////////////////////// 00349 // Function: PStatCollector::get_level 00350 // Access: Published 00351 // Description: Returns the current level value of the given 00352 // collector in the main thread. This implicitly calls 00353 // flush_level(). 00354 //////////////////////////////////////////////////////////////////// 00355 INLINE double PStatCollector:: 00356 get_level() { 00357 flush_level(); 00358 return _client->get_level(_index, 0); 00359 } 00360 00361 //////////////////////////////////////////////////////////////////// 00362 // Function: PStatCollector::clear_thread_level 00363 // Access: Published 00364 // Description: Removes the level setting associated with this 00365 // collector for the current thread. The collector 00366 // will no longer show up on any level graphs in the 00367 // current thread. 00368 //////////////////////////////////////////////////////////////////// 00369 INLINE void PStatCollector:: 00370 clear_thread_level() { 00371 #ifndef HAVE_THREADS 00372 _client->clear_level(_index, 0); 00373 #else // HAVE_THREADS 00374 clear_level(_client->get_current_thread()); 00375 #endif // HAVE_THREADS 00376 } 00377 00378 //////////////////////////////////////////////////////////////////// 00379 // Function: PStatCollector::set_thread_level 00380 // Access: Published 00381 // Description: Sets the level setting associated with this 00382 // collector for the current thread to the indicated 00383 // value. 00384 //////////////////////////////////////////////////////////////////// 00385 INLINE void PStatCollector:: 00386 set_thread_level(double level) { 00387 #ifndef HAVE_THREADS 00388 _client->set_level(_index, 0, level); 00389 #else // HAVE_THREADS 00390 set_level(_client->get_current_thread(), level); 00391 #endif // HAVE_THREADS 00392 } 00393 00394 //////////////////////////////////////////////////////////////////// 00395 // Function: PStatCollector::add_thread_level 00396 // Access: Published 00397 // Description: Adds the indicated increment (which may be negative) 00398 // to the level setting associated with this collector 00399 // for the current thread. If the collector did not 00400 // already have a level setting for the current thread, 00401 // it is initialized to 0. 00402 //////////////////////////////////////////////////////////////////// 00403 INLINE void PStatCollector:: 00404 add_thread_level(double increment) { 00405 #ifndef HAVE_THREADS 00406 _client->add_level(_index, 0, increment); 00407 #else // HAVE_THREADS 00408 add_level(_client->get_current_thread(), increment); 00409 #endif // HAVE_THREADS 00410 } 00411 00412 //////////////////////////////////////////////////////////////////// 00413 // Function: PStatCollector::sub_thread_level 00414 // Access: Published 00415 // Description: Subtracts the indicated decrement (which may be 00416 // negative) to the level setting associated with this 00417 // collector for the current thread. If the collector 00418 // did not already have a level setting for the current 00419 // thread, it is initialized to 0. 00420 //////////////////////////////////////////////////////////////////// 00421 INLINE void PStatCollector:: 00422 sub_thread_level(double decrement) { 00423 #ifndef HAVE_THREADS 00424 _client->add_level(_index, 0, -decrement); 00425 #else // HAVE_THREADS 00426 sub_level(_client->get_current_thread(), decrement); 00427 #endif // HAVE_THREADS 00428 } 00429 00430 //////////////////////////////////////////////////////////////////// 00431 // Function: PStatCollector::get_thread_level 00432 // Access: Published 00433 // Description: Returns the current level value of the given 00434 // collector in the current thread. 00435 //////////////////////////////////////////////////////////////////// 00436 INLINE double PStatCollector:: 00437 get_thread_level() { 00438 #ifndef HAVE_THREADS 00439 return _client->get_level(_index, 0); 00440 #else // HAVE_THREADS 00441 return get_level(_client->get_current_thread()); 00442 #endif // HAVE_THREADS 00443 } 00444 00445 //////////////////////////////////////////////////////////////////// 00446 // Function: PStatCollector::is_active 00447 // Access: Published 00448 // Description: Returns true if this particular collector is active 00449 // on the indicated thread, and we are currently 00450 // transmitting PStats data. 00451 //////////////////////////////////////////////////////////////////// 00452 INLINE bool PStatCollector:: 00453 is_active(const PStatThread &thread) { 00454 return _client->is_active(_index, thread._index); 00455 } 00456 00457 //////////////////////////////////////////////////////////////////// 00458 // Function: PStatCollector::is_started 00459 // Access: Published 00460 // Description: Returns true if this particular collector has been 00461 // started on the indicated thread, or false otherwise. 00462 //////////////////////////////////////////////////////////////////// 00463 INLINE bool PStatCollector:: 00464 is_started(const PStatThread &thread) { 00465 return _client->is_started(_index, thread._index); 00466 } 00467 00468 //////////////////////////////////////////////////////////////////// 00469 // Function: PStatCollector::start 00470 // Access: Published 00471 // Description: Starts this timer ticking within a particular thread. 00472 //////////////////////////////////////////////////////////////////// 00473 INLINE void PStatCollector:: 00474 start(const PStatThread &thread) { 00475 nassertv(_client != NULL); 00476 _client->start(_index, thread._index); 00477 } 00478 00479 //////////////////////////////////////////////////////////////////// 00480 // Function: PStatCollector::start 00481 // Access: Published 00482 // Description: Marks that the timer should have been started as of 00483 // the indicated time. This must be a time based on the 00484 // PStatClient's clock (see PStatClient::get_clock()), 00485 // and care should be taken that all such calls exhibit 00486 // a monotonically increasing series of time values. 00487 //////////////////////////////////////////////////////////////////// 00488 INLINE void PStatCollector:: 00489 start(const PStatThread &thread, double as_of) { 00490 _client->start(_index, thread._index, as_of); 00491 } 00492 00493 //////////////////////////////////////////////////////////////////// 00494 // Function: PStatCollector::stop 00495 // Access: Published 00496 // Description: Stops this timer within a particular thread. 00497 //////////////////////////////////////////////////////////////////// 00498 INLINE void PStatCollector:: 00499 stop(const PStatThread &thread) { 00500 _client->stop(_index, thread._index); 00501 } 00502 00503 //////////////////////////////////////////////////////////////////// 00504 // Function: PStatCollector::stop 00505 // Access: Published 00506 // Description: Marks that the timer should have been stopped as of 00507 // the indicated time. This must be a time based on the 00508 // PStatClient's clock (see PStatClient::get_clock()), 00509 // and care should be taken that all such calls exhibit 00510 // a monotonically increasing series of time values. 00511 //////////////////////////////////////////////////////////////////// 00512 INLINE void PStatCollector:: 00513 stop(const PStatThread &thread, double as_of) { 00514 _client->stop(_index, thread._index, as_of); 00515 } 00516 00517 //////////////////////////////////////////////////////////////////// 00518 // Function: PStatCollector::clear_level 00519 // Access: Published 00520 // Description: Removes the level setting associated with this 00521 // collector for the indicated thread. The collector 00522 // will no longer show up on any level graphs in this 00523 // thread. 00524 //////////////////////////////////////////////////////////////////// 00525 INLINE void PStatCollector:: 00526 clear_level(const PStatThread &thread) { 00527 _client->clear_level(_index, thread._index); 00528 } 00529 00530 //////////////////////////////////////////////////////////////////// 00531 // Function: PStatCollector::set_level 00532 // Access: Published 00533 // Description: Sets the level setting associated with this 00534 // collector for the indicated thread to the indicated 00535 // value. 00536 //////////////////////////////////////////////////////////////////// 00537 INLINE void PStatCollector:: 00538 set_level(const PStatThread &thread, double level) { 00539 _client->set_level(_index, thread._index, level); 00540 } 00541 00542 //////////////////////////////////////////////////////////////////// 00543 // Function: PStatCollector::add_level 00544 // Access: Published 00545 // Description: Adds the indicated increment (which may be negative) 00546 // to the level setting associated with this collector 00547 // for the indicated thread. If the collector did not 00548 // already have a level setting for this thread, it is 00549 // initialized to 0. 00550 //////////////////////////////////////////////////////////////////// 00551 INLINE void PStatCollector:: 00552 add_level(const PStatThread &thread, double increment) { 00553 _client->add_level(_index, thread._index, increment); 00554 } 00555 00556 //////////////////////////////////////////////////////////////////// 00557 // Function: PStatCollector::sub_level 00558 // Access: Published 00559 // Description: Subtracts the indicated decrement (which may be 00560 // negative) to the level setting associated with this 00561 // collector for the indicated thread. If the collector 00562 // did not already have a level setting for this thread, 00563 // it is initialized to 0. 00564 //////////////////////////////////////////////////////////////////// 00565 INLINE void PStatCollector:: 00566 sub_level(const PStatThread &thread, double decrement) { 00567 _client->add_level(_index, thread._index, -decrement); 00568 } 00569 00570 //////////////////////////////////////////////////////////////////// 00571 // Function: PStatCollector::get_level 00572 // Access: Published 00573 // Description: Returns the current level value of the given collector. 00574 //////////////////////////////////////////////////////////////////// 00575 INLINE double PStatCollector:: 00576 get_level(const PStatThread &thread) { 00577 return _client->get_level(_index, thread._index); 00578 } 00579 00580 //////////////////////////////////////////////////////////////////// 00581 // Function: PStatCollector::get_index 00582 // Access: Published 00583 // Description: Returns the index number of this particular collector 00584 // within the PStatClient. 00585 //////////////////////////////////////////////////////////////////// 00586 INLINE int PStatCollector:: 00587 get_index() const { 00588 return _index; 00589 } 00590 00591 #else // DO_PSTATS 00592 00593 //////////////////////////////////////////////////////////////////// 00594 // Function: PStatCollector::Default Constructor 00595 // Access: Public 00596 // Description: Creates an invalid PStatCollector. Any attempt to 00597 // use this collector will crash messily. 00598 // 00599 // You can reassign it to a different, valid one later. 00600 //////////////////////////////////////////////////////////////////// 00601 INLINE PStatCollector:: 00602 PStatCollector() 00603 { 00604 } 00605 00606 //////////////////////////////////////////////////////////////////// 00607 // Function: PStatCollector::Constructor 00608 // Access: Published 00609 // Description: This bogus version of the function is only defined if 00610 // DO_PSTATS is not defined, meaning all these functions 00611 // should compile to nothing. 00612 //////////////////////////////////////////////////////////////////// 00613 INLINE PStatCollector:: 00614 PStatCollector(const string &, PStatClient *client) { 00615 // We need this bogus comparison just to prevent the SGI compiler 00616 // from dumping core. It's perfectly meaningless. 00617 #ifdef mips 00618 if (client == (PStatClient *)NULL) { 00619 return; 00620 } 00621 #endif 00622 } 00623 00624 //////////////////////////////////////////////////////////////////// 00625 // Function: PStatCollector::Constructor 00626 // Access: Published 00627 // Description: This bogus version of the function is only defined if 00628 // DO_PSTATS is not defined, meaning all these functions 00629 // should compile to nothing. 00630 //////////////////////////////////////////////////////////////////// 00631 INLINE PStatCollector:: 00632 PStatCollector(const PStatCollector &parent, const string &) { 00633 // We need this bogus comparison just to prevent the SGI compiler 00634 // from dumping core. It's perfectly meaningless. 00635 #ifdef mips 00636 if (&parent == (const PStatCollector *)NULL) { 00637 return; 00638 } 00639 #endif 00640 } 00641 00642 00643 #endif // DO_PSTATS