1 /*!	\file tool/renderprogress.cpp
2 **	\brief Implementation of the functions from the render progress class
3 **
4 **	$Id$
5 **
6 **	\legal
7 **	Copyright (c) 2014, 2015 Diego Barrios Romero
8 **
9 **	This package is free software; you can redistribute it and/or
10 **	modify it under the terms of the GNU General Public License as
11 **	published by the Free Software Foundation; either version 2 of
12 **	the License, or (at your option) any later version.
13 **
14 **	This package is distributed in the hope that it will be useful,
15 **	but WITHOUT ANY WARRANTY; without even the implied warranty of
16 **	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 **	General Public License for more details.
18 **	\endlegal
19 */
20 
21 #include <cmath>
22 #include <iostream>
23 #include "renderprogress.h"
24 #include <boost/format.hpp>
25 
RenderProgress()26 RenderProgress::RenderProgress()
27     : last_frame_(0), last_printed_line_length_(0),
28       start_timepoint_(Clock::now()), last_timepoint_(Clock::now())
29 { }
30 
task(const std::string & taskname)31 bool RenderProgress::task(const std::string& taskname)
32 {
33     taskname_ = taskname;
34     return true;
35 }
36 
error(const std::string & task)37 bool RenderProgress::error(const std::string& task)
38 {
39     std::cout << _("error") << ": " << task << std::endl;
40     return true;
41 }
42 
warning(const std::string & task)43 bool RenderProgress::warning(const std::string& task)
44 {
45     std::cout << _("warning") << ": " << task << std::endl;
46     return true;
47 }
48 
amount_complete(int current_frame,int frames_count)49 bool RenderProgress::amount_complete(int current_frame, int frames_count)
50 {
51     if(SynfigToolGeneralOptions::instance()->should_be_quiet())
52     {
53         return true;
54     }
55 
56     std::ostringstream outputStream;
57 
58     const bool isFinished = (current_frame == frames_count);
59     if (!isFinished)
60     {
61         // avoid reporting the progress too often
62         Duration time_since_last_call(Clock::now() - last_timepoint_);
63         if (time_since_last_call.count() < 0.2)
64         {
65             return true;
66         }
67         last_timepoint_ = Clock::now();
68 
69         int percentage_completed = 100;
70         if (frames_count > 0)
71         {
72             percentage_completed = 100 * current_frame / frames_count;
73         }
74 
75         outputStream << "\r"
76                      << boost::format(_("%1%: Frame %2% of %3% (%4%%%). Remaining time: "))
77                         % taskname_ % current_frame % frames_count % percentage_completed;
78 
79         if (current_frame != last_frame_)
80         {
81             remaining_rendered_proportion_ =
82                 double(frames_count-current_frame)/(current_frame-last_frame_);
83         }
84         Duration time_since_start(Clock::now() - start_timepoint_);
85         double remaining_seconds =
86             time_since_start.count() * remaining_rendered_proportion_;
87 
88         printRemainingTime(outputStream, remaining_seconds);
89     }
90     else
91     {
92         outputStream << "\r" << taskname_ << ": " << _("DONE");
93     }
94 
95     const std::string line = outputStream.str();
96     const std::string extendedLine =
97         extendLineToClearRest(line, last_printed_line_length_);
98     last_printed_line_length_ = line.size();
99 
100     std::cerr << extendedLine;
101     if (isFinished)
102     {
103         std::cerr << std::endl;
104     }
105 
106     return true;
107 }
108 
printRemainingTime(std::ostream & os,double remaining_seconds) const109 void RenderProgress::printRemainingTime(std::ostream& os,
110                                         double remaining_seconds) const
111 {
112     int weeks, days, hours, minutes, seconds;
113 
114     seconds = remaining_seconds;
115 
116     minutes = floor(seconds/60);
117     seconds %= 60;
118 
119     hours = floor(minutes/60);
120     minutes %= 60;
121 
122     days = floor(hours/24);
123     hours %= 24;
124 
125     weeks = floor(days/7);
126     days %= 7;
127 
128     printRemainingTime(os, seconds, minutes, hours, days, weeks);
129 }
130 
printRemainingTime(std::ostream & os,const int seconds,const int minutes,const int hours,const int days,const int weeks) const131 void RenderProgress::printRemainingTime(std::ostream& os,
132                                         const int seconds, const int minutes,
133                                         const int hours, const int days,
134                                         const int weeks) const
135 {
136     if(weeks != 0)
137     {
138         /// TRANSLATORS This "w" stands for weeks
139         os << weeks << _("w ");
140     }
141     if(days != 0)
142     {
143         /// TRANSLATORS This "d" stands for days
144         os << days << _("d ");
145     }
146     if(hours != 0)
147     {
148         /// TRANSLATORS This "h" stands for hours
149         os << hours << _("h ");
150     }
151     if(minutes != 0)
152     {
153         /// TRANSLATORS This "m" stands for minutes
154         os << minutes << _("m ");
155     }
156     /// TRANSLATORS This "s" stands for seconds
157     os << seconds << _("s ");
158 }
159 
extendLineToClearRest(std::string line,size_t last_line_length) const160 std::string RenderProgress::extendLineToClearRest(std::string line,
161                                                   size_t last_line_length) const
162 {
163     if (line.size() < last_line_length)
164     {
165         line.append(last_line_length - line.size(), ' ');
166     }
167 
168     return line;
169 }
170