Cycles: merge of changes from tomato branch.
[blender-staging.git] / intern / cycles / util / util_progress.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #ifndef __UTIL_PROGRESS_H__
20 #define __UTIL_PROGRESS_H__
21
22 /* Progress
23  *
24  * Simple class to communicate progress status messages, timing information,
25  * update notifications from a job running in another thread. All methods
26  * except for the constructor/destructor are thread safe. */
27
28 #include "util_function.h"
29 #include "util_string.h"
30 #include "util_time.h"
31 #include "util_thread.h"
32
33 CCL_NAMESPACE_BEGIN
34
35 class Progress {
36 public:
37         Progress()
38         {
39                 tile = 0;
40                 sample = 0;
41                 start_time = time_dt();
42                 total_time = 0.0f;
43                 tile_time = 0.0f;
44                 status = "Initializing";
45                 substatus = "";
46                 update_cb = NULL;
47                 cancel = false;
48                 cancel_message = "";
49                 cancel_cb = NULL;
50         }
51
52         Progress(Progress& progress)
53         {
54                 *this = progress;
55         }
56
57         Progress& operator=(Progress& progress)
58         {
59                 thread_scoped_lock lock(progress.progress_mutex);
60
61                 progress.get_status(status, substatus);
62                 progress.get_tile(tile, total_time, tile_time);
63
64                 sample = progress.get_sample();
65
66                 return *this;
67         }
68
69         /* cancel */
70         void set_cancel(const string& cancel_message_)
71         {
72                 thread_scoped_lock lock(progress_mutex);
73                 cancel_message = cancel_message_;
74                 cancel = true;
75         }
76
77         bool get_cancel()
78         {
79                 if(!cancel && cancel_cb)
80                         cancel_cb();
81
82                 return cancel;
83         }
84
85         string get_cancel_message()
86         {
87                 thread_scoped_lock lock(progress_mutex);
88                 return cancel_message;
89         }
90
91         void set_cancel_callback(boost::function<void(void)> function)
92         {
93                 cancel_cb = function;
94         }
95
96         /* tile and timing information */
97
98         void set_start_time(double start_time_)
99         {
100                 thread_scoped_lock lock(progress_mutex);
101
102                 start_time = start_time_;
103         }
104
105         void set_tile(int tile_, double tile_time_)
106         {
107                 thread_scoped_lock lock(progress_mutex);
108
109                 tile = tile_;
110                 total_time = time_dt() - start_time;
111                 tile_time = tile_time_;
112         }
113
114         void get_tile(int& tile_, double& total_time_, double& tile_time_)
115         {
116                 thread_scoped_lock lock(progress_mutex);
117
118                 tile_ = tile;
119                 total_time_ = (total_time > 0.0)? total_time: 0.0;
120                 tile_time_ = tile_time;
121         }
122
123         void reset_sample()
124         {
125                 thread_scoped_lock lock(progress_mutex);
126
127                 sample = 0;
128         }
129
130         void increment_sample()
131         {
132                 thread_scoped_lock lock(progress_mutex);
133
134                 sample++;
135         }
136
137         int get_sample()
138         {
139                 return sample;
140         }
141
142         /* status messages */
143
144         void set_status(const string& status_, const string& substatus_ = "")
145         {
146                 {
147                         thread_scoped_lock lock(progress_mutex);
148                         status = status_;
149                         substatus = substatus_;
150                         total_time = time_dt() - start_time;
151                 }
152
153                 set_update();
154         }
155
156         void set_substatus(const string& substatus_)
157         {
158                 {
159                         thread_scoped_lock lock(progress_mutex);
160                         substatus = substatus_;
161                         total_time = time_dt() - start_time;
162                 }
163
164                 set_update();
165         }
166
167         void get_status(string& status_, string& substatus_)
168         {
169                 thread_scoped_lock lock(progress_mutex);
170                 status_ = status;
171                 substatus_ = substatus;
172         }
173
174         /* callback */
175
176         void set_update()
177         {
178                 if(update_cb) {
179                         thread_scoped_lock lock(update_mutex);
180                         update_cb();
181                 }
182         }
183
184         void set_update_callback(boost::function<void(void)> function)
185         {
186                 update_cb = function;
187         }
188
189 protected:
190         thread_mutex progress_mutex;
191         thread_mutex update_mutex;
192         boost::function<void(void)> update_cb;
193         boost::function<void(void)> cancel_cb;
194
195         int tile;    /* counter for rendered tiles */
196         int sample;  /* counter of rendered samples, global for all tiles */
197
198         double start_time;
199         double total_time;
200         double tile_time;
201
202         string status;
203         string substatus;
204
205         volatile bool cancel;
206         string cancel_message;
207 };
208
209 CCL_NAMESPACE_END
210
211 #endif /* __UTIL_PROGRESS_H__ */
212