"Fossies" - the Fresh Open Source Software Archive

Member "xosview-1.23/fieldmeterdecay.cc" (11 Jul 2020, 5684 Bytes) of package /linux/misc/xosview-1.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "fieldmeterdecay.cc" see the Fossies "Dox" file reference documentation.

    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 
   31 FieldMeterDecay::FieldMeterDecay( XOSView *parent,
   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 
   44 FieldMeterDecay::~FieldMeterDecay( void ){
   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 
  127     parent_->setForeground( colors_[i] );
  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 }