Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

ProgressCounter.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                                                                      |
00003 |                      __   __    ____ _____ ____                      |
00004 |                      \ \ / /_ _/ ___|_   _|___ \                     |
00005 |                       \ V / _` \___ \ | |   __) |                    |
00006 |                        | | (_| |___) || |  / __/                     |
00007 |                        |_|\__,_|____/ |_| |_____|                    |
00008 |                                                                      |
00009 |                               core system                            |
00010 |                                                        (C) SuSE GmbH |
00011 \----------------------------------------------------------------------/
00012 
00013   File:       ProgressCounter.h
00014 
00015   Author:     Michael Andres <ma@suse.de>
00016   Maintainer: Michael Andres <ma@suse.de>
00017 
00018   Purpose: Simple progress counting.
00019 
00020 /-*/
00021 #ifndef ProgressCounter_h
00022 #define ProgressCounter_h
00023 
00024 #include <iosfwd>
00025 
00027 //
00028 //      CLASS NAME : ProgressData
00036 class ProgressData {
00037   friend std::ostream & operator<<( std::ostream & str, const ProgressData & obj );
00038 
00039   private:
00040 
00044     int _min;
00048     int _max;
00052     int _val;
00053 
00054   public:
00055 
00059     ProgressData( int max_r = 0 )
00060       : _min( 0 )
00061       , _max( max_r )
00062       , _val( 0 )
00063     {}
00067     ProgressData( int min_r, int max_r )
00068       : _min( min_r )
00069       , _max( max_r )
00070       , _val( min_r )
00071     {}
00075     ProgressData( int min_r, int max_r, int val_r )
00076       : _min( min_r )
00077       , _max( max_r )
00078       , _val( val_r )
00079     {}
00083     ProgressData( const ProgressData & rhs )
00084       : _min( rhs._min )
00085       , _max( rhs._max )
00086       , _val( rhs._val )
00087     {}
00088 
00092     ProgressData & operator=( const ProgressData & rhs ) {
00093       if ( &rhs != this ) {
00094         init( rhs._min, rhs._max, rhs._val );
00095       }
00096       return *this;
00097     }
00098 
00102     virtual ~ProgressData() {}
00103 
00104   public:
00105 
00109     virtual ProgressData & min( int min_r )               { _min = min_r; return *this; }
00113     virtual ProgressData & max( int max_r )               { _max = max_r; return *this; }
00114 
00118     virtual ProgressData & range( int min_r, int max_r )   { _min = min_r; _max = max_r; return *this; }
00122     ProgressData & range( int max_r )                      { return range( 0, max_r ); }
00123 
00127     virtual ProgressData & set( int val_r )                { _val = val_r; return *this; }
00131     ProgressData & incr( int val_r = 1 )                   { return set( _val +val_r ); }
00135     ProgressData & decr( int val_r = 1 )                   { return set( _val -val_r ); }
00139     ProgressData & toMin()                                 { return set( _min ); }
00143     ProgressData & toMax()                                 { return set( _max ); }
00144 
00148     virtual ProgressData & init( int min_r, int max_r, int val_r ) { _min = min_r; _max = max_r; _val = val_r; return *this; }
00152     ProgressData & init( int min_r, int max_r )            { return init( min_r, max_r, min_r ); }
00156     ProgressData & init( int max_r )                       { return init( 0, max_r ); }
00157 
00158   public:
00159 
00163     int min() const { return _min; }
00164 
00168     int max() const { return _max; }
00169 
00173     int val() const { return _val; }
00174 };
00175 
00177 
00179 //
00180 //      CLASS NAME : ProgressCounter
00191 class ProgressCounter : public ProgressData {
00192   friend std::ostream & operator<<( std::ostream & str, const ProgressCounter & obj );
00193 
00194   public:
00195 
00196     typedef unsigned Bits;
00197 
00201    enum ChangedBit {
00202       VC_NONE = 0x00,
00203       //============
00204       VC_MIN      = 0x01,
00205       VC_MAX      = 0x02,
00206       VC_VAL      = 0x04,
00207       VC_PERCENT  = 0x10,
00208       //============
00209       VC_RANGE = (VC_MIN|VC_MAX),
00210       VC_COUNT = (VC_RANGE|VC_VAL),
00211       VC_ALL   = (VC_COUNT|VC_PERCENT)
00212     };
00213 
00214   private:
00215 
00221     mutable Bits _changed;
00222 
00226     int _oldPercent;
00227 
00231     void check( int lhs, int rhs, ChangedBit which ) { if ( lhs != rhs ) _changed |= which; }
00232 
00237     bool checkPercent() const {
00238       if ( _changed & VC_PERCENT )
00239         return true; // Dirty percent is reset on update only.
00240       // Dirty min, max or val -> check precent
00241       if ( (_changed & VC_COUNT) &&  _oldPercent != percent() ) {
00242         _changed |= VC_PERCENT;
00243         return true;
00244       }
00245       return false;
00246     }
00247 
00248   protected:
00249 
00254      virtual Bits onUpdate() { return _changed; }
00255 
00256   public:
00257 
00261     ProgressCounter( Bits initial_r = VC_NONE )
00262       : _changed( initial_r )
00263       , _oldPercent( percent() )
00264     {}
00268     ProgressCounter( const ProgressData & pd_r, Bits initial_r = VC_NONE )
00269       : ProgressData( pd_r )
00270       , _changed( initial_r )
00271       , _oldPercent( percent() )
00272     {}
00273 
00277     ProgressCounter & operator=( const ProgressData & pd_r ) {
00278       ProgressData::operator=( pd_r );
00279       return *this;
00280     }
00281 
00285     virtual ~ProgressCounter() {}
00286 
00287   public:
00288 
00292     virtual ProgressData & min( int min_r ) {
00293       check( min(), min_r, VC_MIN );
00294       return ProgressData::min( min_r );
00295     }
00299     ProgressData::min;
00300 
00304     virtual ProgressData & max( int max_r ) {
00305       check( max(), max_r, VC_MAX );
00306       return ProgressData::max( max_r );
00307     }
00311     ProgressData::max;
00312 
00316     virtual ProgressData & range( int min_r, int max_r ) {
00317       check( min(), min_r, VC_MIN );
00318       check( max(), max_r, VC_MAX );
00319       return ProgressData::range( min_r, max_r );
00320     }
00324     ProgressData::range;
00325 
00329     virtual ProgressData & set( int val_r ) {
00330       check( val(), val_r, VC_VAL );
00331       return ProgressData::set( val_r );
00332     }
00333 
00337     virtual ProgressData & init( int min_r, int max_r, int val_r ) {
00338       check( min(), min_r, VC_MIN );
00339       check( max(), max_r, VC_MAX );
00340       check( val(), val_r, VC_VAL );
00341       return ProgressData::init( min_r, max_r, val_r );
00342     }
00346     ProgressData::init;
00347 
00348   public:
00349 
00353     bool newMin() const { return( _changed & VC_MIN ); }
00357     bool newMax() const { return( _changed & VC_MAX ); }
00361     bool newVal() const { return( _changed & VC_VAL ); }
00365     bool newRange() const { return( _changed & VC_RANGE ); }
00369     bool newPercent() const { return checkPercent(); }
00373     bool needsUpdate() const {
00374       checkPercent(); // Check, as VC_PERCENT isn't updated on the fly.
00375       return _changed;
00376     }
00377 
00378   public:
00379 
00385     double fPercent( double ifepmty_r = 0.0 ) const {
00386       if ( max() == min() ) {
00387         return ifepmty_r;
00388       }
00389       return double( val() - min() ) * 100.0 / double( max() - min() );
00390     }
00396     int percent( int ifepmty_r = 0 ) const {
00397       if ( max() == min() ) {
00398         return ifepmty_r;
00399       }
00400       return (int)fPercent();
00401     }
00402 
00403   public:
00404 
00408     void tagDirty( Bits bits_r = VC_ALL ) { _changed |= bits_r; }
00412     void setDirty( Bits bits_r = VC_ALL ) { _changed = bits_r; }
00413 
00420     Bits update() {
00421       needsUpdate();         // update bits not set ont the fly (percent)
00422       Bits ret = onUpdate(); // get the discarded bits to return
00423       _changed = VC_NONE;
00424       _oldPercent = percent();
00425       return ret;
00426     }
00427 
00441     bool updateIfNewPercent( unsigned limit_r = 0 ) {
00442       if ( _changed == VC_ALL ) {
00443         // always update after reset
00444         update();
00445         return true;
00446       }
00447       if ( checkPercent() ) {
00448         if ( limit_r ) {
00449           int newpc = percent();
00450           if ( newpc == _oldPercent )
00451             return false;
00452           if ( ! ( newpc == 100 || _oldPercent == 0 || newpc == 0 || _oldPercent == 100 ) ) {
00453             unsigned dist = newpc > _oldPercent ? newpc - _oldPercent
00454                                                 : _oldPercent - newpc;
00455             if ( dist < limit_r )
00456               return false;
00457           }
00458         }
00459         update();
00460         return true;
00461       }
00462       return false;
00463     }
00464 
00468     void reset() { init( 0 ); _oldPercent = 0; setDirty(); }
00469 
00470 };
00471 
00473 
00474 #endif // ProgressCounter_h

Generated on Thu Feb 23 23:56:10 2006 for liby2util by doxygen 1.3.6