00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "pStatThreadData.h"
00016
00017 #include "pStatFrameData.h"
00018 #include "pStatCollectorDef.h"
00019 #include "config_pstats.h"
00020
00021
00022 PStatFrameData PStatThreadData::_null_frame;
00023
00024
00025
00026
00027
00028
00029 PStatThreadData::
00030 PStatThreadData(const PStatClientData *client_data) :
00031 _client_data(client_data)
00032 {
00033 _first_frame_number = 0;
00034 _history = pstats_history;
00035 _computed_elapsed_frames = false;
00036 }
00037
00038
00039
00040
00041
00042
00043 PStatThreadData::
00044 ~PStatThreadData() {
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054 bool PStatThreadData::
00055 is_empty() const {
00056 return _frames.empty();
00057 }
00058
00059
00060
00061
00062
00063
00064
00065 int PStatThreadData::
00066 get_latest_frame_number() const {
00067 nassertr(!_frames.empty(), 0);
00068 return _first_frame_number + _frames.size() - 1;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077 int PStatThreadData::
00078 get_oldest_frame_number() const {
00079 nassertr(!_frames.empty(), 0);
00080 return _first_frame_number;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090 bool PStatThreadData::
00091 has_frame(int frame_number) const {
00092 int rel_frame = frame_number - _first_frame_number;
00093
00094 return (rel_frame >= 0 && rel_frame < (int)_frames.size() &&
00095 _frames[rel_frame] != (PStatFrameData *)NULL);
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 const PStatFrameData &PStatThreadData::
00107 get_frame(int frame_number) const {
00108 int rel_frame = frame_number - _first_frame_number;
00109 int num_frames = _frames.size();
00110 if (rel_frame >= num_frames) {
00111 rel_frame = num_frames - 1;
00112 }
00113
00114 while (rel_frame >= 0 && _frames[rel_frame] == (PStatFrameData *)NULL) {
00115 rel_frame--;
00116 }
00117 if (rel_frame < 0) {
00118
00119 rel_frame = 0;
00120 while (rel_frame < num_frames &&
00121 _frames[rel_frame] == (PStatFrameData *)NULL) {
00122 rel_frame++;
00123 }
00124 }
00125
00126 if (rel_frame >= 0 && rel_frame < num_frames) {
00127 PStatFrameData *frame = _frames[rel_frame];
00128 nassertr(frame != (PStatFrameData *)NULL, _null_frame);
00129 nassertr(frame->get_start() >= 0.0, _null_frame);
00130 return *frame;
00131 }
00132
00133 nassertr(_null_frame.get_start() >= 0.0, _null_frame);
00134 return _null_frame;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 double PStatThreadData::
00144 get_latest_time() const {
00145 nassertr(!_frames.empty(), 0.0);
00146 return _frames.back()->get_start();
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 double PStatThreadData::
00156 get_oldest_time() const {
00157 nassertr(!_frames.empty(), 0.0);
00158 return _frames.front()->get_start();
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 const PStatFrameData &PStatThreadData::
00168 get_frame_at_time(double time) const {
00169 return get_frame(get_frame_number_at_time(time));
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 int PStatThreadData::
00183 get_frame_number_at_time(double time, int hint) const {
00184 hint -= _first_frame_number;
00185 if (hint >= 0 && hint < (int)_frames.size()) {
00186 if (_frames[hint] != (PStatFrameData *)NULL &&
00187 _frames[hint]->get_start() <= time) {
00188
00189 int i = hint + 1;
00190 while (i < (int)_frames.size() &&
00191 (_frames[i] == (PStatFrameData *)NULL ||
00192 _frames[i]->get_start() <= time)) {
00193 if (_frames[i] != (PStatFrameData *)NULL) {
00194 hint = i;
00195 }
00196 ++i;
00197 }
00198 return _first_frame_number + hint;
00199 }
00200 }
00201
00202
00203
00204
00205 int i = _frames.size() - 1;
00206 while (i >= 0) {
00207 const PStatFrameData *frame = _frames[i];
00208 if (frame != (PStatFrameData *)NULL && frame->get_start() <= time) {
00209 break;
00210 }
00211 --i;
00212 }
00213
00214 return _first_frame_number + i;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223 const PStatFrameData &PStatThreadData::
00224 get_latest_frame() const {
00225 nassertr(!_frames.empty(), _null_frame);
00226 return *_frames.back();
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 bool PStatThreadData::
00239 get_elapsed_frames(int &then_i, int &now_i) const {
00240 if (!_computed_elapsed_frames) {
00241 ((PStatThreadData *)this)->compute_elapsed_frames();
00242 }
00243
00244 now_i = _now_i;
00245 then_i = _then_i;
00246 return _got_elapsed_frames;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256 double PStatThreadData::
00257 get_frame_rate() const {
00258 int then_i, now_i;
00259 if (!get_elapsed_frames(then_i, now_i)) {
00260 return 0.0f;
00261 }
00262
00263 int num_frames = now_i - then_i + 1;
00264 double now = _frames[now_i - _first_frame_number]->get_end();
00265 double elapsed_time = (now - _frames[then_i - _first_frame_number]->get_start());
00266 return (double)num_frames / elapsed_time;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 void PStatThreadData::
00279 set_history(double time) {
00280 _history = time;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 double PStatThreadData::
00292 get_history() const {
00293 return _history;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 void PStatThreadData::
00309 record_new_frame(int frame_number, PStatFrameData *frame_data) {
00310 nassertv(frame_data != (PStatFrameData *)NULL);
00311 nassertv(!frame_data->is_empty());
00312 double time = frame_data->get_start();
00313
00314
00315
00316 double oldest_allowable_time = time - _history;
00317 while (!_frames.empty() &&
00318 (_frames.front() == (PStatFrameData *)NULL ||
00319 _frames.front()->is_empty() ||
00320 _frames.front()->get_start() < oldest_allowable_time)) {
00321 if (_frames.front() != (PStatFrameData *)NULL) {
00322 delete _frames.front();
00323 }
00324 _frames.pop_front();
00325 _first_frame_number++;
00326 }
00327
00328
00329
00330
00331 if (_frames.empty()) {
00332 _first_frame_number = frame_number;
00333 _frames.push_back(NULL);
00334
00335 } else {
00336 while (_first_frame_number + (int)_frames.size() <= frame_number) {
00337 _frames.push_back(NULL);
00338 }
00339 }
00340
00341 int index = frame_number - _first_frame_number;
00342 nassertv(index >= 0 && index < (int)_frames.size());
00343
00344 if (_frames[index] != (PStatFrameData *)NULL) {
00345 nout << "Got repeated frame data for frame " << frame_number << "\n";
00346 delete _frames[index];
00347 }
00348
00349 _frames[index] = frame_data;
00350 _computed_elapsed_frames = false;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 void PStatThreadData::
00362 compute_elapsed_frames() {
00363 if (_frames.empty()) {
00364
00365 _got_elapsed_frames = false;
00366
00367 } else {
00368 _now_i = _frames.size() - 1;
00369 while (_now_i > 0 && _frames[_now_i] == (PStatFrameData *)NULL) {
00370 _now_i--;
00371 }
00372 if (_now_i < 0) {
00373
00374 _got_elapsed_frames = false;
00375
00376 } else {
00377 nassertv(_frames[_now_i] != (PStatFrameData *)NULL);
00378
00379 double now = _frames[_now_i]->get_end();
00380 double then = now - pstats_average_time;
00381
00382 int old_i = _now_i;
00383 _then_i = _now_i;
00384
00385 while (old_i >= 0) {
00386 const PStatFrameData *frame = _frames[old_i];
00387 if (frame != (PStatFrameData *)NULL) {
00388 if (frame->get_start() > then) {
00389 _then_i = old_i;
00390 } else {
00391 break;
00392 }
00393 }
00394 old_i--;
00395 }
00396
00397 nassertv(_then_i >= 0);
00398 nassertv(_frames[_then_i] != (PStatFrameData *)NULL);
00399 _got_elapsed_frames = true;
00400
00401 _now_i += _first_frame_number;
00402 _then_i += _first_frame_number;
00403 }
00404 }
00405
00406 _computed_elapsed_frames = true;
00407 }