OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 <sstream>
26 #include <string>
27 #include <set>
28 
29 #include <boost/utility.hpp>
30 
31 #include "WProgressCombiner.h"
32 
34  WProgress( name, 1 ),
35  m_name( name ),
36  m_progress( 0.0 )
37 {
38  // initialize members
39  m_pending = false;
40 }
41 
43 {
44  // cleanup
45 }
46 
48 {
49  // This updates the internal state. Here, all states from child progress' get combined.
50 
51  // get read lock
52  boost::shared_lock< boost::shared_mutex > rlock;
53  rlock = boost::shared_lock< boost::shared_mutex >( m_updateLock );
54 
55  m_pending = false;
56  m_determined = true;
57  m_progress = 0.0;
58  unsigned int numPendingChildren = 0;
59 
60  // as the children define this progress' state -> iterate children
61  for( std::set< boost::shared_ptr< WProgress > >::iterator i = m_children.begin(); i != m_children.end(); ++i )
62  {
63  // enforce child to update
64  ( *i )->update();
65 
66  // update own state basing on child states.
67  if( ( *i )->isPending() )
68  {
69  // This actually builds the mean value. This might cause backstepping in progress, which is not wanted.
70  m_pending = true;
71  m_determined &= ( *i )->isDetermined();
72  m_progress += ( *i )->getProgress();
73  numPendingChildren++;
74  }
75  }
76  if( numPendingChildren )
77  {
78  m_progress /= static_cast< float >( numPendingChildren );
79  }
80 
81  rlock.unlock();
82 }
83 
85 {
86  // read lock combiner
87  boost::shared_lock< boost::shared_mutex > rlock = boost::shared_lock< boost::shared_mutex >( m_updateLock );
88 
89  std::stringstream ss;
90  ss << "[";
91  for( std::set< boost::shared_ptr< WProgress > >::const_iterator i = m_children.begin(); i != m_children.end(); ++i )
92  {
93  // enforce child to update
94  ss << ( *i )->getName();
95  if( boost::next( i ) != m_children.end() )
96  {
97  ss << ", ";
98  }
99  }
100  ss << "]";
101 
102  // Done. Free lock.
103  rlock.unlock();
104  return ss.str();
105 }
106 
107 void WProgressCombiner::addSubProgress( boost::shared_ptr< WProgress > progress )
108 {
109  boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_updateLock );
110  // add the progress to the children list
111  m_children.insert( progress );
112  lock.unlock();
113 }
114 
115 void WProgressCombiner::removeSubProgress( boost::shared_ptr< WProgress > progress )
116 {
117  boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_updateLock );
118  // add the progress to the children list
119  m_children.erase( progress );
120  lock.unlock();
121 }
122 
124 {
125  // combiner just propagate the finish request down to all children
126  boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_updateLock );
127 
128  // as the children define this progress' state -> iterate children
129  for( std::set< boost::shared_ptr< WProgress > >::iterator i = m_children.begin(); i != m_children.end(); ++i )
130  {
131  // enforce child to update
132  ( *i )->finish();
133  ( *i )->update();
134  }
135 
136  // remove the children
137  m_children.clear();
138 
139  // set the defaults
141  m_progress = 0.0;
142 
143  lock.unlock();
144 }
145 
147 {
148  // in progress combiners, this can be ignored. The progress is defined by the children.
149  return *this;
150 }
151 
153 {
154  return m_progress;
155 }
156