libzypp 17.37.10

progressobserver.cc
Go to the documentation of this file.
1#include "progressobserver.h"
2#include "zypp-core/AutoDispose.h"
3#include <zypp-core/zyppng/base/private/base_p.h>
4#include <zypp-core/base/dtorreset.h>
5
6 namespace zyppng {
7
8 class ProgressObserverPrivate : public BasePrivate
9 {
10 ZYPP_DECLARE_PUBLIC(ProgressObserver)
11 public:
12 ProgressObserverPrivate( ProgressObserver &p ) : BasePrivate(p) {}
13
14
15 void updateProgress ();
16 void setLabel( const std::string &label );
17
18
19 ProgressObserverWeakRef _parent;
20 std::string _label;
21
22 // the current counter value
23 double _counterValue = 0;
24
25 // the number of steps we are going to have
26 double _counterSteps = 0;
27
28 // the value of all finished progresses
29 double _finishedValue = 0;
30
31 // the steps of all finished progresses
32 double _finishedSteps = 0;
33
34 int _baseValue = 0;
35 int _baseSteps = 100;
36
37 bool _started = false;
38 bool _ignoreChildSigs = false;
39
40 struct ChildInfo {
41 ChildInfo( std::vector<connection> &&conns, float weight ) : _signalConns( std::move(conns) ), _childWeight( weight ) {}
42 ChildInfo( ChildInfo &&other ) noexcept
43 : _signalConns( std::move(other._signalConns) )
44 , _childWeight( other._childWeight )
45 {
46 other._signalConns.clear ();
47 }
48 ChildInfo( const ChildInfo &other ) = delete;
49 ~ChildInfo() {
50 std::for_each( _signalConns.begin (), _signalConns.end(), []( auto &sig ){ sig.disconnect(); });
51 }
52
53 ChildInfo &operator=( const ChildInfo & ) = delete;
54 ChildInfo &operator=( ChildInfo &&other )
55 {
56 _childWeight = other._childWeight;
57 _signalConns = std::move(other._signalConns);
58 other._signalConns.clear ();
59 return *this;
60 }
61
62 std::vector<connection> _signalConns;
63 float _childWeight = 1.0; // the factor how much increase a step in the child is worth in the parent
64 };
65
66 std::vector<ProgressObserverRef> _children;
67 std::vector< ChildInfo > _childInfo;
68
69 void onChildStarted(ProgressObserver &);
70 void updateCounters();
71 void onChildFinished( ProgressObserver &child , ProgressObserver::FinishResult );
72
73 Signal<void ( ProgressObserver &sender) > _sigStarted;
74 Signal<void ( ProgressObserver &sender, const std::string &str )> _sigLabelChanged;
75 Signal<void ( ProgressObserver &sender, double steps ) > _sigStepsChanged;
76 Signal<void ( ProgressObserver &sender, double steps ) > _sigValueChanged;
77 Signal<void ( ProgressObserver &sender, double steps ) > _sigProgressChanged;
78 Signal<void ( ProgressObserver &sender, ProgressObserver::FinishResult )> _sigFinished;
79 Signal<void ( ProgressObserver &sender, ProgressObserverRef child )> _sigNewSubprogress;
80 };
81
82 ZYPP_IMPL_PRIVATE(ProgressObserver)
83
84 void ProgressObserverPrivate::onChildStarted( ProgressObserver &/*child*/ )
85 {
86 if ( !_started ) z_func()->start();
87 }
88
89 void ProgressObserverPrivate::updateCounters()
90 {
91 if ( _ignoreChildSigs )
92 return;
93
94 double currProgressSteps = _baseValue;
95 double accumSteps = static_cast<double>(_baseSteps);
96
97 for ( std::vector<ProgressObserverRef>::size_type i = 0; i < _children.size (); i++ ) {
98 const auto childPtr = _children[i].get();
99 const auto &childInfo = _childInfo[i];
100 const auto weight = childInfo._childWeight;
101 currProgressSteps += childPtr->current() * weight;
102 accumSteps += childPtr->steps()* weight;
103 }
104
105 bool notifyAccuMaxSteps = _counterSteps != accumSteps ;
106 bool notifyCurrSteps = _counterValue != currProgressSteps;
107
108 _counterSteps = accumSteps;
109 _counterValue = currProgressSteps;
110
111 if ( !_started )
112 return;
113
114 if ( notifyAccuMaxSteps )
115 _sigStepsChanged.emit( *z_func(), _counterSteps );
116 if ( notifyCurrSteps) {
117 _sigValueChanged.emit( *z_func(), notifyCurrSteps );
118 _sigProgressChanged.emit( *z_func(), z_func()->progress() );
119 }
120 }
121
122 void ProgressObserverPrivate::onChildFinished(ProgressObserver &child, ProgressObserver::FinishResult )
123 {
124 auto i = std::find_if( _children.begin (), _children.end (), [&]( const auto &elem ) { return ( &child == elem.get() ); } );
125 if ( i == _children.end() ) {
126 WAR << "Unknown child sent a finished message, ignoring" << std::endl;
127 return;
128 }
129
130 const auto idx = std::distance ( _children.begin (), i );
131 _children.erase(i);
132 _childInfo.erase( _childInfo.begin () + idx );
133 updateCounters();
134 }
135
136 ZYPP_IMPL_PRIVATE_CONSTR_ARGS ( ProgressObserver, const std::string &label, int steps ) : Base( *( new ProgressObserverPrivate( *this ) ) )
137 {
138 Z_D();
139 d->_baseSteps = steps;
140 d->_label = label;
141 d->updateCounters();
142 }
143
144 void ProgressObserverPrivate::setLabel(const std::string &label)
145 {
146 if ( _label == label )
147 return;
148 _label = label;
149 _sigLabelChanged.emit ( *z_func(), label );
150 }
151
152
153 int ProgressObserver::steps() const
154 {
155 return d_func()->_counterSteps;
156 }
157
158 bool ProgressObserver::started() const
159 {
160 return d_func()->_started;
161 }
162
163 void ProgressObserver::start()
164 {
165 Z_D();
166 if ( d->_started )
167 return;
168
169 d->updateCounters();
170
171 d->_started = true;
172 d->_sigStarted.emit( *this );
173 }
174
175 void ProgressObserver::reset()
176 {
177 Z_D();
178 {
179 zypp::DtorReset deferedReset( d->_ignoreChildSigs, false );
180 d->_ignoreChildSigs = true;
181 std::for_each( d->_children.begin (), d->_children.end(), []( auto &child ) { child->reset(); });
182 }
183 d->updateCounters();
184 }
185
186 double ProgressObserver::progress() const
187 {
188 return 100.0 * current() / steps();
189 }
190
191 double ProgressObserver::current() const
192 {
193 return d_func()->_counterValue;
194 }
195
196 const std::vector<ProgressObserverRef> &ProgressObserver::children()
197 {
198 return d_func()->_children;
199 }
200
201 const std::string &ProgressObserver::label() const
202 {
203 return d_func()->_label;
204 }
205
206 SignalProxy<void (ProgressObserver &)> ProgressObserver::sigStarted()
207 {
208 return d_func()->_sigStarted;
209 }
210
211 SignalProxy<void (ProgressObserver &, const std::string &)> ProgressObserver::sigLabelChanged()
212 {
213 return d_func()->_sigLabelChanged;
214 }
215
216 SignalProxy<void (ProgressObserver &, double)> ProgressObserver::sigStepsChanged()
217 {
218 return d_func()->_sigStepsChanged;
219 }
220
221 SignalProxy<void (ProgressObserver &, double steps)> ProgressObserver::sigValueChanged()
222 {
223 return d_func()->_sigValueChanged;
224 }
225
226 SignalProxy<void (ProgressObserver &, double)> ProgressObserver::sigProgressChanged()
227 {
228 return d_func()->_sigProgressChanged;
229 }
230
231 SignalProxy<void (ProgressObserver &sender, ProgressObserver::FinishResult result)> ProgressObserver::sigFinished()
232 {
233 return d_func()->_sigFinished;
234 }
235
236 SignalProxy<void (ProgressObserver &, ProgressObserverRef)> ProgressObserver::sigNewSubprogress()
237 {
238 return d_func()->_sigNewSubprogress;
239 }
240
241 void ProgressObserver::setBaseSteps(int steps)
242 {
243 Z_D();
244 if ( d->_baseSteps == steps )
245 return;
246
247 d->_baseSteps = steps;
248
249 // update stats
250 d->updateCounters();
251 }
252
253 void ProgressObserver::setLabel(const std::string &label)
254 {
255 d_func()->setLabel( label );
256 }
257
258 void ProgressObserver::setCurrent(double curr)
259 {
260 Z_D();
261 auto set = std::max<double>(0, std::min<double>( curr, d->_baseSteps ) );
262 if ( set == d->_baseValue )
263 return;
264 d->_baseValue = set;
265
266 //update stats
267 d->updateCounters();
268 }
269
270 int ProgressObserver::baseSteps() const
271 {
272 return d_func()->_baseSteps;
273 }
274
275 void ProgressObserver::setFinished( FinishResult result )
276 {
277 Z_D();
278
279 // finish all children first, started children are removed via their finished signal
280 // others we have to manually remove
281 while ( d->_children.size() ) {
282 auto back = d->_children.back();
283 bool remove = !back->started ();
284 back->setFinished( result );
285 if ( remove ) d->_children.pop_back();
286 }
287
288 if ( result != Error )
289 setCurrent( d->_baseSteps );
290
291 if ( d->_started )
292 d->_sigFinished.emit( *this , result );
293 }
294
295 void ProgressObserver::inc( double inc, const std::optional<std::string> &newLabel )
296 {
297 setCurrent ( d_func()->_baseValue + inc );
298 if ( newLabel ) setLabel ( *newLabel );
299 }
300
301 void ProgressObserver::registerSubTask( const ProgressObserverRef& child, float weight )
302 {
303 Z_D();
304 auto i = std::find( d->_children.begin(), d->_children.end(), child );
305 const auto adjustedWeight = std::min<float>( std::max<float>( 0.0, weight ), 1.0 );
306 if ( i != d->_children.end() ) {
307 const auto index = std::distance ( d->_children.begin (), i );
308 d->_childInfo[index]._childWeight = adjustedWeight;
309 } else {
310 d->_children.push_back( child );
311 d->_childInfo.push_back( {
312 { connectFunc ( *child, &ProgressObserver::sigStepsChanged, [this]( auto &sender, auto ){ d_func()->updateCounters(); }, *this ),
313 connectFunc ( *child, &ProgressObserver::sigValueChanged, [this]( auto &sender, auto ){ d_func()->updateCounters(); }, *this ),
314 connect ( *child, &ProgressObserver::sigStarted, *d, &ProgressObserverPrivate::onChildStarted ),
315 connect ( *child, &ProgressObserver::sigFinished, *d, &ProgressObserverPrivate::onChildFinished )
316 }
317 , adjustedWeight
318 });
319 d->_sigNewSubprogress.emit( *this, child );
320
321 // if the child has been started already, we also need to start()
322 if ( child->started () )
323 start();
324 }
325
326 // update stats
327 d->updateCounters();
328 }
329
330 ProgressObserverRef ProgressObserver::makeSubTask( float weight, const std::string &label, int steps )
331 {
332 auto r = ProgressObserver::create( label, steps );
333 registerSubTask ( r, weight );
334 return r;
335 }
336
344 zypp::ProgressData::ReceiverFnc ProgressObserver::makeProgressDataReceiver()
345 {
346 return [ sThis = shared_this<ProgressObserver>() ]( const zypp::ProgressData & data ){
347 auto instance = sThis.get();
348 instance->start();
349 instance->setBaseSteps ( data.max () - data.min () );
350 instance->setCurrent ( data.val () - data.min () );
351 instance->setLabel ( data.name () );
352 if ( data.finalReport() )
353 instance->setFinished();
354 return true;
355 };
356 }
357
358} // namespace zyppng
base_p.h
zypp::DtorReset
Assign a vaiable a certain value when going out of scope.
Definition dtorreset.h:50
zypp::ProgressData
Maintain [min,max] and counter (value) for progress counting.
Definition progressdata.h:132
zypp::ProgressData::ReceiverFnc
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition progressdata.h:140
zyppng::BasePrivate::BasePrivate
BasePrivate(Base &b)
Definition base_p.h:17
zyppng::Base
Definition base.h:60
zyppng::Base::shared_this
std::shared_ptr< T > shared_this() const
Definition base.h:113
zyppng::Base::connectFunc
static auto connectFunc(typename internal::MemberFunction< SenderFunc >::ClassType &s, SenderFunc &&sFun, ReceiverFunc &&rFunc, const Tracker &...trackers)
Definition base.h:163
zyppng::Base::connect
static auto connect(typename internal::MemberFunction< SenderFunc >::ClassType &s, SenderFunc &&sFun, typename internal::MemberFunction< ReceiverFunc >::ClassType &recv, ReceiverFunc &&rFunc)
Definition base.h:142
zyppng::ProgressObserverPrivate
Definition progressobserver.cc:9
zyppng::ProgressObserverPrivate::updateProgress
void updateProgress()
zyppng::ProgressObserverPrivate::setLabel
void setLabel(const std::string &label)
Definition progressobserver.cc:144
zyppng::ProgressObserverPrivate::_baseValue
int _baseValue
Definition progressobserver.cc:34
zyppng::ProgressObserverPrivate::_sigLabelChanged
Signal< void(ProgressObserver &sender, const std::string &str)> _sigLabelChanged
Definition progressobserver.cc:74
zyppng::ProgressObserverPrivate::onChildFinished
void onChildFinished(ProgressObserver &child, ProgressObserver::FinishResult)
Definition progressobserver.cc:122
zyppng::ProgressObserverPrivate::_started
bool _started
Definition progressobserver.cc:37
zyppng::ProgressObserverPrivate::_baseSteps
int _baseSteps
Definition progressobserver.cc:35
zyppng::ProgressObserverPrivate::_sigNewSubprogress
Signal< void(ProgressObserver &sender, ProgressObserverRef child)> _sigNewSubprogress
Definition progressobserver.cc:79
zyppng::ProgressObserverPrivate::_sigStepsChanged
Signal< void(ProgressObserver &sender, double steps) > _sigStepsChanged
Definition progressobserver.cc:75
zyppng::ProgressObserverPrivate::_counterValue
double _counterValue
Definition progressobserver.cc:23
zyppng::ProgressObserverPrivate::_childInfo
std::vector< ChildInfo > _childInfo
Definition progressobserver.cc:67
zyppng::ProgressObserverPrivate::_sigProgressChanged
Signal< void(ProgressObserver &sender, double steps) > _sigProgressChanged
Definition progressobserver.cc:77
zyppng::ProgressObserverPrivate::_children
std::vector< ProgressObserverRef > _children
Definition progressobserver.cc:66
zyppng::ProgressObserverPrivate::onChildStarted
void onChildStarted(ProgressObserver &)
Definition progressobserver.cc:84
zyppng::ProgressObserverPrivate::_label
std::string _label
Definition progressobserver.cc:20
zyppng::ProgressObserverPrivate::_sigFinished
Signal< void(ProgressObserver &sender, ProgressObserver::FinishResult)> _sigFinished
Definition progressobserver.cc:78
zyppng::ProgressObserverPrivate::ProgressObserverPrivate
ProgressObserverPrivate(ProgressObserver &p)
Definition progressobserver.cc:12
zyppng::ProgressObserverPrivate::_parent
ProgressObserverWeakRef _parent
Definition progressobserver.cc:19
zyppng::ProgressObserverPrivate::_sigValueChanged
Signal< void(ProgressObserver &sender, double steps) > _sigValueChanged
Definition progressobserver.cc:76
zyppng::ProgressObserverPrivate::_counterSteps
double _counterSteps
Definition progressobserver.cc:26
zyppng::ProgressObserverPrivate::_sigStarted
Signal< void(ProgressObserver &sender) > _sigStarted
Definition progressobserver.cc:73
zyppng::ProgressObserverPrivate::_ignoreChildSigs
bool _ignoreChildSigs
Definition progressobserver.cc:38
zyppng::ProgressObserverPrivate::_finishedValue
double _finishedValue
Definition progressobserver.cc:29
zyppng::ProgressObserverPrivate::updateCounters
void updateCounters()
Definition progressobserver.cc:89
zyppng::ProgressObserverPrivate::_finishedSteps
double _finishedSteps
Definition progressobserver.cc:32
zyppng::ProgressObserver
Definition progressobserver.h:28
zyppng::ProgressObserver::sigValueChanged
SignalProxy< void(ProgressObserver &sender, double current) > sigValueChanged()
Definition progressobserver.cc:221
zyppng::ProgressObserver::sigStarted
SignalProxy< void(ProgressObserver &sender)> sigStarted()
Definition progressobserver.cc:206
zyppng::ProgressObserver::inc
void inc(double inc=1.0, const std::optional< std::string > &newLabel={})
Definition progressobserver.cc:295
zyppng::ProgressObserver::sigFinished
SignalProxy< void(ProgressObserver &sender, FinishResult result)> sigFinished()
Definition progressobserver.cc:231
zyppng::ProgressObserver::steps
int steps() const
Definition progressobserver.cc:153
zyppng::ProgressObserver::setBaseSteps
void setBaseSteps(int steps)
Definition progressobserver.cc:241
zyppng::ProgressObserver::setLabel
static void setLabel(ProgressObserverRef progress, const std::string &label)
Definition progressobserver.h:86
zyppng::ProgressObserver::makeSubTask
static ProgressObserverRef makeSubTask(ProgressObserverRef parentProgress, float weight=1.0, const std::string &label=std::string(), int steps=100)
Definition progressobserver.h:62
zyppng::ProgressObserver::children
const std::vector< zyppng::ProgressObserverRef > & children()
Definition progressobserver.cc:196
zyppng::ProgressObserver::sigStepsChanged
SignalProxy< void(ProgressObserver &sender, double steps)> sigStepsChanged()
Definition progressobserver.cc:216
zyppng::ProgressObserver::current
double current() const
Definition progressobserver.cc:191
zyppng::ProgressObserver::makeProgressDataReceiver
zypp::ProgressData::ReceiverFnc makeProgressDataReceiver()
Definition progressobserver.cc:344
zyppng::ProgressObserver::label
const std::string & label() const
Definition progressobserver.cc:201
zyppng::ProgressObserver::started
bool started() const
Definition progressobserver.cc:158
zyppng::ProgressObserver::progress
double progress() const
Definition progressobserver.cc:186
zyppng::ProgressObserver::setCurrent
void setCurrent(double curr)
Definition progressobserver.cc:258
zyppng::ProgressObserver::sigProgressChanged
SignalProxy< void(ProgressObserver &sender, double progress)> sigProgressChanged()
Definition progressobserver.cc:226
zyppng::ProgressObserver::setFinished
void setFinished(FinishResult result=Success)
Definition progressobserver.cc:275
zyppng::ProgressObserver::reset
void reset()
Definition progressobserver.cc:175
zyppng::ProgressObserver::baseSteps
int baseSteps() const
Definition progressobserver.cc:270
zyppng::ProgressObserver::FinishResult
FinishResult
Definition progressobserver.h:34
zyppng::ProgressObserver::Error
@ Error
Definition progressobserver.h:36
zyppng::ProgressObserver::sigNewSubprogress
SignalProxy< void(ProgressObserver &sender, ProgressObserverRef child)> sigNewSubprogress()
Definition progressobserver.cc:236
zyppng::ProgressObserver::registerSubTask
void registerSubTask(const ProgressObserverRef &child, float weight=1.0)
Definition progressobserver.cc:301
zyppng::ProgressObserver::sigLabelChanged
SignalProxy< void(ProgressObserver &sender, const std::string &str)> sigLabelChanged()
Definition progressobserver.cc:211
zyppng::ProgressObserver::start
void start()
Definition progressobserver.cc:163
zyppng::SignalProxy
Definition signals.h:325
zyppng::Signal
Definition signals.h:151
dtorreset.h
std
Definition Arch.h:364
str
String related utilities and Regular expression matching.
zyppng
Definition MediaNetworkRequestExecutor.h:16
progressobserver.h
zyppng::ProgressObserverPrivate::ChildInfo::_childWeight
float _childWeight
Definition progressobserver.cc:63
zyppng::ProgressObserverPrivate::ChildInfo::ChildInfo
ChildInfo(ChildInfo &&other) noexcept
Definition progressobserver.cc:42
zyppng::ProgressObserverPrivate::ChildInfo::ChildInfo
ChildInfo(std::vector< connection > &&conns, float weight)
Definition progressobserver.cc:41
zyppng::ProgressObserverPrivate::ChildInfo::operator=
ChildInfo & operator=(ChildInfo &&other)
Definition progressobserver.cc:54
zyppng::ProgressObserverPrivate::ChildInfo::operator=
ChildInfo & operator=(const ChildInfo &)=delete
zyppng::ProgressObserverPrivate::ChildInfo::ChildInfo
ChildInfo(const ChildInfo &other)=delete
zyppng::ProgressObserverPrivate::ChildInfo::_signalConns
std::vector< connection > _signalConns
Definition progressobserver.cc:62
zyppng::ProgressObserverPrivate::ChildInfo::~ChildInfo
~ChildInfo()
Definition progressobserver.cc:49
AutoDispose.h
WAR
#define WAR
Definition Logger.h:101
ZYPP_IMPL_PRIVATE_CONSTR_ARGS
#define ZYPP_IMPL_PRIVATE_CONSTR_ARGS(Class,...)
Definition zyppglobal.h:224
ZYPP_IMPL_PRIVATE
#define ZYPP_IMPL_PRIVATE(Class)
Definition zyppglobal.h:92
Z_D
#define Z_D()
Definition zyppglobal.h:105
ZYPP_DECLARE_PUBLIC
#define ZYPP_DECLARE_PUBLIC(Class)
Definition zyppglobal.h:98