automatic commit
[folded-ctf.git] / progress_bar.cc
1
2 ///////////////////////////////////////////////////////////////////////////
3 // This program is free software: you can redistribute it and/or modify  //
4 // it under the terms of the version 3 of the GNU General Public License //
5 // as published by the Free Software Foundation.                         //
6 //                                                                       //
7 // This program is distributed in the hope that it will be useful, but   //
8 // WITHOUT ANY WARRANTY; without even the implied warranty of            //
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      //
10 // General Public License for more details.                              //
11 //                                                                       //
12 // You should have received a copy of the GNU General Public License     //
13 // along with this program. If not, see <http://www.gnu.org/licenses/>.  //
14 //                                                                       //
15 // Written by Francois Fleuret                                           //
16 // (C) Idiap Research Institute                                          //
17 //                                                                       //
18 // Contact <francois.fleuret@idiap.ch> for comments & bug reports        //
19 ///////////////////////////////////////////////////////////////////////////
20
21 #include <time.h>
22 #include "progress_bar.h"
23
24 const int ProgressBar::_width = 80;
25
26 ProgressBar::ProgressBar()  : _visible(false), _value_max(-1) { }
27
28 void ProgressBar::set_visible(bool visible) {
29   _visible = visible;
30 }
31
32 void ProgressBar::init(ostream *out, scalar_t value_max) {
33   _value_max = value_max;
34   _last_step = -1;
35   time(&_initial_time);
36   refresh(out, 0);
37 }
38
39 void ProgressBar::refresh(ostream *out, scalar_t value) {
40   if(_visible && _value_max > 0) {
41     int step = int((value * 40) / _value_max);
42
43     if(1 || step > _last_step) {
44       char buffer[_width + 1], date_buffer[buffer_size];
45       int i, j;
46       j = sprintf(buffer, "Timer: ");
47
48       for(i = 0; i < step; i++) buffer[j + i] = 'X';
49       for(; i < 40; i++) buffer[j + i] = (i%4 == 0) ? '+' : '-';
50       j += i;
51
52       time_t current_time; time(&current_time);
53       int rt = int(((current_time - _initial_time)/scalar_t(value)) * scalar_t(_value_max - value));
54
55       if(rt > 0) {
56         if(rt > 3600 * 24) {
57           time_t current;
58           time(&current);
59           current += rt;
60           strftime(date_buffer, buffer_size, "%a %b %e %H:%M", localtime(&current));
61           j += snprintf(buffer + j, _width - j - 1, " (end ~ %s)", date_buffer);
62         } else {
63           int hours = rt/3600, min = (rt%3600)/60, sec = rt%60;
64           if(hours > 0)
65             j += snprintf(buffer + j, _width - j - 1, " (~%dh%dmin left)", hours, min);
66           else if(min > 0)
67             j += snprintf(buffer + j, _width - j - 1, " (~%dmin%ds left)", min, sec);
68           else
69             j += snprintf(buffer + j, _width - j - 1, " (~%ds left)", sec);
70         }
71       }
72
73       for(; j < _width; j++) buffer[j] = ' ';
74       buffer[j] = '\0';
75       (*out) << buffer << "\r";
76       out->flush();
77       _last_step = step;
78     }
79   }
80 }
81
82 void ProgressBar::finish(ostream *out) {
83   if(_visible) {
84     char buffer[_width + 1];
85     int j;
86     time_t current_time; time(&current_time);
87     int rt = int(current_time - _initial_time);
88     int min = rt/60, sec = rt%60;
89     j = sprintf(buffer, "Timer: Total %dmin%ds", min, sec);
90     for(; j < _width; j++) buffer[j] = ' ';
91     buffer[j] = '\0';
92     (*out) << buffer << endl;
93     out->flush();
94   }
95 }