1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef itkTotalProgressReporter_h
#define itkTotalProgressReporter_h
#include "itkIntTypes.h"
#include "itkProcessObject.h"
namespace itk
{
/** \class TotalProgressReporter
* \brief A progress reporter for concurrent threads.
*
* Each thread should construct their own instance of the class. The ProcessObject::IncrementProgress method will be
* called to update the progress from all threads. The ProcessObject's method will automatically create ProgressEvents
* when the pipeline invoking thread updates the progress.
*
* All threads concurrently contribute parts of the progress to the *total* number of pixels for all threads. This
* report will update the progress after a sufficient number of pixel to meet the numberOfUpdates requirement between
* all threads. Also when the object is deconstructed, all remaining pixels will increment the progress.
*
*
* \ingroup ITKCommon
*/
class ITKCommon_EXPORT TotalProgressReporter
{
public:
ITK_DISALLOW_COPY_AND_MOVE(TotalProgressReporter);
/** \brief Construct a TotalProgressReporter
*
* @param filter - the ProcessObject which whose progress will be updated. If nullptr then no updates will occur.
* @param totalNumberOfPixels - the number of pixels between all threads and chunks that will be updated.
* If zero, any completed chunk will result in a progress event.
* @param numberOfUpdates - controls how often the ProcessObject's progress will be incremented
* @param progressWeight - A percentage of the filters progress, this total number of pixels will contribute
*/
TotalProgressReporter(ProcessObject * filter,
SizeValueType totalNumberOfPixels,
SizeValueType numberOfUpdates = 100,
float progressWeight = 1.0f);
/** Destructor sets progress to 1 because the filter has finished. */
~TotalProgressReporter();
/** Check if the filter has the ProcessObject::AbortGenerateData
* flag set. If true, then a ProcessAborted exception will be thrown.
*/
void
CheckAbortGenerateData()
{
// all threads needs to check the abort flag
if (m_Filter && m_Filter->GetAbortGenerateData())
{
std::string msg;
ProcessAborted e(__FILE__, __LINE__);
msg += "Object " + std::string(m_Filter->GetNameOfClass()) + ": AbortGenerateDataOn";
e.SetDescription(msg);
throw e;
}
}
/** Called by a filter once per pixel. */
void
CompletedPixel()
{
// Inline implementation for efficiency.
if (--m_PixelsBeforeUpdate == 0)
{
m_PixelsBeforeUpdate = m_PixelsPerUpdate;
m_CurrentPixel += m_PixelsPerUpdate;
if (m_Filter)
{
m_Filter->IncrementProgress(m_PixelsPerUpdate * m_InverseNumberOfPixels * m_ProgressWeight);
this->CheckAbortGenerateData();
}
}
}
/** Called by a filter when a chunk, region, scan-line, etc. is completed. */
void
Completed(SizeValueType count)
{
if (count >= m_PixelsBeforeUpdate)
{
SizeValueType total = static_cast<SizeValueType>(m_PixelsPerUpdate - m_PixelsBeforeUpdate) + count;
SizeValueType numberOfUpdates = total / m_PixelsPerUpdate;
m_PixelsBeforeUpdate = m_PixelsPerUpdate - total % m_PixelsPerUpdate;
m_CurrentPixel += numberOfUpdates * m_PixelsPerUpdate;
if (m_Filter)
{
m_Filter->IncrementProgress(numberOfUpdates * m_PixelsPerUpdate * m_InverseNumberOfPixels * m_ProgressWeight);
this->CheckAbortGenerateData();
}
}
else
{
m_PixelsBeforeUpdate -= count;
}
}
protected:
ProcessObject * m_Filter;
float m_InverseNumberOfPixels;
SizeValueType m_CurrentPixel;
SizeValueType m_PixelsPerUpdate;
SizeValueType m_PixelsBeforeUpdate;
float m_ProgressWeight;
};
} // end namespace itk
#endif
|