33 int thread_index,
int collector_index,
int xsize,
int ysize) :
35 _thread_index(thread_index),
37 _collector_index(collector_index)
39 _scroll_mode = pstats_scroll_mode;
40 _average_mode =
false;
47 _value_height = 1.0/10.0;
51 _title_unknown =
true;
56 _unit_name = def._level_units;
59 set_default_vertical_scale();
77 _next_frame = min(frame_number, _next_frame);
95 if (latest > _next_frame) {
96 draw_frames(_next_frame, latest);
106 while (di != _data.end() &&
108 dec_label_usage((*di).second);
137 if (_collector_index != collector_index) {
138 _collector_index = collector_index;
139 _title_unknown =
true;
157 if (def._suggested_scale != 0.0) {
173 double max_value = 0.0;
175 int frame_number = -1;
176 for (
int x = 0; x <= _xsize; x++) {
181 if (thread_data->
has_frame(frame_number)) {
182 double net_value = get_net_value(frame_number);
183 max_value = max(max_value, net_value);
189 if (max_value == 0.0) {
217 compute_average_pixel_data(fdata, then_i, now_i, start_time);
218 double overall_value = 0.0;
221 FrameData::const_iterator fi;
222 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
223 const ColorData &cd = (*fi);
224 overall_value += cd._net_value;
227 return cd._collector_index;
233 const FrameData &fdata = get_frame_data(frame_number);
234 double overall_value = 0.0;
237 FrameData::const_iterator fi;
238 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
239 const ColorData &cd = (*fi);
240 overall_value += cd._net_value;
243 return cd._collector_index;
258 _title_unknown =
false;
265 if (!def._level_units.empty()) {
266 text +=
" (" + def._level_units +
")";
272 _title_unknown =
true;
275 if (_thread_index != 0) {
277 text +=
" (" + client_data->
get_thread_name(_thread_index) +
" thread)";
279 _title_unknown =
true;
292 return _title_unknown;
299 void PStatStripChart::
300 accumulate_frame_data(FrameData &fdata,
const FrameData &additional,
302 FrameData::iterator ai;
303 FrameData::const_iterator bi;
306 bi = additional.begin();
310 if (fdata.size() == additional.size()) {
314 while (ai != fdata.end() &&
315 (*ai)._collector_index == (*bi)._collector_index) {
316 (*ai)._net_value += ((*bi)._net_value * weight);
321 if (ai == fdata.end()) {
330 result.reserve(max(fdata.size(), additional.size()));
331 FrameData::const_iterator ci;
332 for (ci = fdata.begin(); ci != ai; ++ci) {
333 result.push_back(*ci);
338 result.reserve(max(fdata.size(), additional.size()));
341 while (ai != fdata.end() && bi != additional.end()) {
342 if ((*ai)._i < (*bi)._i) {
344 result.push_back(*ai);
347 }
else if ((*bi)._i < (*ai)._i) {
350 scaled._collector_index = (*bi)._collector_index;
351 scaled._i = (*bi)._i;
352 scaled._net_value = (*bi)._net_value * weight;
353 result.push_back(scaled);
359 combined._collector_index = (*ai)._collector_index;
360 combined._i = (*bi)._i;
361 combined._net_value = (*ai)._net_value + (*bi)._net_value * weight;
362 result.push_back(combined);
368 while (ai != fdata.end()) {
370 result.push_back(*ai);
374 while (bi != additional.end()) {
377 scaled._collector_index = (*bi)._collector_index;
378 scaled._i = (*bi)._i;
379 scaled._net_value = (*bi)._net_value * weight;
380 result.push_back(scaled);
390 void PStatStripChart::
391 scale_frame_data(FrameData &fdata,
double factor) {
392 FrameData::iterator fi;
393 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
394 (*fi)._net_value *= factor;
405 get_frame_data(
int frame_number) {
406 Data::const_iterator di;
407 di = _data.find(frame_number);
408 if (di != _data.end()) {
415 FrameData &fdata = _data[frame_number];
419 for (
int i = 0; i < num_children; i++) {
422 cd._collector_index = (
unsigned short)child->
get_collector();
423 cd._i = (
unsigned short)i;
425 if (cd._net_value != 0.0) {
433 cd._collector_index = (
unsigned short)level->
get_collector();
434 cd._i = (
unsigned short)num_children;
436 if (cd._net_value > 0.0) {
440 inc_label_usage(fdata);
455 void PStatStripChart::
457 int &then_i,
int &now_i,
double now) {
466 double then = now - pstats_average_time;
469 while (then_i <= latest_frame &&
473 while (now_i <= latest_frame &&
484 accumulate_frame_data(result, get_frame_data(then_i),
489 for (
int frame_number = then_i + 1;
490 frame_number < now_i;
492 accumulate_frame_data(result, get_frame_data(frame_number),
499 accumulate_frame_data(result, get_frame_data(now_i), now - last);
502 scale_frame_data(result, 1.0f / (now - then));
509 double PStatStripChart::
510 get_net_value(
int frame_number)
const {
511 const FrameData &frame =
514 double net_value = 0.0;
515 FrameData::const_iterator fi;
516 for (fi = frame.begin(); fi != frame.end(); ++fi) {
517 const ColorData &cd = (*fi);
518 net_value += cd._net_value;
528 double PStatStripChart::
529 get_average_net_value()
const {
535 double now = _time_width + _start_time;
536 double then = now - pstats_average_time;
538 int num_frames = now_i - then_i + 1;
548 double now = now_frame_data.
get_end();
549 double elapsed_time = (now - then_frame_data.
get_start());
550 return elapsed_time / (double)num_frames;
560 double net_value = 0.0f;
561 double net_time = 0.0f;
567 net_value += get_net_value(then_i) * this_time;
568 net_time += this_time;
571 for (
int frame_number = then_i + 1;
572 frame_number <= now_i;
575 net_value += get_net_value(frame_number) * this_time;
576 net_time += this_time;
579 return net_value / net_time;
588 void PStatStripChart::
589 changed_size(
int xsize,
int ysize) {
590 if (xsize != _xsize || ysize != _ysize) {
593 if (_xsize > 0 && _ysize > 0) {
594 _cursor_pixel = xsize * _cursor_pixel / _xsize;
598 draw_pixels(0, _xsize);
602 double old_start_time = _start_time;
605 _start_time -= _time_width;
606 draw_pixels(_cursor_pixel, _xsize);
609 _start_time = old_start_time;
610 draw_pixels(0, _cursor_pixel);
621 void PStatStripChart::
624 draw_pixels(0, _xsize);
632 void PStatStripChart::
643 void PStatStripChart::
651 void PStatStripChart::
652 copy_region(
int,
int,
int) {
660 void PStatStripChart::
661 begin_draw(
int,
int) {
669 void PStatStripChart::
677 void PStatStripChart::
678 draw_empty(
int,
int) {
686 void PStatStripChart::
695 void PStatStripChart::
705 void PStatStripChart::
712 class SortCollectorLabels2 {
715 _client_data(client_data) {
717 bool operator () (
int a,
int b)
const {
719 _client_data->get_collector_def(a)._sort >
720 _client_data->get_collector_def(b)._sort;
728 void PStatStripChart::
734 for (
int i = 0; i < num_children; i++) {
737 if (is_label_used(collector_index)) {
738 _labels.push_back(collector_index);
742 SortCollectorLabels2 sort_labels(
get_monitor()->get_client_data());
743 sort(_labels.begin(), _labels.end(), sort_labels);
746 _labels.push_back(collector_index);
748 _labels_changed =
true;
755 void PStatStripChart::
756 normal_guide_bars() {
757 update_guide_bars(4, _value_height);
764 void PStatStripChart::
765 draw_frames(
int first_frame,
int last_frame) {
781 if (thread_data->
has_frame(first_frame)) {
791 if (_first_data && !_scroll_mode) {
792 first_pixel = min(_cursor_pixel, first_pixel);
796 if (last_pixel - first_pixel >= _xsize) {
804 if (last_pixel <= _xsize) {
806 _cursor_pixel = last_pixel;
807 draw_pixels(first_pixel, last_pixel);
812 int slide_pixels = last_pixel - _xsize;
813 copy_region(slide_pixels, first_pixel, 0);
814 first_pixel -= slide_pixels;
815 last_pixel -= slide_pixels;
816 _start_time += (double)slide_pixels / (
double)_xsize * _time_width;
817 draw_pixels(first_pixel, last_pixel);
822 draw_pixels(first_pixel, _xsize);
824 last_pixel -= _xsize;
825 _cursor_pixel = last_pixel;
826 draw_pixels(0, last_pixel);
834 void PStatStripChart::
835 draw_pixels(
int first_pixel,
int last_pixel) {
836 begin_draw(first_pixel, last_pixel);
839 if (_average_mode && !thread_data->
is_empty()) {
844 for (
int x = first_pixel; x <= last_pixel; x++) {
845 if (x == _cursor_pixel && !_scroll_mode) {
850 draw_slice(x, 1, fdata);
857 int frame_number = -1;
859 while (x <= last_pixel) {
860 if (x == _cursor_pixel && !_scroll_mode) {
868 int stop_pixel = last_pixel;
870 stop_pixel = min(stop_pixel, _cursor_pixel);
872 while (x + w < stop_pixel &&
876 if (thread_data->
has_frame(frame_number)) {
877 draw_slice(x, w, get_frame_data(frame_number));
886 end_draw(first_pixel, last_pixel);
892 void PStatStripChart::
893 clear_label_usage() {
894 _label_usage.clear();
903 void PStatStripChart::
904 dec_label_usage(
const FrameData &fdata) {
905 FrameData::const_iterator fi;
906 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
907 const ColorData &cd = (*fi);
908 nassertv(cd._collector_index < (
int)_label_usage.size());
909 nassertv(_label_usage[cd._collector_index] > 0);
910 _label_usage[cd._collector_index]--;
911 if (_label_usage[cd._collector_index] == 0) {
925 void PStatStripChart::
926 inc_label_usage(
const FrameData &fdata) {
927 FrameData::const_iterator fi;
928 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
929 const ColorData &cd = (*fi);
930 while (cd._collector_index >= (
int)_label_usage.size()) {
931 _label_usage.push_back(0);
933 nassertv(_label_usage[cd._collector_index] >= 0);
934 _label_usage[cd._collector_index]++;
935 if (_label_usage[cd._collector_index] == 1) {
bool first_data() const
Returns true if the chart has seen its first data appear on it, false if it is still a virgin chart.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_auto_vertical_scale()
Sets the vertical scale to make all the data visible.
int get_ysize() const
Returns the height of the chart in pixels.
void set_to_frame(const PStatFrameData &frame_data)
Supplies the View with the data for the current frame.
void new_data(int frame_number)
Indicates that new data has become available.
int timestamp_to_pixel(double time) const
Converts a timestamp to a horizontal pixel offset.
const PStatViewLevel * get_child(int n) const
Returns the nth child of this Level/Collector.
const PStatFrameData & get_frame(int frame_number) const
Returns a FrameData structure associated with the indicated frame number.
int get_frame_number_at_time(double time, int hint=-1) const
Returns the frame number of the latest frame not later than the indicated time.
bool get_elapsed_frames(int &then_i, int &now_i) const
Computes the oldest frame number not older than pstats_average_time seconds, and the newest frame num...
The data associated with a particular client, but not with any one particular frame or thread: the li...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_vertical_scale(double value_height)
Changes the value the height of the vertical axis represents.
double get_value_alone() const
Returns the total level value (or elapsed time value) for this Collector, not including any values ac...
This is an abstract base class for several different kinds of graphs that have a few things in common...
const PStatCollectorDef & get_collector_def(int index) const
Returns the nth collector definition.
std::string get_collector_fullname(int index) const
Returns the "full name" of the indicated collector.
double get_target_frame_rate() const
Returns the indicated target frame rate in Hz.
int get_num_threads() const
Returns the total number of threads the Data knows about.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract class that presents the interface for drawing a basic strip-chart,...
double get_oldest_time() const
Returns the timestamp (in seconds elapsed since connection) of the oldest available frame.
PStatMonitor * get_monitor() const
Returns the monitor associated with this chart.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_collector_under_pixel(int xpoint, int ypoint)
Return the collector index associated with the particular band of color at the indicated pixel locati...
This is our own Panda specialization on the default STL vector.
This is a single level value, or band of color, within a View.
double get_net_value() const
Returns the total level value (or elapsed time) represented by this Collector, including all values i...
This is an abstract class that presents the interface to any number of different front-ends for the s...
bool has_collector(int index) const
Returns true if the indicated collector has been defined by the client already, false otherwise.
void update()
Updates the chart with the latest data.
int height_to_pixel(double value) const
Converts a value (i.e.
bool has_thread(int index) const
Returns true if the indicated thread has been defined by the client already, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Contains the raw timing and level data for a single frame.
A View boils down the frame data to a linear list of times spent in a number of different Collectors,...
int get_num_collectors() const
Returns the total number of collectors the Data knows about.
A collection of FrameData structures for recently-received frames within a particular thread.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_title_unknown() const
Returns true if get_title_text() has never yet returned an answer, false if it has.
const PStatThreadData * get_thread_data()
Returns the current PStatThreadData associated with the view.
double pixel_to_timestamp(int x) const
Converts a horizontal pixel offset to a timestamp.
bool has_frame(int frame_number) const
Returns true if we have received data for the indicated frame number from the client and we still hav...
void set_collector_index(int collector_index)
Changes the collector represented by this strip chart.
int get_collector() const
Returns the Collector index associated with this level.
double get_end() const
Returns the time of the last data point in the frame data.
void set_default_vertical_scale()
Sets the vertical scale according to the suggested scale of the base collector, if any,...
int get_level_index() const
Returns an index number that can be used to determine when the set of known levels has changed.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
int get_num_children() const
Returns the number of children of this Level/Collector.
Defines the details about the Collectors: the name, the suggested color, etc.
bool get_show_level() const
Returns true if we are showing level data, false if time data.
bool is_empty() const
Returns true if the structure contains no frames, false otherwise.
double get_start() const
Returns the time of the first data point in the frame data.
int get_latest_frame_number() const
Returns the frame number of the most recent frame stored in the data.
PStatViewLevel * get_level(int collector)
Returns a pointer to the level that corresponds to the indicated Collector.
double get_net_time() const
Returns the total time elapsed for the frame.
std::string get_thread_name(int index) const
Returns the name of the indicated thread.
std::string get_title_text()
Returns the text suitable for the title label on the top line.