00001 /* 00002 * The information in this file is 00003 * Copyright(c) 2007 Ball Aerospace & Technologies Corporation 00004 * and is subject to the terms and conditions of the 00005 * GNU Lesser General Public License Version 2.1 00006 * The license text is available from 00007 * http://www.gnu.org/licenses/lgpl.html 00008 */ 00009 00010 #ifndef PROGRESSTRACKER_H 00011 #define PROGRESSTRACKER_H 00012 00013 #include <vector> 00014 #include <string> 00015 00016 #include "MessageLogResource.h" 00017 #include "Progress.h" 00018 00019 /** 00020 * Exception class for algorithm aborts. 00021 */ 00022 class AlgorithmAbort 00023 { 00024 public: 00025 /** 00026 * Construct a new %AlgorithmAbort with a specified message. 00027 * 00028 * @param message 00029 * The message to associate with this exception. 00030 */ 00031 AlgorithmAbort(std::string message) : 00032 mMessage(message) 00033 { 00034 } 00035 00036 /** 00037 * Access the message. 00038 * 00039 * @return The message associated with this exception. 00040 */ 00041 std::string getText() const 00042 { 00043 return mMessage; 00044 } 00045 00046 private: 00047 std::string mMessage; 00048 }; 00049 00050 /** 00051 * Automatically track progress basic on predefined steps. 00052 * 00053 * @note There are short term plans to replace ProgressTracker 00054 * with a similar system that functions more like StepResource. 00055 * Keep watching the release notes and the developer's mailing 00056 * list for announcements. 00057 */ 00058 class ProgressTracker 00059 { 00060 public: 00061 /** 00062 * This is a stage in a progress track. 00063 */ 00064 class Stage 00065 { 00066 public: 00067 /** 00068 * Construct an empty stage. 00069 * This is not usually called and exists as an 00070 * implementation detail of the %ProgressTracker 00071 */ 00072 Stage() : mWeight(-1), mpParent(NULL), mSubStageWeight(-1), mWeightComplete(-1), mpStep(NULL) {} 00073 00074 /** 00075 * Construct a stage. 00076 * 00077 * @param message 00078 * This is the message associated with this stage. 00079 * 00080 * @param component 00081 * The component for the message log %Step. See Message. 00082 * 00083 * @param key 00084 * The key for the message log %Step. See Message. 00085 * 00086 * @param weight 00087 * A multiplier specifying how much weight the %Stage holds compared to its siblings. 00088 */ 00089 Stage(const std::string &message, const std::string &component, const std::string &key, int weight = 1); 00090 00091 /** 00092 * Destructor. 00093 */ 00094 ~Stage(); 00095 00096 /** 00097 * Accessor for the parent of this %Stage. 00098 * 00099 * @return A pointer to the parent or NULL if this is the root %Stage. 00100 */ 00101 Stage* getParent() const; 00102 00103 /** 00104 * Accessor for the %MessageLog %Step associated with this stage. 00105 * 00106 * @return The %Step associated with this %Stage. 00107 */ 00108 Step *getStep(); 00109 00110 /** 00111 * Set this %Stage as a child of \a pParent. 00112 * This is called internally by %ProgressTracker. 00113 * 00114 * @param pParent 00115 * The parent of this %Stage 00116 */ 00117 void initialize(Stage *pParent); 00118 00119 /** 00120 * Finalize a &Stage. 00121 * This is called internalled by %ProgressTracker. 00122 * 00123 * @param result 00124 * The result of the %Stage's execution. See Message. 00125 * 00126 * @param failureReason 00127 * The optional reason for failure of the %Stage. 00128 */ 00129 void finalize(Message::Result result, const std::string &failureReason = ""); 00130 00131 /** 00132 * Subdivide a %Stage into a series of sub-stages. 00133 * 00134 * @param stages 00135 * The vector of sub-stages. 00136 */ 00137 void subdivide(std::vector<Stage>& stages); 00138 00139 /** 00140 * Advance to the next sub-stage. 00141 */ 00142 void toNextSubStage(); 00143 00144 /** 00145 * Return the active %Stage. 00146 * 00147 * @return The active sub-stage or this %Stage if there is no active sub-stage. 00148 */ 00149 Stage &getActiveStage(); 00150 00151 /** 00152 * Get the percentage complete of this %Stage. 00153 * 00154 * @param percent 00155 * This will be returned if there are no sub-stages. 00156 * 00157 * @return The percentage complete. 00158 */ 00159 int getPercentComplete(int percent) const; 00160 00161 /** 00162 * Get the message associated with this %Stage and all sub-stages. 00163 * 00164 * @param message 00165 * This will be prefixed to the messages of sub-stages. 00166 * 00167 * @param indent 00168 * This string is used to indent messages of sub-stages. 00169 * 00170 * @return A composite message calculated from sub-stages. 00171 */ 00172 std::string getActiveMessage(std::string message, std::string indent) const; 00173 00174 private: 00175 std::string mMessage; 00176 std::string mComponent; 00177 std::string mKey; 00178 int mWeight; 00179 mutable Stage* mpParent; 00180 std::vector<Stage> mSubStages; 00181 std::vector<Stage>::iterator mCurrentSubStage; 00182 int mSubStageWeight; 00183 int mWeightComplete; 00184 StepResource mpStep; 00185 }; 00186 00187 /** 00188 * Construct an empty progress tracker. 00189 */ 00190 ProgressTracker() : mpProgress(NULL) {} 00191 00192 /** 00193 * Construct a progress tracker with a %Progress object and %Step message. 00194 * This convenience constructor is equivalent to constructing an empty 00195 * progress tracker then calling initialize(). 00196 * 00197 * @param pProgress 00198 * The %Progress object associated with this tracker. 00199 * 00200 * @param message 00201 * The message of the root %Stage. 00202 * 00203 * @param component 00204 * The component associated with the root message log %Step. 00205 * 00206 * @param key 00207 * The key associated with the root message log %Step. 00208 */ 00209 ProgressTracker(Progress *pProgress, const std::string &message, 00210 const std::string &component, const std::string &key) 00211 { 00212 initialize(pProgress, message, component, key); 00213 } 00214 00215 /** 00216 * Initialize a tracker. 00217 * 00218 * @param pProgress 00219 * The %Progress object associated with this tracker. 00220 * 00221 * @param message 00222 * The message of the root %Stage. 00223 * 00224 * @param component 00225 * The component associated with the root message log %Step. 00226 * 00227 * @param key 00228 * The key associated with the root message log %Step. 00229 */ 00230 void initialize(Progress *pProgress, const std::string &message, 00231 const std::string &component, const std::string &key); 00232 00233 /** 00234 * Initialize a tracker using the existing Progress object. 00235 * 00236 * @param message 00237 * The message of the root %Stage. 00238 * 00239 * @param component 00240 * The component associated with the root message log %Step. 00241 * 00242 * @param key 00243 * The key associated with the root message log %Step. 00244 */ 00245 void initialize(const std::string &message, const std::string &component, const std::string &key) 00246 { 00247 initialize(mpProgress, message, component, key); 00248 } 00249 00250 /** 00251 * Subdivide the current &Stage into sub-stages. 00252 * 00253 * @param stages 00254 * The sub-stage vector. 00255 */ 00256 void subdivideCurrentStage(std::vector<Stage>& stages); 00257 00258 /** 00259 * Finalize the current sub-stage and set the current stage to its parent. 00260 */ 00261 void upALevel(); 00262 00263 /** 00264 * Advance to the next sub-stage. 00265 */ 00266 void nextStage(); 00267 00268 /** 00269 * Report progress within a %Stage. 00270 * 00271 * @param text 00272 * The text to send to the message log and %Progress object. 00273 * 00274 * @param percent 00275 * The new percentage complete for the current %Stage. 00276 * 00277 * @param gran 00278 * The ReportingLevel associated with this report. 00279 * 00280 * @param log 00281 * Should the message be sent to the message log as well as the %Progress object? 00282 */ 00283 void report(const std::string &text, int percent, ReportingLevel gran, bool log = false); 00284 00285 /** 00286 * Get the current status as reported by the %Progess object. 00287 * 00288 * @param text 00289 * Output argument which will hold the current %Progress object text. 00290 * 00291 * @param percent 00292 * Output argument which will hold the current %Progress object percent complete. 00293 * 00294 * @param level 00295 * Output argument which will hold the current state of the %Progress object. 00296 * 00297 * @return True if successfull, false if there is no %Progress object. 00298 */ 00299 bool getStatus(std::string &text, int& percent, ReportingLevel &level) 00300 { 00301 if (mpProgress != NULL) 00302 { 00303 mpProgress->getProgress(text, percent, level); 00304 } 00305 else 00306 { 00307 text = ""; 00308 percent = 0; 00309 level = NORMAL; 00310 } 00311 return mpProgress != NULL; 00312 } 00313 00314 /** 00315 * Get the Progress object associated with the current step. 00316 * 00317 * @return Pointer to the current Progress or NULL if there is no current Progress. 00318 */ 00319 Progress* getCurrentProgress() const 00320 { 00321 return mpProgress; 00322 } 00323 00324 /** 00325 * Abort the process tracked by this %ProgressTracker. 00326 */ 00327 void abort(); 00328 00329 /** 00330 * Accessor for the message log %Step associated with the current %Stage. 00331 * 00332 * @return The %Step associated with the current %Stage. 00333 */ 00334 Step *getCurrentStep(); 00335 00336 private: 00337 Progress* mpProgress; 00338 Stage mMainStage; 00339 }; 00340 00341 /** 00342 * Resource for subdividing the current %Stage. 00343 */ 00344 class ProgressSubdivision 00345 { 00346 public: 00347 /** 00348 * Construct a %ProgressSubdivision in a specified %ProgressTracker. 00349 * 00350 * @param pTracker 00351 * The tracker to subdivide. 00352 * 00353 * @param stages 00354 * The vector of sub-stages. 00355 */ 00356 ProgressSubdivision(ProgressTracker *pTracker, std::vector<ProgressTracker::Stage> &stages) : 00357 mpTracker(pTracker), 00358 mStageCount(static_cast<int>(stages.size())) 00359 { 00360 mpTracker->subdivideCurrentStage(stages); 00361 } 00362 00363 /** 00364 * Destructor. 00365 * Automatically moves up to the parent %Stage of the subdivision managed by this resource. 00366 */ 00367 ~ProgressSubdivision() 00368 { 00369 if (mStageCount > 0) 00370 { 00371 mpTracker->upALevel(); 00372 } 00373 } 00374 00375 private: 00376 ProgressTracker* mpTracker; 00377 int mStageCount; 00378 }; 00379 00380 #endif