Blender V2.61 - r43446

util_progress.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #ifndef __UTIL_PROGRESS_H__
00020 #define __UTIL_PROGRESS_H__
00021 
00022 /* Progress
00023  *
00024  * Simple class to communicate progress status messages, timing information,
00025  * update notifications from a job running in another thread. All methods
00026  * except for the constructor/destructor are thread safe. */
00027 
00028 #include "util_function.h"
00029 #include "util_string.h"
00030 #include "util_time.h"
00031 #include "util_thread.h"
00032 
00033 CCL_NAMESPACE_BEGIN
00034 
00035 class Progress {
00036 public:
00037     Progress()
00038     {
00039         sample = 0;
00040         start_time = time_dt();
00041         total_time = 0.0f;
00042         sample_time = 0.0f;
00043         status = "Initializing";
00044         substatus = "";
00045         update_cb = NULL;
00046         cancel = false;
00047         cancel_message = "";
00048         cancel_cb = NULL;
00049     }
00050 
00051     Progress(Progress& progress)
00052     {
00053         *this = progress;
00054     }
00055 
00056     Progress& operator=(Progress& progress)
00057     {
00058         thread_scoped_lock lock(progress.progress_mutex);
00059 
00060         progress.get_sample(sample, total_time, sample_time);
00061         progress.get_status(status, substatus);
00062 
00063         return *this;
00064     }
00065 
00066     /* cancel */
00067     void set_cancel(const string& cancel_message_)
00068     {
00069         thread_scoped_lock lock(progress_mutex);
00070         cancel_message = cancel_message_;
00071         cancel = true;
00072     }
00073 
00074     bool get_cancel()
00075     {
00076         if(!cancel && cancel_cb)
00077             cancel_cb();
00078 
00079         return cancel;
00080     }
00081 
00082     string get_cancel_message()
00083     {
00084         thread_scoped_lock lock(progress_mutex);
00085         return cancel_message;
00086     }
00087 
00088     void set_cancel_callback(boost::function<void(void)> function)
00089     {
00090         cancel_cb = function;
00091     }
00092 
00093     /* sample and timing information */
00094 
00095     void set_start_time(double start_time_)
00096     {
00097         thread_scoped_lock lock(progress_mutex);
00098 
00099         start_time = start_time;
00100     }
00101 
00102     void set_sample(int sample_, double sample_time_)
00103     {
00104         thread_scoped_lock lock(progress_mutex);
00105 
00106         sample = sample_;
00107         total_time = time_dt() - start_time;
00108         sample_time = sample_time_;
00109     }
00110 
00111     void get_sample(int& sample_, double& total_time_, double& sample_time_)
00112     {
00113         thread_scoped_lock lock(progress_mutex);
00114 
00115         sample_ = sample;
00116         total_time_ = (total_time > 0.0)? total_time: 0.0;
00117         sample_time_ = sample_time;
00118     }
00119 
00120     /* status messages */
00121 
00122     void set_status(const string& status_, const string& substatus_ = "")
00123     {
00124         {
00125             thread_scoped_lock lock(progress_mutex);
00126             status = status_;
00127             substatus = substatus_;
00128             total_time = time_dt() - start_time;
00129         }
00130 
00131         set_update();
00132     }
00133 
00134     void set_substatus(const string& substatus_)
00135     {
00136         {
00137             thread_scoped_lock lock(progress_mutex);
00138             substatus = substatus_;
00139             total_time = time_dt() - start_time;
00140         }
00141 
00142         set_update();
00143     }
00144 
00145     void get_status(string& status_, string& substatus_)
00146     {
00147         thread_scoped_lock lock(progress_mutex);
00148         status_ = status;
00149         substatus_ = substatus;
00150     }
00151 
00152     /* callback */
00153 
00154     void set_update()
00155     {
00156         if(update_cb)
00157             update_cb();
00158     }
00159 
00160     void set_update_callback(boost::function<void(void)> function)
00161     {
00162         update_cb = function;
00163     }
00164 
00165 protected:
00166     thread_mutex progress_mutex;
00167     boost::function<void(void)> update_cb;
00168     boost::function<void(void)> cancel_cb;
00169 
00170     int sample;
00171 
00172     double start_time;
00173     double total_time;
00174     double sample_time;
00175 
00176     string status;
00177     string substatus;
00178 
00179     volatile bool cancel;
00180     string cancel_message;
00181 };
00182 
00183 CCL_NAMESPACE_END
00184 
00185 #endif /* __UTIL_PROGRESS_H__ */
00186