libzypp  10.5.0
ProgressData.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include "zypp/base/Logger.h"
00014 #include "zypp/base/InputStream.h"
00015 #include "zypp/base/String.h"
00016 
00017 #include "zypp/ProgressData.h"
00018 
00019 using std::endl;
00020 
00021 #undef  ZYPP_BASE_LOGGER_LOGGROUP
00022 #define  ZYPP_BASE_LOGGER_LOGGROUP "Progress"
00023 
00025 namespace zypp
00026 { 
00027 
00029   //
00030   //    METHOD NAME : ProgressData::report
00031   //    METHOD TYPE : void
00032   //
00033   bool ProgressData::report()
00034   {
00035     bool goOn     = true;  // continue per default
00036     bool doReport = false;
00037 
00038     // compute value and check whether to report it
00039     if ( hasRange() )
00040     {
00041       value_type newVal = _d->_val * 100;
00042       newVal /= ( _d->_max - _d->_min );
00043 
00044       if ( newVal - _d->_last_val > 20
00045            || Date::now() - _d->_last_send > 1
00046            || ( newVal == 100 && _d->_last_send != 100 )
00047            || _d->_state == END )
00048       {
00049         _d->_last_val  = newVal;
00050         _d->_last_send = Date::now();
00051         doReport = true;
00052       }
00053     }
00054     else
00055     {
00056       if ( Date::now() - _d->_last_send > 1 || _d->_state == END )
00057       {
00058         _d->_last_val  = _d->_val;
00059         _d->_last_send = Date::now();
00060         doReport = true;
00061       }
00062     }
00063 
00064     // report if necessary
00065     if ( doReport )
00066     {
00067       if ( _d->_state == INIT )
00068       {
00069         _d->_state = RUN;
00070       }
00071 
00072       if ( _d->_receiver )
00073       {
00074         goOn = _d->_receiver( *this );
00075       }
00076       else
00077       {
00078         if ( _d->_state != END )
00079         {
00080           XXX << str::form( "{#%u|%s}(%lld%s)",
00081                             numericId(), name().c_str(),
00082                             _d->_last_val, ( hasRange() ? "%" : "!" ) ) << endl;
00083         }
00084         else
00085         {
00086           DBG << str::form( "{#%u|%s}END", numericId(), name().c_str() ) << endl;
00087         }
00088       }
00089     }
00090 
00091     // log abort request and return
00092     if ( ! goOn && _d->_state != END )
00093     {
00094       WAR << "User request to ABORT pending action. "
00095           << str::form( "{#%u|%s}(%lld%s)",
00096                         numericId(), name().c_str(),
00097                         _d->_last_val, ( hasRange() ? "%" : "!" ) ) << endl;
00098     }
00099     return goOn;
00100   }
00101 
00102   /******************************************************************
00103   **
00104   **    FUNCTION NAME : operator<<
00105   **    FUNCTION TYPE : std::ostream &
00106   */
00107   std::ostream & operator<<( std::ostream & str, const ProgressData & obj )
00108   {
00109     if ( obj.hasRange() )
00110     {
00111       return str << str::form( "{%u|%s}[%lld,%lld](%lld)%lld%%)",
00112                                obj.numericId(), obj.name().c_str(),
00113                                obj.min(), obj.max(), obj.val(), obj.reportValue() );
00114     }
00115     return str << str::form( "{%u|%s}[-,-](%lld)",
00116                              obj.numericId(), obj.name().c_str(),
00117                              obj.val() );
00118   }
00119 
00120   /******************************************************************
00121   **
00122   **    FUNCTION NAME : operator<<
00123   **    FUNCTION TYPE : std::ostream &
00124   */
00125   ProgressData makeProgressData( const InputStream & input_r )
00126   {
00127     ProgressData ret;
00128     ret.name( input_r.name() );
00129     if ( input_r.size() > 0 )
00130       ret.range( input_r.size() );
00131     return ret;
00132   }
00133 
00134   CombinedProgressData::CombinedProgressData( ProgressData &pd,
00135                                               ProgressData::value_type weight )
00136     : _weight(weight),
00137       _last_value(0),
00138       _pd(pd)
00139   {
00140 
00141   }
00142 
00143   bool CombinedProgressData::operator()( const ProgressData &progress )
00144   {
00145     if ( progress.reportAlive() || ( _weight == 0 ) )
00146       return _pd.tick();
00147 
00148     // factor [0,1] of increase in subtask ( ie: before 0,2 now 0.5 )
00149     float increment = ((float)(progress.val() - _last_value))/(progress.max() - progress.min());
00150     // how much the subtask affects the parent task ie: 0,1
00151     float parent_factor = (float)(_weight)/(_pd.max() - _pd.min());
00152     // real increment of the parent task
00153     float real_increment = parent_factor*increment;
00154     _last_value = progress.val();
00155     return _pd.incr( (int)( (_pd.max()-_pd.min()) * real_increment) );
00156   }
00157 
00159 } // namespace zypp