xosview  1.23
About: xosview is an X Windows based system monitor (cpu, memory, swap and network usage; interrupt and serial activities; load average).
  Fossies Dox: xosview-1.23.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

fieldmeterdecay.cc
Go to the documentation of this file.
1 //
2 // The original FieldMeter class is Copyright (c) 1994, 2006 by Mike Romberg
3 // ( mike.romberg@noaa.gov )
4 // Modifications from FieldMeter class done in Oct. 1995
5 // by Brian Grayson ( bgrayson@netbsd.org )
6 //
7 // This file was written by Brian Grayson for the NetBSD and xosview
8 // projects.
9 // This file may be distributed under terms of the GPL or of the BSD
10 // license, whichever you choose. The full license notices are
11 // contained in the files COPYING.GPL and COPYING.BSD, which you
12 // should have received. If not, contact one of the xosview
13 // authors for a copy.
14 //
15 
16 // In order to use the FieldMeterDecay class in place of a FieldMeter class in
17 // a meter file (say, cpumeter.cc), make the following changes:
18 // 1. Change cpumeter.h to include fieldmeterdecay.h instead of
19 // fieldmeter.h
20 // 2. Change CPUMeter to inherit from FieldMeterDecay, rather than
21 // FieldMeter.
22 // 3. Change the constructor call to use FieldMeterDecay(), rather than
23 // FieldMeter().
24 // 4. Make the checkResources () function in the meter set the
25 // dodecay_ variable according to the, e.g., xosview*cpuDecay resource.
26 
27 #include "fieldmeterdecay.h"
28 #include <iostream>
29 
30 
32  int numfields, const char *title,
33  const char *legend, int docaptions, int dolegends,
34  int dousedlegends )
35 : FieldMeter (parent, numfields, title, legend, docaptions, dolegends,
36  dousedlegends)
37 {
38  decay_ = new double[numfields];
39  lastDecayval_ = new double[numfields];
40  firsttime_ = 1;
41  dodecay_ = 1;
42 }
43 
45  delete[] decay_;
46  delete[] lastDecayval_;
47 }
48 
49 void FieldMeterDecay::drawfields( int mandatory ){
50  int twidth, x = x_;
51  int decay_changed = 0;
52 
53  if (!dodecay_)
54  {
55  // If this meter shouldn't be done as a decaying splitmeter,
56  // call the ordinary fieldmeter code.
57  FieldMeter::drawfields (mandatory);
58  return;
59  }
60 
61  if ( total_ == 0.0 )
62  return;
63 
64  int halfheight = height_ / 2;
65  int decaytwidth, decayx = x_;
66 
67  // This code is supposed to make the average display look just like
68  // the ordinary display for the first drawfields, but it doesn't seem
69  // to work too well. But it's better than setting all decay_ fields
70  // to 0.0 initially!
71 
72  if (firsttime_) {
73  firsttime_ = 0;
74  mandatory = 1;
75  for (int i = 0; i < numfields_; i++)
76  {
77  decay_[i] = 1.0*fields_[i]/total_;
78  }
79  }
80 
81  // Update the decay fields. This is not quite accurate, since if
82  // the screen is refreshed, we will update the decay fields more
83  // often than we need to. However, this makes the decay stuff
84  // TOTALLY independent of the ????Meter methods.
85 
86  // The constant below can be modified for quicker or slower
87  // exponential rates for the average. No fancy math is done to
88  // set it to correspond to a five-second decay or anything -- I
89  // just played with it until I thought it looked good! :) BCG
90 #define ALPHA 0.97
91 
92  /* This is majorly ugly code. It needs a rewrite. BCG */
93  /* I think one good way to do it may be to normalize all of the
94  * fields_ in a temporary array into the range 0.0 .. 1.0,
95  * calculate the shifted starting positions and ending positions
96  * for coloring, multiply by the pixel width of the meter, and
97  * then turn to ints. I think this will solve a whole bunch of
98  * our problems with rounding that before we tackled at a whole
99  * lot of places. BCG */
100  for ( int i = 0 ; i < numfields_ ; i++ ){
101 
102  decay_[i] = ALPHA*decay_[i] + (1-ALPHA)*(fields_[i]*1.0/total_);
103 
104  // We want to round the widths, rather than truncate.
105  twidth = (int) (0.5 + (width_ * (double) fields_[i]) / total_);
106  decaytwidth = (int) (0.5 + width_ * decay_[i]);
107  if (decaytwidth < 0.0) {
108  std::cerr << "Error: FieldMeterDecay " << name() << ": decaytwidth of ";
109  std::cerr << decaytwidth << ", width of " << width_ << ", decay_[" << i;
110  std::cerr << "] of " << decay_[i] << std::endl;
111  }
112 
113  // However, due to rounding, we may have gone one
114  // pixel too far by the time we get to the later fields...
115  if (x + twidth > x_ + width_)
116  twidth = width_ + x_ - x;
117  if (decayx + decaytwidth > x_ + width_)
118  decaytwidth = width_ + x_ - decayx;
119 
120  // Also, due to rounding error, the last field may not go far
121  // enough...
122  if ( (i == numfields_ - 1) && ((x + twidth) != (x_ + width_)) )
123  twidth = width_ + x_ - x;
124  if ( (i == numfields_ - 1) && ((decayx + decaytwidth) != (x_ + width_)))
125  decaytwidth = width_ + x_ - decayx;
126 
128  parent_->setStippleN(i%4);
129 
130  // drawFilledRectangle() adds one to its width and height.
131  // Let's correct for that here.
132  if ( mandatory || (twidth != lastvals_[i]) || (x != lastx_[i]) ){
133  if (!checkX(x, twidth))
134  std::cerr <<__FILE__ << ":" << __LINE__ <<std::endl;
135  parent_->drawFilledRectangle( x, y_, twidth, halfheight );
136  }
137 
138  if ( mandatory || decay_changed || (decay_[i] != lastDecayval_[i]) ){
139  if (!checkX(decayx, decaytwidth))
140  std::cerr <<__FILE__ << ":" << __LINE__ <<std::endl;
141  decay_changed = 1;
142  parent_->drawFilledRectangle( decayx, y_+halfheight+1,
143  decaytwidth, height_ - halfheight-1);
144  }
145 
146  lastvals_[i] = twidth;
147  lastx_[i] = x;
148  lastDecayval_[i] = decay_[i];
149 
150  parent_->setStippleN(0); /* Restore all-bits stipple. */
151  if ( dousedlegends_ )
152  drawused( mandatory );
153  x += twidth;
154 
155  decayx += decaytwidth;
156 
157  }
158 }
virtual ~FieldMeterDecay(void)
double * lastDecayval_
virtual void drawfields(int mandatory=0)
FieldMeterDecay(XOSView *parent, int numfields, const char *title="", const char *legend="", int docaptions=0, int dolegends=0, int dousedlegends=0)
double total_
Definition: fieldmeter.h:41
void drawused(int mandatory)
Definition: fieldmeter.cc:171
virtual void drawfields(int mandatory=0)
Definition: fieldmeter.cc:221
int numfields_
Definition: fieldmeter.h:39
double * fields_
Definition: fieldmeter.h:40
unsigned long * colors_
Definition: fieldmeter.h:43
int * lastvals_
Definition: fieldmeter.h:42
int * lastx_
Definition: fieldmeter.h:42
bool checkX(int x, int width) const
Definition: fieldmeter.cc:283
int x_
Definition: meter.h:53
int y_
Definition: meter.h:53
int dousedlegends_
Definition: meter.h:53
int width_
Definition: meter.h:53
virtual const char * name(void) const
Definition: meter.h:20
XOSView * parent_
Definition: meter.h:52
int height_
Definition: meter.h:53
void setForeground(unsigned long pixelvalue)
Definition: xwin.h:38
void setStippleN(int n)
Definition: xwin.h:48
void drawFilledRectangle(int x, int y, int width, int height)
Definition: xwin.h:67
#define ALPHA