1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkIterationReporter_h
19 #define itkIterationReporter_h
20 
21 #include "itkProcessObject.h"
22 
23 namespace itk
24 {
25 /** \class IterationReporter
26  * \brief Implements iterations tracking for a filter.
27  *
28  * This is a utility class for use by filter implementations in
29  * GenerateData() and ThreadedGenerateData().
30  *
31  * This class is intended to be used in iterative filter for which
32  * a progress cannot be stablished. These filters run until an stopping
33  * criterion is reached and it is not possible to anticipate how long
34  * it will take to get to the stopping point.
35  *
36  * This class is constructed before entering the iteration loop in the
37  * filter. The CompletedStep() method should be called at every iteration.
38  * The reporter will count the number of calls and will invoke an
39  * IterationEvent every certain number of calls. The default period
40  * is 100.
41  *
42  * Example usage:
43  *
44  *   IterationReporter iteration(this, threadId, 100);
45  *
46  *   for( each pixel )
47  *     {
48  *     ...
49  *     iteration.CompletedStep();
50  *     }
51  *
52  * When used in a non-threaded filter, the threadId argument should be 0.
53  * \ingroup ITKCommon
54  */
55 class ITKCommon_EXPORT IterationReporter
56 {
57 public:
58   /** Constructor sets progress to 0 because the filter is starting.  */
59   IterationReporter(ProcessObject *filter, ThreadIdType threadId,
60                     unsigned long stepsPerUpdate = 100);
61 
62   /** Destructor */
63   ~IterationReporter() = default;
64 
65   /** Called by a filter once per iteration.  */
CompletedStep()66   void CompletedStep()
67   {
68     // Inline implementation for efficiency.
69     // We don't need to test for thread id 0 here because the
70     // constructor sets m_StepsBeforeUpdate to a value larger than
71     // the number of pixels for threads other than 0.
72     if ( --m_StepsBeforeUpdate == 0 )
73       {
74       m_StepsBeforeUpdate = m_StepsPerUpdate;
75       m_Filter->InvokeEvent( IterationEvent() );
76       }
77   }
78 
79 protected:
80   ProcessObject *m_Filter;
81   ThreadIdType   m_ThreadId;
82   unsigned long  m_StepsPerUpdate;
83   unsigned long  m_StepsBeforeUpdate;
84 };
85 } // end namespace itk
86 
87 #endif
88