ProgressDisplay.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00026 #include <cmath>
00027 
00028 #include <iostream>
00029 #include <iomanip>
00030 #include <hugin_math/hugin_math.h>
00031 
00032 #include "ProgressDisplay.h"
00033 
00034 using namespace std;
00035 
00036 namespace AppBase {
00037 
00038     
00039 
00040 
00041 void ProgressDisplay::startSubtaskWithTask(const ProgressSubtask& newSubtask)
00042 {
00043     o_subtasks.push_back(newSubtask);
00044     subtaskStarted();
00045     updateProgressDisplay();
00046 }
00047 
00048 void ProgressDisplay::setParentProgressOfNewSubtasks(double subtaskTotalProgress, bool propagatesProgress)
00049 {
00050     if(subtaskTotalProgress < 0)
00051         return;
00052 
00053     o_newSubtaskProgress = subtaskTotalProgress;
00054     o_newSubtaskPropagates = propagatesProgress;
00055 };
00056 
00057 
00058 void ProgressDisplay::startSubtask(const std::string& message,
00059                                    const double& maxProgress,
00060                                    const double& progressForParentTask,
00061                                    const bool& propagatesProgress)
00062 {
00063     ProgressSubtask newSubtask = ProgressSubtask(message, maxProgress, progressForParentTask, propagatesProgress);
00064 
00065     startSubtaskWithTask(newSubtask);
00066 };
00067 
00068 
00069 void ProgressDisplay::startSubtask(const std::string& message,
00070                                    const double& maxProgress)
00071 {
00072     if(o_newSubtaskProgress > 0)
00073         startSubtask(message, maxProgress, o_newSubtaskProgress, o_newSubtaskPropagates);
00074     else
00075         startSubtask(message, maxProgress, 0, false);
00076 };
00077 
00078 
00079 void ProgressDisplay::startSubtask(const double& maxProgress)
00080 { 
00081     startSubtask("", maxProgress);
00082 };
00083    
00084 
00085 void ProgressDisplay::setSubtaskMessage(const std::string& message)
00086     { getCurrentSubtask().message = message; }
00087 
00088 
00089 std::string ProgressDisplay::getSubtaskMessage() const
00090 {
00091     return getCurrentSubtask().message;
00092 }
00093 
00094 
00095 double ProgressDisplay::getSubtaskMaxProgress() const
00096 {
00097     assert(!noSubtasksAvailable()); //[TODO] make it nicer:)
00098     return getCurrentSubtask().maxProgress;
00099 }
00100     
00101 
00102 double ProgressDisplay::getSubtaskProgress() const
00103 {
00104     assert(!noSubtasksAvailable()); //[TODO] make it nicer:)
00105     return getCurrentSubtask().progress;
00106 }
00107 
00108 
00109 void ProgressDisplay::updateSubtaskProgress(const double& newValue)
00110 {
00111     if(noSubtasksAvailable())
00112     {
00113         DEBUG_INFO("No subtask available");
00114         return;
00115     }
00116     
00117     if(getCurrentSubtask().progress > newValue)
00118     {
00119         DEBUG_INFO("Progress has already reached its max.");
00120         return;
00121     }
00122     
00123     propagateProgress(newValue);
00124     //getCurrentSubtask().progress = std::min(newValue, getSubtaskMaxProgress());
00125     updateProgressDisplay();
00126 }
00127 
00128 
00129 void ProgressDisplay::increaseSubtaskProgressBy(const double& deltaValue)
00130 {
00131     updateSubtaskProgress(getSubtaskProgress() + deltaValue);
00132 }
00133 
00134 
00135 void ProgressDisplay::finishSubtask()
00136 {
00137     subtaskFinished();
00138     
00139     if (!o_subtasks.back().measuresProgress() && o_subtasks.size()>1) {
00140         o_subtasks[o_subtasks.size()-2].progress += o_subtasks[o_subtasks.size()-1].progressForParentTask;
00141     }
00142     
00143     o_subtasks.pop_back();
00144     updateProgressDisplay();
00145 }
00146 
00147 
00148 void ProgressDisplay::cancelTask()
00149 {
00150     o_canceled = true;
00151     // more to do?
00152 }
00153 
00154 
00155 bool ProgressDisplay::wasCancelled()
00156     { return o_canceled; }
00157     
00158 
00159 
00160 
00161 void ProgressDisplay::propagateProgress(const double& newProgress)
00162 {
00163     std::vector<ProgressSubtask>::reverse_iterator itr = o_subtasks.rbegin();
00164     
00165     double diffFromPrev = newProgress - itr->progress;
00166     
00167     if(diffFromPrev <= 0)
00168         return;
00169     
00170     do {
00171         
00172         DEBUG_INFO("Propagating progress:+" << diffFromPrev*100 << "%");
00173         
00174         itr->progress += diffFromPrev;
00175         
00176         if(!itr->propagatesProgress)
00177         {
00178             DEBUG_INFO("Propagation stopped.");
00179             return;
00180         }
00181         
00182         // scale previous change for higher level
00183         diffFromPrev *= itr->progressForParentTask / itr->maxProgress;
00184         ++itr;
00185         
00186     } while(itr != o_subtasks.rend());
00187 }
00188 
00189 
00190 ProgressDisplay::ProgressSubtask& ProgressDisplay::getCurrentSubtask() const
00191     { return (ProgressSubtask& )o_subtasks.back(); }
00192 
00193 
00194 bool ProgressDisplay::noSubtasksAvailable() const
00195     { return o_subtasks.empty(); }
00196 
00197 
00198 
00199 void StreamProgressDisplay::updateProgressDisplay()
00200 {
00201     // TODO: check for Ctrl-C then cancelTask() ?
00202 
00203     // step back the line printed before.
00204     if (m_printedLines == 0 )
00205     {
00206         m_stream << endl;
00207     }
00208     m_printedLines = 1;
00209     // build the message
00210 
00211     int strlen=0;
00212     ostringstream stream;
00213 #if defined _WINDOWS
00214     stream << setfill('\b') << setw(81);
00215 #else
00216     stream << "\r";
00217 #endif
00218     for (std::vector<ProgressSubtask>::iterator it = o_subtasks.begin();
00219          it != o_subtasks.end(); ++it)
00220     {
00221         if (stream.str().size() + it->message.size() > 70) {
00222             break;
00223         }
00224         if (it != o_subtasks.begin()) {
00225             stream << ", ";
00226         }
00227         stream << it->message;
00228 
00229         std::vector<ProgressSubtask>::iterator next = it;
00230         ++next;
00231     }
00232     bool showProgress=false;
00233     if(o_subtasks.size()>0)
00234         showProgress=o_subtasks[0].measuresProgress();
00235     if(showProgress){
00236         stream << ": " << setw(3) << hugin_utils::roundi( 100.0 * o_subtasks[0].progress / o_subtasks[0].maxProgress) << "%";
00237     } else {
00238         m_whizzCount = (++m_whizzCount) % (int)m_whizz.size();
00239         stream << ": "  << m_whizz[m_whizzCount] << "   ";
00240     }
00241 
00242     int fill = 81-stream.str().size();
00243     stream << setw(fill) << " ";
00244     m_stream << stream.str() << flush;
00245 }
00246 
00247 
00248 
00249 }; //namespace

Generated on 26 Nov 2014 for Hugintrunk by  doxygen 1.4.7