mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0031763: Foundation Classes - reporting of progress within parallel algorithms
Classes Message_ProgressRange and Message_ProgressScope are improved to store start point of the range. Method Message_ProgressScope::Value() is improved to compute the value in the current scope from the actual current value of the global progress. Description of Message_ProgressScope class is improved. Off-topic: - method Message_ProgressScope::Relieve() is renamed to Close() for semantic consistency - article in Upgrade Guide is revised and corrected
This commit is contained in:
@@ -1935,26 +1935,38 @@ Offset direction, which used in class Adaptor2d_OffsetCurve for evaluating value
|
||||
|
||||
Adaptor2d_OffsetCurve aOC(BaseCurve, Offset) --> Adaptor2d_OffsetCurve aOC(BaseCurve, -Offset)
|
||||
|
||||
subsection upgrade_750_ProgressIndicator Change of Message_ProgressIndicator
|
||||
@subsection upgrade_750_ProgressIndicator Change of progress indication API
|
||||
|
||||
The progress indication mechanism has been revised to eliminate its weak points in previous design (leading to ambiguity and unprotected from an error-prone behavior).
|
||||
Redesign also allows using progress indicator in multi-threaded algorithms in more straight-forward way with minimal overhead.
|
||||
Note, however, that multi-threaded algorithm should pre-allocate per-thread progress scopes in advance to ensure thread-safety - check new classes API for details.
|
||||
The progress indication mechanism has been revised to eliminate its weak points in
|
||||
previous design (leading to implementation mistakes).
|
||||
Redesign also allows using progress indicator in multi-threaded algorithms
|
||||
in more straight-forward way with minimal overhead.
|
||||
Note however, that multi-threaded algorithm should pre-allocate per-task
|
||||
progress ranges in advance to ensure thread-safety -
|
||||
see examples in documentation of class Message_ProgressScope for details.
|
||||
|
||||
Classes Message_ProgressSentry and Message_ProgressScale have been removed.
|
||||
New classes Message_ProgressScope and Messge_ProgressRange replace them and should be used as main API classes to organize progress indication in the algorithms.
|
||||
Instances of the class Message_ProgressRange are used to pass the progress capability to nested levels of the algorithm
|
||||
and an instance of the class Message_ProgressScope is to be created (preferably as local variable) to manage progress at each level of the algorithm.
|
||||
New classes Message_ProgressScope and Message_ProgressRange should be used as main
|
||||
API classes to organize progress indication in the algorithms.
|
||||
Instances of the class Message_ProgressRange are used to pass the progress capability to
|
||||
nested levels of the algorithm, and an instance of the class Message_ProgressScope is to
|
||||
be created (preferably as local variable) to manage progress at each level of the algorithm.
|
||||
The instance of Message_ProgressIndicator is not passed anymore to sub-algorithms.
|
||||
See documentation of the class Message_ProgressScope for more details and examples.
|
||||
|
||||
Methods to deal with progress scopes and to advance progress are removed from class Message_ProgressIndicator; now it only provides interface to the application-level progress indicator.
|
||||
Virtual method Message_ProgressIndicator::Show() has changed its signature and should be updated accordingly in descendants of Message_ProgressIndicator.
|
||||
The scope passed as argument to this method can be used to obtain information on context of the current process (instead of calling method GetScope() in previous implementation).
|
||||
Methods Show(), UserBreak(), and Reset() are made protected in class Message_ProgressIndicator; method More() of Message_ProgressScope should be used to know if the cancel event has come.
|
||||
See documentation of the class Message_ProgressIndicator for more details and implementation of Draw_ProgressIndicator for an example.
|
||||
Methods to deal with progress scopes and to advance progress are removed from class
|
||||
Message_ProgressIndicator; now it only provides interface to the application-level progress indicator.
|
||||
Virtual method Message_ProgressIndicator::Show() has changed its signature and should be
|
||||
updated accordingly in descendants of Message_ProgressIndicator.
|
||||
The scope passed as argument to this method can be used to obtain information on context
|
||||
of the current process (instead of calling method GetScope() in previous implementation).
|
||||
Methods Show(), UserBreak(), and Reset() are made protected in class Message_ProgressIndicator;
|
||||
methods More() or UserBreak() of classes Message_ProgressScope or Message_ProgressRange should
|
||||
be used to know if the cancel event has come.
|
||||
See documentation of the class Message_ProgressIndicator for more details and implementation
|
||||
of Draw_ProgressIndicator for an example.
|
||||
|
||||
Lets take a look onto typical algorithm using an old API:
|
||||
Let's take a look onto typical algorithm using an old API:
|
||||
@code
|
||||
class MyAlgo
|
||||
{
|
||||
@@ -1967,7 +1979,10 @@ public:
|
||||
{
|
||||
Message_ProgressSentry aPSentry1 (theProgress, "Stage 1", 0, 153, 1);
|
||||
for (int anIter = 0; anIter < 153; ++anIter, aPSentry1.Next())
|
||||
{ if (!aPSentry1.More()) { return false; } }
|
||||
{
|
||||
if (!aPSentry1.More()) { return false; }
|
||||
// do some job here...
|
||||
}
|
||||
}
|
||||
aPSentry.Next();
|
||||
{
|
||||
@@ -1982,9 +1997,9 @@ private:
|
||||
//! Nested sub-algorithm taking Progress Indicator.
|
||||
bool perform2 (const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
Message_ProgressSentry aPSentry2 (theProgress, "Stage 2", 0, 561, 1);
|
||||
for (int anIter = 0; anIter < 561 && aPSentry2.More(); ++anIter, aPSentry2.Next()) {}
|
||||
return aPSentry2.More();
|
||||
Message_ProgressSentry aPSentry2 (theProgress, "Stage 2", 0, 100, 1);
|
||||
for (int anIter = 0; anIter < 100 && aPSentry2.More(); ++anIter, aPSentry2.Next()) {}
|
||||
return !aPSentry2.UserBreak();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1995,19 +2010,25 @@ anAlgo.Perform ("FileName", aProgress);
|
||||
@endcode
|
||||
|
||||
The following guidance can be used to update such code:
|
||||
- Replace `const Handle(Message_ProgressIndicator)&` with `const Message_ProgressRange&`.
|
||||
- Replace `const Handle(Message_ProgressIndicator)&` with `const Message_ProgressRange&`
|
||||
in arguments of the methods that support progress indication.
|
||||
Message_ProgressIndicator object should be now created only at place where application starts algorithms.
|
||||
- Replace `Message_ProgressSentry` with `Message_ProgressScope`.
|
||||
Take note that Message_ProgressScope has smaller number of arguments (no "minimal value").
|
||||
In other aspects, Message_ProgressScope mimics an iterator-style interface (with methods More() and Next())
|
||||
close to the old Message_ProgressSentry (pay attention to extra functionality of Message_ProgressScope::Next() method below).
|
||||
- Each Message_ProgressScope should take the next Range to fill in.
|
||||
Within old API, Message_ProgressSentry received the root Progress Indicator object and implicitly split it into ranges using error-prone logic.
|
||||
Message_ProgressScope in new API takes Message_ProgressRange, which should be created from the Range of the parent Scope using value returned by Message_ProgressScope::Next() method.
|
||||
Don't use the same Range passed to the algorithm for all sub-Scopes like it was possible in old API.
|
||||
- Check user abortion state using Message_ProgressScope::UserBreak() method;
|
||||
Message_ProgressRange is a temporary object with the only purpose to create a new Message_ProgressScope,
|
||||
and Message_ProgressIndicator should be never passed directly to algorithms.
|
||||
Take note that Message_ProgressScope has less arguments (no "minimal value").
|
||||
In other aspects, Message_ProgressScope mimics an iterator-style interface
|
||||
(with methods More() and Next()) close to the old Message_ProgressSentry (pay attention
|
||||
to extra functionality of Message_ProgressScope::Next() method below).
|
||||
Note that method Message_ProgressScope::Close() is equivalent of the method
|
||||
Relieve() of Message_ProgressSentry in previous version.
|
||||
Class Message_ProgressSentry is still defined (marked as deprecated) providing
|
||||
API more close to old one, and can be still used to reduce porting efforts.
|
||||
- Each Message_ProgressScope should take the next Range object to work with.
|
||||
Within old API, Message_ProgressSentry received the root Progress Indicator
|
||||
object which mantained the sequence of ranges internally.
|
||||
Message_ProgressScope in new API takes Message_ProgressRange, which should be
|
||||
returned by Message_ProgressScope::Next() method of the parent scope.
|
||||
Do not use the same Range passed to the algorithm for all sub-Scopes like
|
||||
it was possible in old API; each range object may be used only once.
|
||||
|
||||
Take a look onto ported code and compare with code above to see differences:
|
||||
|
||||
@@ -2023,7 +2044,10 @@ public:
|
||||
{
|
||||
Message_ProgressScope aPSentry1 (aPSentry.Next(), "Stage 1", 153);
|
||||
for (int anIter = 0; anIter < 153; ++anIter, aPSentry1.Next())
|
||||
{ if (!aPSentry1.More()) { return false; }; }
|
||||
{
|
||||
if (!aPSentry1.More()) { return false; };
|
||||
// do some job here...
|
||||
}
|
||||
}
|
||||
{
|
||||
perform2 (aPSentry.Next());
|
||||
@@ -2035,9 +2059,9 @@ public:
|
||||
//! Nested sub-algorithm taking Progress sub-Range.
|
||||
bool perform2 (const Message_ProgressRange& theProgress)
|
||||
{
|
||||
Message_ProgressScope aPSentry2 (theProgress, "Stage 2", 561);
|
||||
for (int anIter = 0; anIter < 561 && aPSentry2.More(); ++anIter, aPSentry2.Next()) {}
|
||||
return aPSentry2.More();
|
||||
Message_ProgressScope aPSentry2 (theProgress, "Stage 2", 100);
|
||||
for (int anIter = 0; anIter < 100 && aPSentry2.More(); ++anIter, aPSentry2.Next()) {}
|
||||
return !aPSentry2.UserBreak();
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user