0031763: Foundation Classes - reporting of progress within parallel algorithms
[occt.git] / src / Message / Message_ProgressIndicator.hxx
CommitLineData
42cf5bc1 1// Created on: 2002-02-20
2// Created by: Andrey BETENEV
3// Copyright (c) 2002-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#ifndef _Message_ProgressIndicator_HeaderFile
17#define _Message_ProgressIndicator_HeaderFile
18
7e785937 19#include <Standard_TypeDef.hxx>
20#include <Standard_Mutex.hxx>
21#include <Standard_Handle.hxx>
42cf5bc1 22
25e59720 23DEFINE_STANDARD_HANDLE(Message_ProgressIndicator, Standard_Transient)
42cf5bc1 24
7e785937 25class Message_ProgressRange;
26class Message_ProgressScope;
27
28//! Defines abstract interface from program to the user.
6b55f8e3 29//! This includes progress indication and user break mechanisms.
42cf5bc1 30//!
7e785937 31//! The progress indicator controls the progress scale with range from 0 to 1.
6b55f8e3 32//!
7e785937 33//! Method Start() should be called once, at the top level of the call stack,
34//! to reset progress indicator and get access to the root range:
35//!
36//! @code{.cpp}
37//! Handle(Message_ProgressIndicator) aProgress = ...;
38//! anAlgorithm.Perform (aProgress->Start());
39//! @endcode
42cf5bc1 40//!
7e785937 41//! To advance the progress indicator in the algorithm,
42//! use the class Message_ProgressScope that provides iterator-like
43//! interface for incrementing progress; see documentation of that
44//! class for details.
45//! The object of class Message_ProgressRange will automatically advance
46//! the indicator if it is not passed to any Message_ProgressScope.
42cf5bc1 47//!
7e785937 48//! The progress indicator supports concurrent processing and
49//! can be used in multithreaded applications.
42cf5bc1 50//!
7e785937 51//! The derived class should be created to connect this interface to
52//! actual implementation of progress indicator, to take care of visualization
53//! of the progress (e.g. show total position at the graphical bar,
6b55f8e3 54//! print scopes in text mode, or else), and for implementation
55//! of user break mechanism (if necessary).
7e785937 56//!
57//! See details in documentation of methods Show() and UserBreak().
6b55f8e3 58
25e59720 59class Message_ProgressIndicator : public Standard_Transient
42cf5bc1 60{
7e785937 61 DEFINE_STANDARD_RTTIEXT(Message_ProgressIndicator, Standard_Transient)
42cf5bc1 62public:
7e785937 63 //!@name Initialization of progress indication
42cf5bc1 64
7e785937 65 //! Resets the indicator to zero, calls Reset(), and returns the range.
66 //! This range refers to the scope that has no name and is initialized
67 //! with max value 1 and step 1.
68 //! Use this method to get the top level range for progress indication.
69 Standard_EXPORT Message_ProgressRange Start();
42cf5bc1 70
7e785937 71 //! If argument is non-null handle, returns theProgress->Start().
72 //! Otherwise, returns dummy range that can be safely used in the algorithms
73 //! but not bound to progress indicator.
74 Standard_EXPORT static Message_ProgressRange Start
75 (const Handle(Message_ProgressIndicator)& theProgress);
42cf5bc1 76
7e785937 77protected:
78 //!@name Virtual methods to be defined by descendant.
79
80 //! Should return True if user has sent a break signal.
81 //!
82 //! This method can be called concurrently, thus implementation should
83 //! be thread-safe. It should not call Show() or Position() to
84 //! avoid possible data races. The method should return as soon
85 //! as possible to avoid delaying the calling algorithm.
86 //!
87 //! Default implementation returns False.
88 virtual Standard_Boolean UserBreak()
89 {
90 return Standard_False;
91 }
92
93 //! Virtual method to be defined by descendant.
94 //! Should update presentation of the progress indicator.
95 //!
96 //! It is called whenever progress position is changed.
97 //! Calls to this method from progress indicator are protected by mutex so that
98 //! it is never called concurrently for the same progress indicator instance.
99 //! Show() should return as soon as possible to reduce thread contention
100 //! in multithreaded algorithms.
101 //!
7a3e8aad 102 //! It is recommended to update (redraw, output etc.) only if progress is
103 //! advanced by at least 1% from previous update.
7e785937 104 //!
7a3e8aad 105 //! Flag isForce is intended for forcing update in case if it is required
106 //! at particular step of the algorithm; all calls to it from inside the core
107 //! mechanism (Message_Progress... classes) are done with this flag equal to False.
7e785937 108 //!
109 //! The parameter theScope is the current scope being advanced;
110 //! it can be used to show the names and ranges of the on-going scope and
111 //! its parents, providing more visibility of the current stage of the process.
112 virtual void Show (const Message_ProgressScope& theScope,
113 const Standard_Boolean isForce) = 0;
114
115 //! Call-back method called by Start(), can be redefined by descendants
116 //! if some actions are needed when the indicator is restarted.
117 virtual void Reset() {}
118
119public:
120 //!@name Auxiliary methods
42cf5bc1 121
7e785937 122 //! Returns total progress position ranged from 0 to 1.
7a3e8aad 123 //! Should not be called concurrently while the progress is advancing,
7e785937 124 //! except from implementation of method Show().
125 Standard_Real GetPosition() const
126 {
127 return myPosition;
128 }
42cf5bc1 129
7e785937 130 //! Destructor
131 Standard_EXPORT ~Message_ProgressIndicator();
42cf5bc1 132
133protected:
42cf5bc1 134
7e785937 135 //! Constructor
42cf5bc1 136 Standard_EXPORT Message_ProgressIndicator();
137
42cf5bc1 138private:
139
7e785937 140 //! Increment the progress value by the specified step,
141 //! then calls Show() to update presentation.
142 //! The parameter theScope is reference to the caller object;
143 //! it is passed to Show() where can be used to track context of the process.
144 void Increment (const Standard_Real theStep, const Message_ProgressScope& theScope);
42cf5bc1 145
7e785937 146private:
42cf5bc1 147
7e785937 148 Standard_Real myPosition; //!< Total progress position ranged from 0 to 1
149 Standard_Mutex myMutex; //!< Protection of myPosition from concurrent increment
150 Message_ProgressScope* myRootScope; //!< The root progress scope
42cf5bc1 151
7e785937 152private:
153 friend class Message_ProgressScope; //!< Friend: can call Increment()
154 friend class Message_ProgressRange; //!< Friend: can call Increment()
42cf5bc1 155};
156
7e785937 157#include <Message_ProgressScope.hxx>
42cf5bc1 158
7e785937 159//=======================================================================
160//function : Increment
161//purpose :
162//=======================================================================
163inline void Message_ProgressIndicator::Increment(const Standard_Real theStep,
164 const Message_ProgressScope& theScope)
165{
166 // protect incrementation by mutex to avoid problems in multithreaded scenarios
167 Standard_Mutex::Sentry aSentry(myMutex);
42cf5bc1 168
7e785937 169 myPosition = Min(myPosition + theStep, 1.);
42cf5bc1 170
7e785937 171 // show progress indicator; note that this call is protected by
172 // the same mutex to avoid concurrency and ensure that this call
173 // to Show() will see the position exactly as it was just set above
174 Show(theScope, Standard_False);
175}
42cf5bc1 176
177#endif // _Message_ProgressIndicator_HeaderFile