libzypp 17.32.5
progressobserver.cc
Go to the documentation of this file.
1#include "progressobserver.h"
4
5namespace zyppng {
6
8 {
10 public:
12
13
15 void setLabel( const std::string &label );
16
17
18 ProgressObserverWeakRef _parent;
19 std::string _label;
20
21 // the current counter value
22 double _counterValue = 0;
23
24 // the number of steps we are going to have
25 double _counterSteps = 0;
26
27 // the value of all finished progresses
28 double _finishedValue = 0;
29
30 // the steps of all finished progresses
31 double _finishedSteps = 0;
32
33 int _baseValue = 0;
34 int _baseSteps = 100;
35
36 bool _ignoreChildSigs = false;
37
38 struct ChildInfo {
39 ChildInfo( std::vector<connection> &&conns, float weight ) : _signalConns( std::move(conns) ), _childWeight( weight ) {}
41 : _signalConns( std::move(other._signalConns) )
42 , _childWeight( other._childWeight )
43 {
44 other._signalConns.clear ();
45 }
46 ChildInfo( const ChildInfo &other ) = delete;
48 std::for_each( _signalConns.begin (), _signalConns.end(), []( auto &sig ){ sig.disconnect(); });
49 }
50
51 ChildInfo &operator=( const ChildInfo & ) = delete;
53 {
54 _childWeight = other._childWeight;
55 _signalConns = std::move(other._signalConns);
56 other._signalConns.clear ();
57 return *this;
58 }
59
60 std::vector<connection> _signalConns;
61 float _childWeight = 1.0; // the factor how much increase a step in the child is worth in the parent
62 };
63
64 std::vector<ProgressObserverRef> _children;
65 std::vector< ChildInfo > _childInfo;
66
67 void onChildChanged();
69
76 };
77
79
80 void ProgressObserverPrivate::onChildChanged()
81 {
82 if ( _ignoreChildSigs )
83 return;
84
85 double currProgressSteps = _baseValue;
86 double accumSteps = _baseSteps;
87
88 for ( auto i = 0; i < _children.size (); i++ ) {
89 const auto childPtr = _children[i].get();
90 const auto &childInfo = _childInfo[i];
91 const auto weight = childInfo._childWeight;
92 currProgressSteps += childPtr->current() * weight;
93 accumSteps += childPtr->steps()* weight;
94 }
95
96 bool notifyAccuMaxSteps = _counterSteps != accumSteps ;
97 bool notifyCurrSteps = _counterValue != currProgressSteps;
98
99 _counterSteps = accumSteps;
100 _counterValue = currProgressSteps;
101
102 if ( notifyAccuMaxSteps )
103 _sigStepsChanged.emit( *z_func(), _counterSteps );
104 if ( notifyCurrSteps) {
105 _sigValueChanged.emit( *z_func(), notifyCurrSteps );
106 _sigProgressChanged.emit( *z_func(), z_func()->progress() );
107 }
108 }
109
111 {
112 auto i = std::find_if( _children.begin (), _children.end (), [&]( const auto &elem ) { return ( &child == elem.get() ); } );
113 if ( i == _children.end() ) {
114 WAR << "Unknown child sent a finished message, ignoring" << std::endl;
115 return;
116 }
117
118 const auto idx = std::distance ( _children.begin (), i );
119 _children.erase(i);
120 _childInfo.erase( _childInfo.begin () + idx );
121
122 }
123
124 ZYPP_IMPL_PRIVATE_CONSTR_ARGS ( ProgressObserver, const std::string &label, int steps ) : Base( *( new ProgressObserverPrivate( *this ) ) )
125 {
126 Z_D();
127 d->_baseSteps = steps;
128 d->_label = label;
129 }
130
131 void ProgressObserverPrivate::setLabel(const std::string &label)
132 {
133 if ( _label == label )
134 return;
135 _label = label;
136 _sigLabelChanged.emit ( *z_func(), label );
137 }
138
139
141 {
142 return d_func()->_counterSteps;
143 }
144
146 {
147 Z_D();
148 {
149 zypp::DtorReset deferedReset( d->_ignoreChildSigs, false );
150 d->_ignoreChildSigs = true;
151 std::for_each( d->_children.begin (), d->_children.end(), []( auto &child ) { child->reset(); });
152 }
153 d->onChildChanged();
154 }
155
157 {
158 return 100.0 * current() / steps();
159 }
160
162 {
163 return d_func()->_counterValue;
164 }
165
166 const std::vector<ProgressObserverRef> &ProgressObserver::children()
167 {
168 return d_func()->_children;
169 }
170
171 const std::string &ProgressObserver::label() const
172 {
173 return d_func()->_label;
174 }
175
177 {
178 return d_func()->_sigLabelChanged;
179 }
180
181 SignalProxy<void (ProgressObserver &, double)> ProgressObserver::sigStepsChanged()
182 {
183 return d_func()->_sigStepsChanged;
184 }
185
186 SignalProxy<void (ProgressObserver &, double steps)> ProgressObserver::sigValueChanged()
187 {
188 return d_func()->_sigValueChanged;
189 }
190
191 SignalProxy<void (ProgressObserver &, double)> ProgressObserver::sigProgressChanged()
192 {
193 return d_func()->_sigProgressChanged;
194 }
195
196 SignalProxy<void (ProgressObserver &sender)> ProgressObserver::sigFinished()
197 {
198 return d_func()->_sigFinished;
199 }
200
201 SignalProxy<void (ProgressObserver &, ProgressObserverRef)> ProgressObserver::sigNewSubprogress()
202 {
203 return d_func()->_sigNewSubprogress;
204 }
205
207 {
208 Z_D();
209 if ( d->_baseSteps == steps )
210 return;
211
212 d->_baseSteps = steps;
213
214 // update stats
215 d->onChildChanged();
216 }
217
218 void ProgressObserver::setLabel(const std::string &label)
219 {
220 d_func()->setLabel( label );
221 }
222
224 {
225 Z_D();
226 auto set = std::max<double>(0, std::min<double>( curr, d->_baseSteps ) );
227 if ( set == d->_baseValue )
228 return;
229 d->_baseValue = set;
230
231 //update stats
232 d->onChildChanged();
233 }
234
236 {
237 return d_func()->_baseSteps;
238 }
239
241 {
242 Z_D();
243
244 // finish all children first, children are removed via their finished signal
245 while ( d->_children.size() )
246 d->_children.front()->setFinished();
247
248 setCurrent( d->_baseSteps );
249 d->_sigFinished.emit( *this );
250 }
251
252 void ProgressObserver::inc( double inc, const std::optional<std::string> &newLabel )
253 {
254 setCurrent ( d_func()->_baseValue + inc );
255 if ( newLabel ) setLabel ( *newLabel );
256 }
257
258 void ProgressObserver::registerSubTask( const ProgressObserverRef& child, float weight )
259 {
260 Z_D();
261 auto i = std::find( d->_children.begin(), d->_children.end(), child );
262 const auto adjustedWeight = std::min<float>( std::max<float>( 0.0, weight ), 1.0 );
263 if ( i != d->_children.end() ) {
264 const auto index = std::distance ( d->_children.begin (), i );
265 d->_childInfo[index]._childWeight = adjustedWeight;
266 } else {
267 d->_children.push_back( child );
268 d->_childInfo.push_back( {
269 { connectFunc ( *child, &ProgressObserver::sigStepsChanged, [this]( auto &sender, auto ){ d_func()->onChildChanged(); }, *this ),
270 connectFunc ( *child, &ProgressObserver::sigValueChanged, [this]( auto &sender, auto ){ d_func()->onChildChanged(); }, *this ),
272 }
274 });
275 d->_sigNewSubprogress.emit( *this, child );
276 }
277
278 // update stats
279 d->onChildChanged();
280 }
281
290 {
291 return [ sThis = shared_this<ProgressObserver>() ]( const zypp::ProgressData & data ){
292 auto instance = sThis.get();
293 instance->setBaseSteps ( data.max () - data.min () );
294 instance->setCurrent ( data.val () - data.min () );
295 instance->setLabel ( data.name () );
296 if ( data.finalReport() )
297 instance->setFinished();
298 return true;
299 };
300 }
301
302} // namespace zyppng
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
Assign a vaiable a certain value when going out of scope.
Definition dtorreset.h:50
Maintain [min,max] and counter (value) for progress counting.
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
static auto connectFunc(typename internal::MemberFunction< SenderFunc >::ClassType &s, SenderFunc &&sFun, ReceiverFunc &&rFunc, const Tracker &...trackers)
Definition base.h:163
static auto connect(typename internal::MemberFunction< SenderFunc >::ClassType &s, SenderFunc &&sFun, typename internal::MemberFunction< ReceiverFunc >::ClassType &recv, ReceiverFunc &&rFunc)
Definition base.h:142
Signal< void(ProgressObserver &sender) _sigFinished)
void setLabel(const std::string &label)
void onChildFinished(ProgressObserver &child)
Signal< void(ProgressObserver &sender, const std::string &str) _sigLabelChanged)
Signal< void(ProgressObserver &sender, double steps) _sigValueChanged)
Signal< void(ProgressObserver &sender, double steps) _sigProgressChanged)
std::vector< ChildInfo > _childInfo
Signal< void(ProgressObserver &sender, double steps) _sigStepsChanged)
std::vector< ProgressObserverRef > _children
ProgressObserverPrivate(ProgressObserver &p)
ProgressObserverWeakRef _parent
Signal< void(ProgressObserver &sender, ProgressObserverRef child) _sigNewSubprogress)
void inc(double inc=1.0, const std::optional< std::string > &newLabel={})
SignalProxy< void(ProgressObserver &sender, double progress) sigProgressChanged)()
SignalProxy< void(ProgressObserver &sender, double current) sigValueChanged)()
SignalProxy< void(ProgressObserver &sender, const std::string &str) sigLabelChanged)()
const std::vector< zyppng::ProgressObserverRef > & children()
zypp::ProgressData::ReceiverFnc makeProgressDataReceiver()
const std::string & label() const
void setLabel(const std::string &label)
SignalProxy< void(ProgressObserver &sender) sigFinished)()
SignalProxy< void(ProgressObserver &sender, ProgressObserverRef child) sigNewSubprogress)()
SignalProxy< void(ProgressObserver &sender, double steps) sigStepsChanged)()
void registerSubTask(const ProgressObserverRef &child, float weight=1.0)
Definition Arch.h:364
String related utilities and Regular expression matching.
ChildInfo(std::vector< connection > &&conns, float weight)
ChildInfo & operator=(ChildInfo &&other)
ChildInfo & operator=(const ChildInfo &)=delete
ChildInfo(const ChildInfo &other)=delete
#define WAR
Definition Logger.h:97
#define ZYPP_IMPL_PRIVATE_CONSTR_ARGS(Class,...)
Definition zyppglobal.h:215
#define ZYPP_IMPL_PRIVATE(Class)
Definition zyppglobal.h:91
#define Z_D()
Definition zyppglobal.h:104
#define ZYPP_DECLARE_PUBLIC(Class)
Definition zyppglobal.h:97