c63aa841c5206567b118c37af050b696a9afcd30
[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                 sample = 0;
40                 start_time = time_dt();
41                 total_time = 0.0f;
42                 sample_time = 0.0f;
43                 status = "Initializing";
44                 substatus = "";
45                 update_cb = NULL;
46                 cancel = false;
47                 cancel_message = "";
48                 cancel_cb = NULL;
49         }
50
51         Progress(Progress& progress)
52         {
53                 *this = progress;
54         }
55
56         Progress& operator=(Progress& progress)
57         {
58                 thread_scoped_lock lock(progress.progress_mutex);
59
60                 progress.get_sample(sample, total_time, sample_time);
61                 progress.get_status(status, substatus);
62
63                 return *this;
64         }
65
66         /* cancel */
67         void set_cancel(const string& cancel_message_)
68         {
69                 thread_scoped_lock lock(progress_mutex);
70                 cancel_message = cancel_message_;
71                 cancel = true;
72         }
73
74         bool get_cancel()
75         {
76                 if(!cancel && cancel_cb)
77                         cancel_cb();
78
79                 return cancel;
80         }
81
82         string get_cancel_message()
83         {
84                 thread_scoped_lock lock(progress_mutex);
85                 return cancel_message;
86         }
87
88         void set_cancel_callback(boost::function<void(void)> function)
89         {
90                 cancel_cb = function;
91         }
92
93         /* sample and timing information */
94
95         void set_start_time(double start_time_)
96         {
97                 thread_scoped_lock lock(progress_mutex);
98
99                 start_time = start_time_;
100         }
101
102         void set_sample(int sample_, double sample_time_)
103         {
104                 thread_scoped_lock lock(progress_mutex);
105
106                 sample = sample_;
107                 total_time = time_dt() - start_time;
108                 sample_time = sample_time_;
109         }
110
111         void get_sample(int& sample_, double& total_time_, double& sample_time_)
112         {
113                 thread_scoped_lock lock(progress_mutex);
114
115                 sample_ = sample;
116                 total_time_ = (total_time > 0.0)? total_time: 0.0;
117                 sample_time_ = sample_time;
118         }
119
120         /* status messages */
121
122         void set_status(const string& status_, const string& substatus_ = "")
123         {
124                 {
125                         thread_scoped_lock lock(progress_mutex);
126                         status = status_;
127                         substatus = substatus_;
128                         total_time = time_dt() - start_time;
129                 }
130
131                 set_update();
132         }
133
134         void set_substatus(const string& substatus_)
135         {
136                 {
137                         thread_scoped_lock lock(progress_mutex);
138                         substatus = substatus_;
139                         total_time = time_dt() - start_time;
140                 }
141
142                 set_update();
143         }
144
145         void get_status(string& status_, string& substatus_)
146         {
147                 thread_scoped_lock lock(progress_mutex);
148                 status_ = status;
149                 substatus_ = substatus;
150         }
151
152         /* callback */
153
154         void set_update()
155         {
156                 if(update_cb) {
157                         thread_scoped_lock lock(update_mutex);
158                         update_cb();
159                 }
160         }
161
162         void set_update_callback(boost::function<void(void)> function)
163         {
164                 update_cb = function;
165         }
166
167 protected:
168         thread_mutex progress_mutex;
169         thread_mutex update_mutex;
170         boost::function<void(void)> update_cb;
171         boost::function<void(void)> cancel_cb;
172
173         int sample;
174
175         double start_time;
176         double total_time;
177         double sample_time;
178
179         string status;
180         string substatus;
181
182         volatile bool cancel;
183         string cancel_message;
184 };
185
186 CCL_NAMESPACE_END
187
188 #endif /* __UTIL_PROGRESS_H__ */
189