|
degate 0.1.1
|
00001 /* -*-c++-*- 00002 00003 This file is part of the IC reverse engineering tool degate. 00004 00005 Copyright 2008, 2009, 2010 by Martin Schobert 00006 00007 Degate is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 any later version. 00011 00012 Degate is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with degate. If not, see <http://www.gnu.org/licenses/>. 00019 00020 */ 00021 00022 #ifndef __PROGRESSCONTROL_H__ 00023 #define __PROGRESSCONTROL_H__ 00024 00025 #include <tr1/memory> 00026 #include <time.h> 00027 #include <boost/thread.hpp> 00028 00029 namespace degate { 00030 00031 /** 00032 */ 00033 00034 class ProgressControl { 00035 00036 private: 00037 00038 const static int averaging_buf_size = 5; 00039 00040 double progress; 00041 bool canceled; 00042 00043 double step_size; 00044 time_t time_started; 00045 00046 time_t estimated[averaging_buf_size]; 00047 int estimated_idx; 00048 00049 std::string log_message; 00050 bool log_message_set; 00051 00052 boost::recursive_mutex mtx; 00053 00054 private: 00055 00056 time_t get_time_left_averaged() { 00057 estimated[estimated_idx++] = get_time_left(); 00058 estimated_idx %= averaging_buf_size; 00059 00060 unsigned int sum = 0, valid_values = 0; 00061 for(int i = 0; i < averaging_buf_size; i++) 00062 if(estimated[i] != -1) { 00063 sum += estimated[i]; 00064 valid_values++; 00065 } 00066 00067 return valid_values > 0 ? sum / valid_values : get_time_left_averaged(); 00068 } 00069 00070 protected: 00071 00072 /** 00073 * Set progress. 00074 */ 00075 virtual void set_progress(double progress) { 00076 boost::recursive_mutex::scoped_lock(mtx); 00077 this->progress = progress; 00078 } 00079 00080 /** 00081 * Set step size. 00082 */ 00083 virtual void set_progress_step_size(double step_size) { 00084 boost::recursive_mutex::scoped_lock(mtx); 00085 this->step_size = step_size; 00086 } 00087 00088 /** 00089 * Increase progress. 00090 */ 00091 virtual void progress_step_done() { 00092 boost::recursive_mutex::scoped_lock(mtx); 00093 progress += step_size; 00094 } 00095 00096 /** 00097 * Reset progress and cancel state. 00098 */ 00099 virtual void reset_progress() { 00100 boost::recursive_mutex::scoped_lock(mtx); 00101 time_started = time(NULL); 00102 canceled = false; 00103 progress = 0; 00104 00105 for(int i = 0; i < averaging_buf_size; i++) estimated[i] = -1; 00106 00107 estimated_idx = 0; 00108 } 00109 00110 public: 00111 00112 /** 00113 * The constructor 00114 */ 00115 00116 ProgressControl() : log_message_set(false) { 00117 reset_progress(); 00118 } 00119 00120 /** 00121 * The destructor for a plugin. 00122 */ 00123 00124 virtual ~ProgressControl() {} 00125 00126 /** 00127 * Check if the process is canceled. 00128 */ 00129 00130 virtual bool is_canceled() const { 00131 boost::recursive_mutex::scoped_lock(mtx); 00132 return canceled; 00133 } 00134 00135 /** 00136 * Stop the processing. 00137 */ 00138 00139 virtual void cancel() { 00140 boost::recursive_mutex::scoped_lock(mtx); 00141 canceled = true; 00142 } 00143 00144 00145 /** 00146 * Get progress. 00147 * @return Returns a value between 0 and 100 percent. 00148 */ 00149 00150 virtual double get_progress() const { 00151 boost::recursive_mutex::scoped_lock(mtx); 00152 return progress; 00153 } 00154 00155 /** 00156 * Get (real) time since the progress counter was resetted. 00157 */ 00158 virtual time_t get_time_passed() const { 00159 boost::mutex::scoped_lock(m_mutex); 00160 return time(NULL) - time_started; 00161 } 00162 00163 /** 00164 * Get estimated time left in seconds. 00165 * @return Returns the time to go in seconds or -1, if 00166 * that time cannot be calculated. 00167 */ 00168 virtual time_t get_time_left() const { 00169 boost::recursive_mutex::scoped_lock(mtx); 00170 if(progress < 1.0) 00171 return progress > 0 ? (1.0 - progress) * get_time_passed() / progress : -1; 00172 return 0; 00173 } 00174 00175 virtual std::string get_time_left_as_string() { 00176 boost::recursive_mutex::scoped_lock(mtx); 00177 time_t time_left = get_time_left_averaged(); 00178 if(time_left == -1) return std::string("-"); 00179 else { 00180 char buf[100]; 00181 if(time_left < 60) 00182 snprintf(buf, sizeof(buf), "%d s", (int)time_left); 00183 else if(time_left < 60*60) 00184 snprintf(buf, sizeof(buf), "%d:%02d m", (int)time_left / 60, (int)time_left % 60); 00185 else { 00186 unsigned int minutes = (int)time_left / 60; 00187 snprintf(buf, sizeof(buf), "%d:%02d h", minutes / 60, (int)time_left % 60); 00188 } 00189 return std::string(buf); 00190 } 00191 00192 } 00193 00194 00195 virtual void set_log_message(std::string const& msg) { 00196 boost::recursive_mutex::scoped_lock(mtx); 00197 log_message = msg; 00198 log_message_set = true; 00199 } 00200 00201 virtual std::string get_log_message() const { 00202 boost::recursive_mutex::scoped_lock(mtx); 00203 return log_message; 00204 } 00205 00206 virtual bool has_log_message() const { 00207 boost::recursive_mutex::scoped_lock(mtx); 00208 return log_message_set; 00209 } 00210 }; 00211 00212 typedef std::tr1::shared_ptr<ProgressControl> ProgressControl_shptr; 00213 } 00214 00215 #endif 00216
1.7.4