VirtualBox

source: vbox/trunk/src/VBox/Main/include/ProgressImpl.h@ 23454

Last change on this file since 23454 was 23223, checked in by vboxsync, 15 years ago

API: big medium handling change and lots of assorted other cleanups and fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
Line 
1/* $Id: ProgressImpl.h 23223 2009-09-22 15:50:03Z vboxsync $ */
2/** @file
3 *
4 * VirtualBox COM class implementation
5 */
6
7/*
8 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#ifndef ____H_PROGRESSIMPL
24#define ____H_PROGRESSIMPL
25
26#include "VirtualBoxBase.h"
27
28#include <VBox/com/SupportErrorInfo.h>
29
30#include <iprt/semaphore.h>
31
32#include <vector>
33
34class VirtualBox;
35
36////////////////////////////////////////////////////////////////////////////////
37
38/**
39 * Base component class for progress objects.
40 */
41class ATL_NO_VTABLE ProgressBase :
42 public VirtualBoxBase,
43 public com::SupportErrorInfoBase,
44 public VirtualBoxSupportTranslation<ProgressBase>,
45 VBOX_SCRIPTABLE_IMPL(IProgress)
46{
47protected:
48
49 VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (ProgressBase)
50
51 DECLARE_EMPTY_CTOR_DTOR (ProgressBase)
52
53 HRESULT FinalConstruct();
54
55 // protected initializer/uninitializer for internal purposes only
56 HRESULT protectedInit (AutoInitSpan &aAutoInitSpan,
57#if !defined (VBOX_COM_INPROC)
58 VirtualBox *aParent,
59#endif
60 IUnknown *aInitiator,
61 CBSTR aDescription, OUT_GUID aId = NULL);
62 HRESULT protectedInit (AutoInitSpan &aAutoInitSpan);
63 void protectedUninit (AutoUninitSpan &aAutoUninitSpan);
64
65public:
66
67 // IProgress properties
68 STDMETHOD(COMGETTER(Id)) (BSTR *aId);
69 STDMETHOD(COMGETTER(Description)) (BSTR *aDescription);
70 STDMETHOD(COMGETTER(Initiator)) (IUnknown **aInitiator);
71
72 // IProgress properties
73 STDMETHOD(COMGETTER(Cancelable)) (BOOL *aCancelable);
74 STDMETHOD(COMGETTER(Percent)) (ULONG *aPercent);
75 STDMETHOD(COMGETTER(TimeRemaining)) (LONG *aTimeRemaining);
76 STDMETHOD(COMGETTER(Completed)) (BOOL *aCompleted);
77 STDMETHOD(COMGETTER(Canceled)) (BOOL *aCanceled);
78 STDMETHOD(COMGETTER(ResultCode)) (LONG *aResultCode);
79 STDMETHOD(COMGETTER(ErrorInfo)) (IVirtualBoxErrorInfo **aErrorInfo);
80 STDMETHOD(COMGETTER(OperationCount)) (ULONG *aOperationCount);
81 STDMETHOD(COMGETTER(Operation)) (ULONG *aCount);
82 STDMETHOD(COMGETTER(OperationDescription)) (BSTR *aOperationDescription);
83 STDMETHOD(COMGETTER(OperationPercent)) (ULONG *aOperationPercent);
84
85 // public methods only for internal purposes
86
87 static HRESULT setErrorInfoOnThread (IProgress *aProgress);
88
89 // unsafe inline public methods for internal purposes only (ensure there is
90 // a caller and a read lock before calling them!)
91
92 BOOL completed() const { return mCompleted; }
93 HRESULT resultCode() const { return mResultCode; }
94 double calcTotalPercent();
95
96protected:
97
98#if !defined (VBOX_COM_INPROC)
99 /** Weak parent. */
100 const ComObjPtr<VirtualBox, ComWeakRef> mParent;
101#endif
102
103 const ComPtr<IUnknown> mInitiator;
104
105 const Guid mId;
106 const Bstr mDescription;
107
108 uint64_t m_ullTimestamp; // progress object creation timestamp, for ETA computation
109
110 /* The fields below are to be properly initalized by subclasses */
111
112 BOOL mCompleted;
113 BOOL mCancelable;
114 BOOL mCanceled;
115 HRESULT mResultCode;
116 ComPtr<IVirtualBoxErrorInfo> mErrorInfo;
117
118 ULONG m_cOperations; // number of operations (so that progress dialog can display something like 1/3)
119 ULONG m_ulTotalOperationsWeight; // sum of weights of all operations, given to constructor
120
121 ULONG m_ulOperationsCompletedWeight; // summed-up weight of operations that have been completed; initially 0
122
123 ULONG m_ulCurrentOperation; // operations counter, incremented with each setNextOperation()
124 Bstr m_bstrOperationDescription; // name of current operation; initially from constructor, changed with setNextOperation()
125 ULONG m_ulCurrentOperationWeight; // weight of current operation, given to setNextOperation()
126 ULONG m_ulOperationPercent; // percentage of current operation, set with setCurrentOperationProgress()
127};
128
129////////////////////////////////////////////////////////////////////////////////
130
131/**
132 * Normal progress object.
133 */
134class ATL_NO_VTABLE Progress :
135 public com::SupportErrorInfoDerived<ProgressBase, Progress, IProgress>,
136 public VirtualBoxSupportTranslation<Progress>
137{
138
139public:
140
141 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE (Progress)
142
143 DECLARE_NOT_AGGREGATABLE (Progress)
144
145 DECLARE_PROTECT_FINAL_CONSTRUCT()
146
147 BEGIN_COM_MAP (Progress)
148 COM_INTERFACE_ENTRY (ISupportErrorInfo)
149 COM_INTERFACE_ENTRY (IProgress)
150 COM_INTERFACE_ENTRY2 (IDispatch, IProgress)
151 END_COM_MAP()
152
153 HRESULT FinalConstruct();
154 void FinalRelease();
155
156 // public initializer/uninitializer for internal purposes only
157
158 /**
159 * Simplified constructor for progress objects that have only one
160 * operation as a task.
161 * @param aParent
162 * @param aInitiator
163 * @param aDescription
164 * @param aCancelable
165 * @param aId
166 * @return
167 */
168 HRESULT init(
169#if !defined (VBOX_COM_INPROC)
170 VirtualBox *aParent,
171#endif
172 IUnknown *aInitiator,
173 CBSTR aDescription,
174 BOOL aCancelable,
175 OUT_GUID aId = NULL)
176 {
177 return init(
178#if !defined (VBOX_COM_INPROC)
179 aParent,
180#endif
181 aInitiator,
182 aDescription,
183 aCancelable,
184 1, // cOperations
185 1, // ulTotalOperationsWeight
186 aDescription, // bstrFirstOperationDescription
187 1, // ulFirstOperationWeight
188 aId);
189 }
190
191 /**
192 * Not quite so simplified constructor for progress objects that have
193 * more than one operation, but all sub-operations are weighed the same.
194 * @param aParent
195 * @param aInitiator
196 * @param aDescription
197 * @param aCancelable
198 * @param cOperations
199 * @param bstrFirstOperationDescription
200 * @param aId
201 * @return
202 */
203 HRESULT init(
204#if !defined (VBOX_COM_INPROC)
205 VirtualBox *aParent,
206#endif
207 IUnknown *aInitiator,
208 CBSTR aDescription, BOOL aCancelable,
209 ULONG cOperations,
210 CBSTR bstrFirstOperationDescription,
211 OUT_GUID aId = NULL)
212 {
213 return init(
214#if !defined (VBOX_COM_INPROC)
215 aParent,
216#endif
217 aInitiator,
218 aDescription,
219 aCancelable,
220 cOperations, // cOperations
221 cOperations, // ulTotalOperationsWeight = cOperations
222 bstrFirstOperationDescription, // bstrFirstOperationDescription
223 1, // ulFirstOperationWeight: weigh them all the same
224 aId);
225 }
226
227 HRESULT init(
228#if !defined (VBOX_COM_INPROC)
229 VirtualBox *aParent,
230#endif
231 IUnknown *aInitiator,
232 CBSTR aDescription,
233 BOOL aCancelable,
234 ULONG cOperations,
235 ULONG ulTotalOperationsWeight,
236 CBSTR bstrFirstOperationDescription,
237 ULONG ulFirstOperationWeight,
238 OUT_GUID aId = NULL);
239
240 HRESULT init(BOOL aCancelable,
241 ULONG aOperationCount,
242 CBSTR aOperationDescription);
243
244 void uninit();
245
246 // IProgress methods
247 STDMETHOD(WaitForCompletion)(LONG aTimeout);
248 STDMETHOD(WaitForOperationCompletion)(ULONG aOperation, LONG aTimeout);
249 STDMETHOD(Cancel)();
250
251 STDMETHOD(SetCurrentOperationProgress)(ULONG aPercent);
252 STDMETHOD(SetNextOperation)(IN_BSTR bstrNextOperationDescription, ULONG ulNextOperationsWeight);
253
254 // public methods only for internal purposes
255
256 HRESULT setResultCode(HRESULT aResultCode);
257
258 HRESULT notifyComplete(HRESULT aResultCode);
259 HRESULT notifyComplete(HRESULT aResultCode,
260 const GUID &aIID,
261 const Bstr &aComponent,
262 const char *aText, ...);
263
264 /** For com::SupportErrorInfoImpl. */
265 static const char *ComponentName() { return "Progress"; }
266
267private:
268
269 RTSEMEVENTMULTI mCompletedSem;
270 ULONG mWaitersCount;
271};
272
273////////////////////////////////////////////////////////////////////////////////
274
275/**
276 * The CombinedProgress class allows to combine several progress objects to a
277 * single progress component. This single progress component will treat all
278 * operations of individual progress objects as a single sequence of operations
279 * that follow each other in the same order as progress objects are passed to
280 * the #init() method.
281 *
282 * Individual progress objects are sequentially combined so that this progress
283 * object:
284 *
285 * - is cancelable only if all progresses are cancelable.
286 * - is canceled once a progress that follows next to successfully completed
287 * ones reports it was canceled.
288 * - is completed successfully only after all progresses are completed
289 * successfully.
290 * - is completed unsuccessfully once a progress that follows next to
291 * successfully completed ones reports it was completed unsuccessfully;
292 * the result code and error info of the unsuccessful progress
293 * will be reported as the result code and error info of this progress.
294 * - returns N as the operation number, where N equals to the number of
295 * operations in all successfully completed progresses starting from the
296 * first one plus the operation number of the next (not yet complete)
297 * progress; the operation description of the latter one is reported as
298 * the operation description of this progress object.
299 * - returns P as the percent value, where P equals to the sum of percents
300 * of all successfully completed progresses starting from the
301 * first one plus the percent value of the next (not yet complete)
302 * progress, normalized to 100%.
303 *
304 * @note It's the respoisibility of the combined progress object creator to
305 * complete individual progresses in the right order: if, let's say, the
306 * last progress is completed before all previous ones,
307 * #WaitForCompletion(-1) will most likely give 100% CPU load because it
308 * will be in a loop calling a method that returns immediately.
309 */
310class ATL_NO_VTABLE CombinedProgress :
311 public com::SupportErrorInfoDerived<ProgressBase, CombinedProgress, IProgress>,
312 public VirtualBoxSupportTranslation<CombinedProgress>
313{
314
315public:
316
317 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE (CombinedProgress)
318
319 DECLARE_NOT_AGGREGATABLE (CombinedProgress)
320
321 DECLARE_PROTECT_FINAL_CONSTRUCT()
322
323 BEGIN_COM_MAP (CombinedProgress)
324 COM_INTERFACE_ENTRY (ISupportErrorInfo)
325 COM_INTERFACE_ENTRY (IProgress)
326 COM_INTERFACE_ENTRY2 (IDispatch, IProgress)
327 END_COM_MAP()
328
329 HRESULT FinalConstruct();
330 void FinalRelease();
331
332 // public initializer/uninitializer for internal purposes only
333
334 HRESULT init (
335#if !defined (VBOX_COM_INPROC)
336 VirtualBox *aParent,
337#endif
338 IUnknown *aInitiator,
339 CBSTR aDescription,
340 IProgress *aProgress1, IProgress *aProgress2,
341 OUT_GUID aId = NULL);
342
343 /**
344 * Initializes the combined progress object given the first and the last
345 * normal progress object from the list.
346 *
347 * @param aParent See ProgressBase::init().
348 * @param aInitiator See ProgressBase::init().
349 * @param aDescription See ProgressBase::init().
350 * @param aFirstProgress Iterator of the first normal progress object.
351 * @param aSecondProgress Iterator of the last normal progress object.
352 * @param aId See ProgressBase::init().
353 */
354 template <typename InputIterator>
355 HRESULT init (
356#if !defined (VBOX_COM_INPROC)
357 VirtualBox *aParent,
358#endif
359 IUnknown *aInitiator,
360 CBSTR aDescription,
361 InputIterator aFirstProgress, InputIterator aLastProgress,
362 OUT_GUID aId = NULL)
363 {
364 /* Enclose the state transition NotReady->InInit->Ready */
365 AutoInitSpan autoInitSpan (this);
366 AssertReturn (autoInitSpan.isOk(), E_FAIL);
367
368 mProgresses = ProgressVector (aFirstProgress, aLastProgress);
369
370 HRESULT rc = protectedInit (autoInitSpan,
371#if !defined (VBOX_COM_INPROC)
372 aParent,
373#endif
374 aInitiator, aDescription, aId);
375
376 /* Confirm a successful initialization when it's the case */
377 if (SUCCEEDED (rc))
378 autoInitSpan.setSucceeded();
379
380 return rc;
381 }
382
383protected:
384
385 HRESULT protectedInit (AutoInitSpan &aAutoInitSpan,
386#if !defined (VBOX_COM_INPROC)
387 VirtualBox *aParent,
388#endif
389 IUnknown *aInitiator,
390 CBSTR aDescription, OUT_GUID aId);
391
392public:
393
394 void uninit();
395
396 // IProgress properties
397 STDMETHOD(COMGETTER(Percent)) (ULONG *aPercent);
398 STDMETHOD(COMGETTER(Completed)) (BOOL *aCompleted);
399 STDMETHOD(COMGETTER(Canceled)) (BOOL *aCanceled);
400 STDMETHOD(COMGETTER(ResultCode)) (LONG *aResultCode);
401 STDMETHOD(COMGETTER(ErrorInfo)) (IVirtualBoxErrorInfo **aErrorInfo);
402 STDMETHOD(COMGETTER(Operation)) (ULONG *aCount);
403 STDMETHOD(COMGETTER(OperationDescription)) (BSTR *aOperationDescription);
404 STDMETHOD(COMGETTER(OperationPercent)) (ULONG *aOperationPercent);
405
406 // IProgress methods
407 STDMETHOD(WaitForCompletion) (LONG aTimeout);
408 STDMETHOD(WaitForOperationCompletion) (ULONG aOperation, LONG aTimeout);
409 STDMETHOD(Cancel)();
410
411 STDMETHOD(SetCurrentOperationProgress)(ULONG aPercent)
412 {
413 NOREF(aPercent);
414 return E_NOTIMPL;
415 }
416
417 STDMETHOD(SetNextOperation)(IN_BSTR bstrNextOperationDescription, ULONG ulNextOperationsWeight)
418 {
419 NOREF(bstrNextOperationDescription); NOREF(ulNextOperationsWeight);
420 return E_NOTIMPL;
421 }
422
423 // public methods only for internal purposes
424
425 /** For com::SupportErrorInfoImpl. */
426 static const char *ComponentName() { return "CombinedProgress"; }
427
428private:
429
430 HRESULT checkProgress();
431
432 typedef std::vector <ComPtr<IProgress> > ProgressVector;
433 ProgressVector mProgresses;
434
435 size_t mProgress;
436 ULONG mCompletedOperations;
437};
438
439#endif /* ____H_PROGRESSIMPL */
440
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette