OpenWalnut  1.5.0dev
WProgressCombiner.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <memory>
26 #include <set>
27 #include <sstream>
28 #include <string>
29 
30 #include <boost/utility.hpp>
31 
32 #include "WProgressCombiner.h"
33 
35  WProgress( name, 1 ),
36  m_name( name ),
37  m_progress( 0.0 )
38 {
39  // initialize members
40  m_pending = false;
41 }
42 
44 {
45  // cleanup
46 }
47 
49 {
50  // This updates the internal state. Here, all states from child progress' get combined.
51 
52  // get read lock
53  boost::shared_lock< std::shared_mutex > rlock;
54  rlock = boost::shared_lock< std::shared_mutex >( m_updateLock );
55 
56  m_pending = false;
57  m_determined = true;
58  m_progress = 0.0;
59  unsigned int numPendingChildren = 0;
60 
61  // as the children define this progress' state -> iterate children
62  for( std::set< std::shared_ptr< WProgress > >::iterator i = m_children.begin(); i != m_children.end(); ++i )
63  {
64  // enforce child to update
65  ( *i )->update();
66 
67  // update own state basing on child states.
68  if( ( *i )->isPending() )
69  {
70  // This actually builds the mean value. This might cause backstepping in progress, which is not wanted.
71  m_pending = true;
72  m_determined &= ( *i )->isDetermined();
73  m_progress += ( *i )->getProgress();
74  numPendingChildren++;
75  }
76  }
77  if( numPendingChildren )
78  {
79  m_progress /= static_cast< float >( numPendingChildren );
80  }
81 
82  rlock.unlock();
83 }
84 
85 std::string WProgressCombiner::getCombinedNames( bool excludeFinished ) const
86 {
87  // read lock combiner
88  boost::shared_lock< std::shared_mutex > rlock = boost::shared_lock< std::shared_mutex >( m_updateLock );
89 
90  std::stringstream ss;
91  bool addComma = false; // when true, a "," is appended before printing the next name. This is needed as we do not know if an element is the
92  // last one if excludeFinished == true.
93  for( std::set< std::shared_ptr< WProgress > >::const_iterator i = m_children.begin(); i != m_children.end(); ++i )
94  {
95  if( !( !( *i )->isPending() && excludeFinished ) )
96  {
97  if( addComma )
98  {
99  ss << ", ";
100  }
101 
102  // enforce child to update
103  ss << ( *i )->getName();
104  // in next step, add a comma
105  addComma = true;
106  }
107  }
108 
109  // Done. Free lock.
110  rlock.unlock();
111  return ss.str();
112 }
113 
114 void WProgressCombiner::addSubProgress( std::shared_ptr< WProgress > progress )
115 {
116  std::unique_lock<std::shared_mutex> lock = std::unique_lock<std::shared_mutex>( m_updateLock );
117  // add the progress to the children list
118  m_children.insert( progress );
119  lock.unlock();
120 }
121 
122 void WProgressCombiner::removeSubProgress( std::shared_ptr< WProgress > progress )
123 {
124  std::unique_lock<std::shared_mutex> lock = std::unique_lock<std::shared_mutex>( m_updateLock );
125  // add the progress to the children list
126  m_children.erase( progress );
127  lock.unlock();
128 }
129 
131 {
132  // combiner just propagate the finish request down to all children
133  std::unique_lock<std::shared_mutex> lock = std::unique_lock<std::shared_mutex>( m_updateLock );
134 
135  // as the children define this progress' state -> iterate children
136  for( std::set< std::shared_ptr< WProgress > >::iterator i = m_children.begin(); i != m_children.end(); ++i )
137  {
138  // enforce child to update
139  ( *i )->finish();
140  ( *i )->update();
141  }
142 
143  // remove the children
144  m_children.clear();
145 
146  // set the defaults
148  m_progress = 0.0;
149 
150  lock.unlock();
151 }
152 
154 {
155  // in progress combiners, this can be ignored. The progress is defined by the children.
156  return *this;
157 }
158 
160 {
161  return m_progress;
162 }
163 
Base class for all kinds of progress combinations.
virtual void removeSubProgress(std::shared_ptr< WProgress > progress)
Removes the specified sub progress from this combiner.
virtual void addSubProgress(std::shared_ptr< WProgress > progress)
Adds a new progress to this combiner.
virtual void update()
Function updating the internal state.
WProgressCombiner(std::string name="")
Default constructor.
std::shared_mutex m_updateLock
Lock for the above child set and the internal state update.
std::set< std::shared_ptr< WProgress > > m_children
Set of all child progress.
virtual ~WProgressCombiner()
Destructor.
virtual float getProgress()
Returns the overall progress of this progress instance, including the child progress'.
virtual void finish()
Stops the progress.
virtual WProgressCombiner & operator++()
Simple increment operator to signal a forward stepping.
std::string getCombinedNames(bool excludeFinished=false) const
Generates a string combined out of every child progress name.
float m_progress
The current conglomerated progress.
Class managing progress inside of modules.
Definition: WProgress.h:42
virtual void finish()
Stops the progress.
Definition: WProgress.cpp:57
bool m_pending
Flag denoting whether the progress is running or not.
Definition: WProgress.h:155
bool m_determined
True if the progress has a known end point.
Definition: WProgress.h:160