00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "pStatStripChart.h"
00016 #include "pStatClientData.h"
00017 #include "pStatMonitor.h"
00018
00019 #include "pStatFrameData.h"
00020 #include "pStatCollectorDef.h"
00021 #include "string_utils.h"
00022 #include "config_pstats.h"
00023
00024 #include <algorithm>
00025
00026
00027
00028
00029
00030
00031 PStatStripChart::
00032 PStatStripChart(PStatMonitor *monitor, PStatView &view,
00033 int thread_index, int collector_index, int xsize, int ysize) :
00034 PStatGraph(monitor, xsize, ysize),
00035 _thread_index(thread_index),
00036 _view(view),
00037 _collector_index(collector_index)
00038 {
00039 _scroll_mode = pstats_scroll_mode;
00040 _average_mode = false;
00041
00042 _next_frame = 0;
00043 _first_data = true;
00044 _cursor_pixel = 0;
00045
00046 _time_width = 20.0;
00047 _value_height = 1.0/10.0;
00048 _start_time = 0.0;
00049
00050 _level_index = -1;
00051 _title_unknown = true;
00052
00053 const PStatClientData *client_data = _monitor->get_client_data();
00054 if (client_data->has_collector(_collector_index)) {
00055 const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
00056 _unit_name = def._level_units;
00057 }
00058
00059 set_default_vertical_scale();
00060 }
00061
00062
00063
00064
00065
00066
00067 PStatStripChart::
00068 ~PStatStripChart() {
00069 }
00070
00071
00072
00073
00074
00075
00076 void PStatStripChart::
00077 new_data(int frame_number) {
00078
00079
00080
00081 _next_frame = min(frame_number, _next_frame);
00082 }
00083
00084
00085
00086
00087
00088
00089 void PStatStripChart::
00090 update() {
00091 const PStatClientData *client_data = get_monitor()->get_client_data();
00092
00093
00094
00095 if (client_data->get_num_collectors() != 0 &&
00096 client_data->get_num_threads() != 0) {
00097 const PStatThreadData *thread_data = _view.get_thread_data();
00098 if (!thread_data->is_empty()) {
00099 int latest = thread_data->get_latest_frame_number();
00100
00101 if (latest > _next_frame) {
00102 draw_frames(_next_frame, latest);
00103 }
00104 _next_frame = latest;
00105
00106
00107 double oldest_time =
00108 thread_data->get_frame(latest).get_start() - _time_width;
00109
00110 Data::iterator di;
00111 di = _data.begin();
00112 while (di != _data.end() &&
00113 thread_data->get_frame((*di).first).get_start() < oldest_time) {
00114 dec_label_usage((*di).second);
00115 _data.erase(di);
00116 di = _data.begin();
00117 }
00118 }
00119 }
00120
00121 if (_level_index != _view.get_level_index()) {
00122 update_labels();
00123 }
00124
00125 idle();
00126 }
00127
00128
00129
00130
00131
00132
00133
00134 bool PStatStripChart::
00135 first_data() const {
00136 return _first_data;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145 void PStatStripChart::
00146 set_collector_index(int collector_index) {
00147 if (_collector_index != collector_index) {
00148 _collector_index = collector_index;
00149 _title_unknown = true;
00150 _data.clear();
00151 clear_label_usage();
00152 force_redraw();
00153 update_labels();
00154 }
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164 void PStatStripChart::
00165 set_default_vertical_scale() {
00166 const PStatClientData *client_data = _monitor->get_client_data();
00167 if (client_data->has_collector(_collector_index)) {
00168 const PStatCollectorDef &def =
00169 client_data->get_collector_def(_collector_index);
00170 if (def._suggested_scale != 0.0) {
00171 set_vertical_scale(def._suggested_scale);
00172 return;
00173 }
00174 }
00175
00176 set_vertical_scale(2.0 / get_target_frame_rate());
00177 }
00178
00179
00180
00181
00182
00183
00184 void PStatStripChart::
00185 set_auto_vertical_scale() {
00186 const PStatThreadData *thread_data = _view.get_thread_data();
00187
00188 double max_value = 0.0;
00189
00190 int frame_number = -1;
00191 for (int x = 0; x <= _xsize; x++) {
00192 double time = pixel_to_timestamp(x);
00193 frame_number =
00194 thread_data->get_frame_number_at_time(time, frame_number);
00195
00196 if (thread_data->has_frame(frame_number)) {
00197 double net_value = get_net_value(frame_number);
00198 max_value = max(max_value, net_value);
00199 }
00200 }
00201
00202
00203
00204 if (max_value == 0.0) {
00205 set_vertical_scale(1.0);
00206 } else {
00207 set_vertical_scale(max_value * 1.1);
00208 }
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218 int PStatStripChart::
00219 get_collector_under_pixel(int xpoint, int ypoint) {
00220
00221
00222 double time = pixel_to_timestamp(xpoint);
00223
00224
00225 const PStatThreadData *thread_data = _view.get_thread_data();
00226
00227
00228
00229 if (_average_mode) {
00230 double start_time = pixel_to_timestamp(xpoint);
00231 int then_i = thread_data->get_frame_number_at_time(start_time - pstats_average_time);
00232 int now_i = thread_data->get_frame_number_at_time(start_time, then_i);
00233
00234 FrameData fdata;
00235 compute_average_pixel_data(fdata, then_i, now_i, start_time);
00236 double overall_value = 0.0;
00237 int y = get_ysize();
00238
00239 FrameData::const_iterator fi;
00240 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
00241 const ColorData &cd = (*fi);
00242 overall_value += cd._net_value;
00243 y = height_to_pixel(overall_value);
00244 if (y <= ypoint) {
00245 return cd._collector_index;
00246 }
00247 }
00248
00249 } else {
00250 int frame_number = thread_data->get_frame_number_at_time(time);
00251 const FrameData &fdata = get_frame_data(frame_number);
00252 double overall_value = 0.0;
00253 int y = get_ysize();
00254
00255 FrameData::const_iterator fi;
00256 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
00257 const ColorData &cd = (*fi);
00258 overall_value += cd._net_value;
00259 y = height_to_pixel(overall_value);
00260 if (y <= ypoint) {
00261 return cd._collector_index;
00262 }
00263 }
00264 }
00265
00266 return -1;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 string PStatStripChart::
00276 get_title_text() {
00277 string text;
00278
00279 _title_unknown = false;
00280
00281 const PStatClientData *client_data = _monitor->get_client_data();
00282 if (client_data->has_collector(_collector_index)) {
00283 text = client_data->get_collector_fullname(_collector_index);
00284 const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
00285 if (_view.get_show_level()) {
00286 if (!def._level_units.empty()) {
00287 text += " (" + def._level_units + ")";
00288 }
00289 } else {
00290 text += " time";
00291 }
00292 } else {
00293 _title_unknown = true;
00294 }
00295
00296 if (_thread_index != 0) {
00297 if (client_data->has_thread(_thread_index)) {
00298 text += " (" + client_data->get_thread_name(_thread_index) + " thread)";
00299 } else {
00300 _title_unknown = true;
00301 }
00302 }
00303
00304 return text;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313 bool PStatStripChart::
00314 is_title_unknown() const {
00315 return _title_unknown;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324 void PStatStripChart::
00325 accumulate_frame_data(FrameData &fdata, const FrameData &additional,
00326 double weight) {
00327 FrameData::iterator ai;
00328 FrameData::const_iterator bi;
00329
00330 ai = fdata.begin();
00331 bi = additional.begin();
00332
00333 FrameData result;
00334
00335 if (fdata.size() == additional.size()) {
00336
00337
00338
00339 while (ai != fdata.end() &&
00340 (*ai)._collector_index == (*bi)._collector_index) {
00341 (*ai)._net_value += ((*bi)._net_value * weight);
00342 ++ai;
00343 ++bi;
00344 }
00345
00346 if (ai == fdata.end()) {
00347
00348
00349 return;
00350 }
00351
00352
00353
00354
00355 result.reserve(max(fdata.size(), additional.size()));
00356 FrameData::const_iterator ci;
00357 for (ci = fdata.begin(); ci != ai; ++ci) {
00358 result.push_back(*ci);
00359 }
00360
00361 } else {
00362
00363
00364 result.reserve(max(fdata.size(), additional.size()));
00365 }
00366
00367 while (ai != fdata.end() && bi != additional.end()) {
00368 if ((*ai)._i < (*bi)._i) {
00369
00370 result.push_back(*ai);
00371 ++ai;
00372
00373 } else if ((*bi)._i < (*ai)._i) {
00374
00375 ColorData scaled;
00376 scaled._collector_index = (*bi)._collector_index;
00377 scaled._i = (*bi)._i;
00378 scaled._net_value = (*bi)._net_value * weight;
00379 result.push_back(scaled);
00380 ++bi;
00381
00382 } else {
00383
00384 ColorData combined;
00385 combined._collector_index = (*ai)._collector_index;
00386 combined._i = (*bi)._i;
00387 combined._net_value = (*ai)._net_value + (*bi)._net_value * weight;
00388 result.push_back(combined);
00389 ++ai;
00390 ++bi;
00391 }
00392 }
00393
00394 while (ai != fdata.end()) {
00395
00396 result.push_back(*ai);
00397 ++ai;
00398 }
00399
00400 while (bi != additional.end()) {
00401
00402 ColorData scaled;
00403 scaled._collector_index = (*bi)._collector_index;
00404 scaled._i = (*bi)._i;
00405 scaled._net_value = (*bi)._net_value * weight;
00406 result.push_back(scaled);
00407 ++bi;
00408 }
00409
00410 fdata.swap(result);
00411 }
00412
00413
00414
00415
00416
00417
00418
00419 void PStatStripChart::
00420 scale_frame_data(FrameData &fdata, double factor) {
00421 FrameData::iterator fi;
00422 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
00423 (*fi)._net_value *= factor;
00424 }
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 const PStatStripChart::FrameData &PStatStripChart::
00437 get_frame_data(int frame_number) {
00438 Data::const_iterator di;
00439 di = _data.find(frame_number);
00440 if (di != _data.end()) {
00441 return (*di).second;
00442 }
00443
00444 const PStatThreadData *thread_data = _view.get_thread_data();
00445 _view.set_to_frame(thread_data->get_frame(frame_number));
00446
00447 FrameData &fdata = _data[frame_number];
00448
00449 const PStatViewLevel *level = _view.get_level(_collector_index);
00450 int num_children = level->get_num_children();
00451 for (int i = 0; i < num_children; i++) {
00452 const PStatViewLevel *child = level->get_child(i);
00453 ColorData cd;
00454 cd._collector_index = (unsigned short)child->get_collector();
00455 cd._i = (unsigned short)i;
00456 cd._net_value = child->get_net_value();
00457 if (cd._net_value != 0.0) {
00458 fdata.push_back(cd);
00459 }
00460 }
00461
00462
00463
00464 ColorData cd;
00465 cd._collector_index = (unsigned short)level->get_collector();
00466 cd._i = (unsigned short)num_children;
00467 cd._net_value = level->get_value_alone();
00468 if (cd._net_value > 0.0) {
00469 fdata.push_back(cd);
00470 }
00471
00472 inc_label_usage(fdata);
00473
00474 return fdata;
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 void PStatStripChart::
00493 compute_average_pixel_data(PStatStripChart::FrameData &result,
00494 int &then_i, int &now_i, double now) {
00495 result.clear();
00496
00497 const PStatThreadData *thread_data = _view.get_thread_data();
00498 if (thread_data->is_empty() || thread_data->get_oldest_time() > now) {
00499
00500 return;
00501 }
00502
00503 double then = now - pstats_average_time;
00504
00505 int latest_frame = thread_data->get_latest_frame_number();
00506 while (then_i <= latest_frame &&
00507 thread_data->get_frame(then_i).get_end() < then) {
00508 then_i++;
00509 }
00510 while (now_i <= latest_frame &&
00511 thread_data->get_frame(now_i).get_end() < now) {
00512 now_i++;
00513 }
00514
00515 then = max(then, thread_data->get_frame(then_i).get_start());
00516
00517
00518
00519
00520
00521
00522 accumulate_frame_data(result, get_frame_data(then_i),
00523 thread_data->get_frame(then_i).get_end() - then);
00524 double last = thread_data->get_frame(then_i).get_end();
00525
00526
00527 for (int frame_number = then_i + 1;
00528 frame_number < now_i;
00529 frame_number++) {
00530 accumulate_frame_data(result, get_frame_data(frame_number),
00531 thread_data->get_frame(frame_number).get_end() - last);
00532 last = thread_data->get_frame(frame_number).get_end();
00533 }
00534
00535
00536 if (last <= now) {
00537 accumulate_frame_data(result, get_frame_data(now_i), now - last);
00538 }
00539
00540 scale_frame_data(result, 1.0f / (now - then));
00541 }
00542
00543
00544
00545
00546
00547
00548
00549 double PStatStripChart::
00550 get_net_value(int frame_number) const {
00551 const FrameData &frame =
00552 ((PStatStripChart *)this)->get_frame_data(frame_number);
00553
00554 double net_value = 0.0;
00555 FrameData::const_iterator fi;
00556 for (fi = frame.begin(); fi != frame.end(); ++fi) {
00557 const ColorData &cd = (*fi);
00558 net_value += cd._net_value;
00559 }
00560
00561 return net_value;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570 double PStatStripChart::
00571 get_average_net_value() const {
00572 const PStatThreadData *thread_data = _view.get_thread_data();
00573 int now_i, then_i;
00574 if (!thread_data->get_elapsed_frames(then_i, now_i)) {
00575 return 0.0f;
00576 }
00577 double now = _time_width + _start_time;
00578 double then = now - pstats_average_time;
00579
00580 int num_frames = now_i - then_i + 1;
00581
00582 if (_collector_index == 0 && !_view.get_show_level()) {
00583
00584
00585
00586
00587
00588 const PStatFrameData &now_frame_data = thread_data->get_frame(now_i);
00589 const PStatFrameData &then_frame_data = thread_data->get_frame(then_i);
00590 double now = now_frame_data.get_end();
00591 double elapsed_time = (now - then_frame_data.get_start());
00592 return elapsed_time / (double)num_frames;
00593
00594 } else {
00595
00596
00597
00598
00599
00600 const PStatThreadData *thread_data = _view.get_thread_data();
00601
00602 double net_value = 0.0f;
00603 double net_time = 0.0f;
00604
00605
00606
00607
00608 if (thread_data->get_frame(then_i).get_end() > then) {
00609 double this_time = (thread_data->get_frame(then_i).get_end() - then);
00610 net_value += get_net_value(then_i) * this_time;
00611 net_time += this_time;
00612 }
00613
00614 for (int frame_number = then_i + 1;
00615 frame_number <= now_i;
00616 frame_number++) {
00617 double this_time = thread_data->get_frame(frame_number).get_net_time();
00618 net_value += get_net_value(frame_number) * this_time;
00619 net_time += this_time;
00620 }
00621
00622 return net_value / net_time;
00623 }
00624 }
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 void PStatStripChart::
00635 changed_size(int xsize, int ysize) {
00636 if (xsize != _xsize || ysize != _ysize) {
00637 _xsize = xsize;
00638 _ysize = ysize;
00639 if (_xsize > 0 && _ysize > 0) {
00640 _cursor_pixel = xsize * _cursor_pixel / _xsize;
00641
00642 if (!_first_data) {
00643 if (_scroll_mode) {
00644 draw_pixels(0, _xsize);
00645
00646 } else {
00647
00648 double old_start_time = _start_time;
00649
00650
00651 _start_time -= _time_width;
00652 draw_pixels(_cursor_pixel, _xsize);
00653
00654
00655 _start_time = old_start_time;
00656 draw_pixels(0, _cursor_pixel);
00657 }
00658 }
00659 }
00660 }
00661 }
00662
00663
00664
00665
00666
00667
00668
00669 void PStatStripChart::
00670 force_redraw() {
00671 if (!_first_data) {
00672 draw_pixels(0, _xsize);
00673 }
00674 }
00675
00676
00677
00678
00679
00680
00681
00682 void PStatStripChart::
00683 force_reset() {
00684 clear_region();
00685 _first_data = true;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695 void PStatStripChart::
00696 clear_region() {
00697 }
00698
00699
00700
00701
00702
00703
00704
00705
00706 void PStatStripChart::
00707 copy_region(int, int, int) {
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 void PStatStripChart::
00719 begin_draw(int, int) {
00720 }
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 void PStatStripChart::
00731 draw_slice(int, int, const PStatStripChart::FrameData &fdata) {
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741 void PStatStripChart::
00742 draw_empty(int, int) {
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752 void PStatStripChart::
00753 draw_cursor(int) {
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 void PStatStripChart::
00765 end_draw(int, int) {
00766 }
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 void PStatStripChart::
00778 idle() {
00779 }
00780
00781
00782
00783
00784 class SortCollectorLabels2 {
00785 public:
00786 SortCollectorLabels2(const PStatClientData *client_data) :
00787 _client_data(client_data) {
00788 }
00789 bool operator () (int a, int b) const {
00790 return
00791 _client_data->get_collector_def(a)._sort >
00792 _client_data->get_collector_def(b)._sort;
00793 }
00794 const PStatClientData *_client_data;
00795 };
00796
00797
00798
00799
00800
00801
00802 void PStatStripChart::
00803 update_labels() {
00804 const PStatViewLevel *level = _view.get_level(_collector_index);
00805 _labels.clear();
00806
00807 int num_children = level->get_num_children();
00808 for (int i = 0; i < num_children; i++) {
00809 const PStatViewLevel *child = level->get_child(i);
00810 int collector_index = child->get_collector();
00811 if (is_label_used(collector_index)) {
00812 _labels.push_back(collector_index);
00813 }
00814 }
00815
00816 SortCollectorLabels2 sort_labels(get_monitor()->get_client_data());
00817 sort(_labels.begin(), _labels.end(), sort_labels);
00818
00819 int collector_index = level->get_collector();
00820 _labels.push_back(collector_index);
00821
00822 _labels_changed = true;
00823 _level_index = _view.get_level_index();
00824 }
00825
00826
00827
00828
00829
00830
00831
00832 void PStatStripChart::
00833 normal_guide_bars() {
00834 update_guide_bars(4, _value_height);
00835 }
00836
00837
00838
00839
00840
00841
00842
00843 void PStatStripChart::
00844 draw_frames(int first_frame, int last_frame) {
00845 const PStatThreadData *thread_data = _view.get_thread_data();
00846
00847 last_frame = min(last_frame, thread_data->get_latest_frame_number());
00848
00849 if (_first_data) {
00850 if (_scroll_mode) {
00851 _start_time =
00852 thread_data->get_frame(last_frame).get_start() - _time_width;
00853 } else {
00854 _start_time = thread_data->get_frame(first_frame).get_start();
00855 _cursor_pixel = 0;
00856 }
00857 }
00858
00859 int first_pixel;
00860 if (thread_data->has_frame(first_frame)) {
00861 first_pixel =
00862 timestamp_to_pixel(thread_data->get_frame(first_frame).get_start());
00863 } else {
00864 first_pixel = 0;
00865 }
00866
00867 int last_pixel =
00868 timestamp_to_pixel(thread_data->get_frame(last_frame).get_start());
00869
00870 if (_first_data && !_scroll_mode) {
00871 first_pixel = min(_cursor_pixel, first_pixel);
00872 }
00873 _first_data = false;
00874
00875 if (last_pixel - first_pixel >= _xsize) {
00876
00877
00878 _start_time = thread_data->get_frame(last_frame).get_start() - _time_width;
00879 first_pixel = 0;
00880 last_pixel = _xsize;
00881 }
00882
00883 if (last_pixel <= _xsize) {
00884
00885 _cursor_pixel = last_pixel;
00886 draw_pixels(first_pixel, last_pixel);
00887
00888 } else {
00889 if (_scroll_mode) {
00890
00891 int slide_pixels = last_pixel - _xsize;
00892 copy_region(slide_pixels, first_pixel, 0);
00893 first_pixel -= slide_pixels;
00894 last_pixel -= slide_pixels;
00895 _start_time += (double)slide_pixels / (double)_xsize * _time_width;
00896 draw_pixels(first_pixel, last_pixel);
00897
00898 } else {
00899
00900 _cursor_pixel = -1;
00901 draw_pixels(first_pixel, _xsize);
00902 _start_time = pixel_to_timestamp(_xsize);
00903 last_pixel -= _xsize;
00904 _cursor_pixel = last_pixel;
00905 draw_pixels(0, last_pixel);
00906 }
00907 }
00908 }
00909
00910
00911
00912
00913
00914
00915 void PStatStripChart::
00916 draw_pixels(int first_pixel, int last_pixel) {
00917 begin_draw(first_pixel, last_pixel);
00918 const PStatThreadData *thread_data = _view.get_thread_data();
00919
00920 if (_average_mode && !thread_data->is_empty()) {
00921
00922 double start_time = pixel_to_timestamp(first_pixel);
00923 int then_i = thread_data->get_frame_number_at_time(start_time - pstats_average_time);
00924 int now_i = thread_data->get_frame_number_at_time(start_time, then_i);
00925 for (int x = first_pixel; x <= last_pixel; x++) {
00926 if (x == _cursor_pixel && !_scroll_mode) {
00927 draw_cursor(x);
00928 } else {
00929 FrameData fdata;
00930 compute_average_pixel_data(fdata, then_i, now_i, pixel_to_timestamp(x));
00931 draw_slice(x, 1, fdata);
00932 }
00933 }
00934
00935 } else {
00936
00937
00938 int frame_number = -1;
00939 int x = first_pixel;
00940 while (x <= last_pixel) {
00941 if (x == _cursor_pixel && !_scroll_mode) {
00942 draw_cursor(x);
00943 x++;
00944
00945 } else {
00946 double time = pixel_to_timestamp(x);
00947 frame_number = thread_data->get_frame_number_at_time(time, frame_number);
00948 int w = 1;
00949 int stop_pixel = last_pixel;
00950 if (!_scroll_mode) {
00951 stop_pixel = min(stop_pixel, _cursor_pixel);
00952 }
00953 while (x + w < stop_pixel &&
00954 thread_data->get_frame_number_at_time(pixel_to_timestamp(x + w), frame_number) == frame_number) {
00955 w++;
00956 }
00957 if (thread_data->has_frame(frame_number)) {
00958 draw_slice(x, w, get_frame_data(frame_number));
00959 } else {
00960 draw_empty(x, w);
00961 }
00962 x += w;
00963 }
00964 }
00965 }
00966
00967 end_draw(first_pixel, last_pixel);
00968 }
00969
00970
00971
00972
00973
00974
00975 void PStatStripChart::
00976 clear_label_usage() {
00977 _label_usage.clear();
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 void PStatStripChart::
00990 dec_label_usage(const FrameData &fdata) {
00991 FrameData::const_iterator fi;
00992 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
00993 const ColorData &cd = (*fi);
00994 nassertv(cd._collector_index < (int)_label_usage.size());
00995 nassertv(_label_usage[cd._collector_index] > 0);
00996 _label_usage[cd._collector_index]--;
00997 if (_label_usage[cd._collector_index] == 0) {
00998
00999
01000 _level_index = -1;
01001 }
01002 }
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 void PStatStripChart::
01017 inc_label_usage(const FrameData &fdata) {
01018 FrameData::const_iterator fi;
01019 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
01020 const ColorData &cd = (*fi);
01021 while (cd._collector_index >= (int)_label_usage.size()) {
01022 _label_usage.push_back(0);
01023 }
01024 nassertv(_label_usage[cd._collector_index] >= 0);
01025 _label_usage[cd._collector_index]++;
01026 if (_label_usage[cd._collector_index] == 1) {
01027
01028
01029 _level_index = -1;
01030 }
01031 }
01032 }