2011-04-27 11:58:34 +00:00
|
|
|
/*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Copyright 2011-2013 Blender Foundation
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License
|
2011-04-27 11:58:34 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __UTIL_PROGRESS_H__
|
|
|
|
#define __UTIL_PROGRESS_H__
|
|
|
|
|
|
|
|
/* Progress
|
|
|
|
*
|
|
|
|
* Simple class to communicate progress status messages, timing information,
|
|
|
|
* update notifications from a job running in another thread. All methods
|
|
|
|
* except for the constructor/destructor are thread safe. */
|
|
|
|
|
2011-06-17 11:33:57 +00:00
|
|
|
#include "util_function.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
#include "util_string.h"
|
2012-01-09 16:57:46 +00:00
|
|
|
#include "util_time.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
#include "util_thread.h"
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
class Progress {
|
|
|
|
public:
|
|
|
|
Progress()
|
|
|
|
{
|
2012-09-04 13:29:07 +00:00
|
|
|
tile = 0;
|
2011-09-16 13:14:02 +00:00
|
|
|
sample = 0;
|
2012-01-09 16:57:46 +00:00
|
|
|
start_time = time_dt();
|
2011-04-27 11:58:34 +00:00
|
|
|
total_time = 0.0f;
|
2012-09-04 13:29:07 +00:00
|
|
|
tile_time = 0.0f;
|
2011-04-27 11:58:34 +00:00
|
|
|
status = "Initializing";
|
|
|
|
substatus = "";
|
2012-09-28 12:37:20 +00:00
|
|
|
sync_status = "";
|
|
|
|
sync_substatus = "";
|
2011-04-27 11:58:34 +00:00
|
|
|
update_cb = NULL;
|
|
|
|
cancel = false;
|
|
|
|
cancel_message = "";
|
2014-12-05 16:17:48 +00:00
|
|
|
error = false;
|
|
|
|
error_message = "";
|
2011-04-27 11:58:34 +00:00
|
|
|
cancel_cb = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Progress(Progress& progress)
|
|
|
|
{
|
|
|
|
*this = progress;
|
|
|
|
}
|
|
|
|
|
|
|
|
Progress& operator=(Progress& progress)
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress.progress_mutex);
|
|
|
|
|
|
|
|
progress.get_status(status, substatus);
|
2012-09-04 13:29:07 +00:00
|
|
|
progress.get_tile(tile, total_time, tile_time);
|
|
|
|
|
|
|
|
sample = progress.get_sample();
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-11-09 08:46:53 +00:00
|
|
|
void reset()
|
|
|
|
{
|
|
|
|
tile = 0;
|
|
|
|
sample = 0;
|
|
|
|
start_time = time_dt();
|
|
|
|
total_time = 0.0f;
|
|
|
|
tile_time = 0.0f;
|
|
|
|
status = "Initializing";
|
|
|
|
substatus = "";
|
|
|
|
sync_status = "";
|
|
|
|
sync_substatus = "";
|
|
|
|
cancel = false;
|
|
|
|
cancel_message = "";
|
2014-12-05 16:17:48 +00:00
|
|
|
error = false;
|
|
|
|
error_message = "";
|
2012-11-09 08:46:53 +00:00
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* cancel */
|
|
|
|
void set_cancel(const string& cancel_message_)
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
cancel_message = cancel_message_;
|
|
|
|
cancel = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool get_cancel()
|
|
|
|
{
|
|
|
|
if(!cancel && cancel_cb)
|
|
|
|
cancel_cb();
|
|
|
|
|
|
|
|
return cancel;
|
|
|
|
}
|
|
|
|
|
|
|
|
string get_cancel_message()
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
return cancel_message;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_cancel_callback(boost::function<void(void)> function)
|
|
|
|
{
|
|
|
|
cancel_cb = function;
|
|
|
|
}
|
|
|
|
|
2014-12-05 16:17:48 +00:00
|
|
|
/* error */
|
|
|
|
void set_error(const string& error_message_)
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
error_message = error_message_;
|
|
|
|
error = true;
|
|
|
|
/* If error happens we also stop rendering. */
|
|
|
|
cancel_message = error_message_;
|
|
|
|
cancel = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool get_error()
|
|
|
|
{
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
string get_error_message()
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
return error_message;
|
|
|
|
}
|
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
/* tile and timing information */
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2012-01-09 16:57:46 +00:00
|
|
|
void set_start_time(double start_time_)
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
|
2012-01-26 14:55:39 +00:00
|
|
|
start_time = start_time_;
|
2012-01-09 16:57:46 +00:00
|
|
|
}
|
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
void set_tile(int tile_, double tile_time_)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
tile = tile_;
|
2012-01-09 16:57:46 +00:00
|
|
|
total_time = time_dt() - start_time;
|
2012-09-04 13:29:07 +00:00
|
|
|
tile_time = tile_time_;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
void get_tile(int& tile_, double& total_time_, double& tile_time_)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
tile_ = tile;
|
2012-01-09 16:57:46 +00:00
|
|
|
total_time_ = (total_time > 0.0)? total_time: 0.0;
|
2012-09-04 13:29:07 +00:00
|
|
|
tile_time_ = tile_time;
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset_sample()
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
|
|
|
|
sample = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void increment_sample()
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
|
|
|
|
sample++;
|
|
|
|
}
|
|
|
|
|
2014-07-22 21:41:01 +00:00
|
|
|
void increment_sample_update()
|
|
|
|
{
|
|
|
|
increment_sample();
|
|
|
|
set_update();
|
|
|
|
}
|
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
int get_sample()
|
|
|
|
{
|
|
|
|
return sample;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* status messages */
|
|
|
|
|
|
|
|
void set_status(const string& status_, const string& substatus_ = "")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
status = status_;
|
|
|
|
substatus = substatus_;
|
2012-01-09 16:57:46 +00:00
|
|
|
total_time = time_dt() - start_time;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
set_update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_substatus(const string& substatus_)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
substatus = substatus_;
|
2012-01-09 16:57:46 +00:00
|
|
|
total_time = time_dt() - start_time;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
set_update();
|
|
|
|
}
|
|
|
|
|
2012-09-28 12:37:20 +00:00
|
|
|
void set_sync_status(const string& status_, const string& substatus_ = "")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
sync_status = status_;
|
|
|
|
sync_substatus = substatus_;
|
|
|
|
total_time = time_dt() - start_time;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_update();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_sync_substatus(const string& substatus_)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
|
|
|
sync_substatus = substatus_;
|
|
|
|
total_time = time_dt() - start_time;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_update();
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
void get_status(string& status_, string& substatus_)
|
|
|
|
{
|
|
|
|
thread_scoped_lock lock(progress_mutex);
|
2012-09-28 12:37:20 +00:00
|
|
|
|
|
|
|
if(sync_status != "") {
|
|
|
|
status_ = sync_status;
|
|
|
|
substatus_ = sync_substatus;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
status_ = status;
|
|
|
|
substatus_ = substatus;
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* callback */
|
|
|
|
|
|
|
|
void set_update()
|
|
|
|
{
|
2012-05-08 19:57:56 +00:00
|
|
|
if(update_cb) {
|
|
|
|
thread_scoped_lock lock(update_mutex);
|
2011-04-27 11:58:34 +00:00
|
|
|
update_cb();
|
2012-05-08 19:57:56 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void set_update_callback(boost::function<void(void)> function)
|
|
|
|
{
|
|
|
|
update_cb = function;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
thread_mutex progress_mutex;
|
2012-05-08 19:57:56 +00:00
|
|
|
thread_mutex update_mutex;
|
2011-04-27 11:58:34 +00:00
|
|
|
boost::function<void(void)> update_cb;
|
|
|
|
boost::function<void(void)> cancel_cb;
|
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
int tile; /* counter for rendered tiles */
|
|
|
|
int sample; /* counter of rendered samples, global for all tiles */
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2012-01-09 16:57:46 +00:00
|
|
|
double start_time;
|
2011-04-27 11:58:34 +00:00
|
|
|
double total_time;
|
2012-09-04 13:29:07 +00:00
|
|
|
double tile_time;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
string status;
|
|
|
|
string substatus;
|
|
|
|
|
2012-09-28 12:37:20 +00:00
|
|
|
string sync_status;
|
|
|
|
string sync_substatus;
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
volatile bool cancel;
|
|
|
|
string cancel_message;
|
2014-12-05 16:17:48 +00:00
|
|
|
|
|
|
|
volatile bool error;
|
|
|
|
string error_message;
|
2011-04-27 11:58:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
CCL_NAMESPACE_END
|
|
|
|
|
|
|
|
#endif /* __UTIL_PROGRESS_H__ */
|
|
|
|
|