Make status updates on tasks safe - add intermediate progress bar for TaskWindow
This commit is contained in:
parent
09758b9152
commit
12ba6834eb
@ -17,8 +17,13 @@ void Task::SetTaskListener(TaskListener * listener)
|
||||
|
||||
void Task::Start()
|
||||
{
|
||||
thDone = false;
|
||||
done = false;
|
||||
progress = 0;
|
||||
status = "";
|
||||
taskMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
before();
|
||||
pthread_mutex_init (&taskMutex, NULL);
|
||||
pthread_cond_init(&taskCond, NULL);
|
||||
pthread_create(&doWorkThread, 0, &Task::doWork_helper, this);
|
||||
}
|
||||
|
||||
@ -40,13 +45,12 @@ bool Task::GetDone()
|
||||
void Task::Poll()
|
||||
{
|
||||
int newProgress;
|
||||
bool newDone;
|
||||
bool newDone = false;
|
||||
std::string newStatus;
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
newProgress = thProgress;
|
||||
newDone = thDone;
|
||||
newStatus = std::string(thStatus);
|
||||
pthread_cond_signal(&taskCond);
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
|
||||
if(newProgress!=progress) {
|
||||
@ -55,21 +59,23 @@ void Task::Poll()
|
||||
listener->NotifyProgress(this);
|
||||
}
|
||||
if(newStatus!=status) {
|
||||
status = newStatus;
|
||||
status = std::string(newStatus);
|
||||
if(listener)
|
||||
listener->NotifyStatus(this);
|
||||
}
|
||||
if(newDone!=done)
|
||||
{
|
||||
done = newDone;
|
||||
if(listener)
|
||||
listener->NotifyDone(this);
|
||||
}
|
||||
|
||||
if(done)
|
||||
{
|
||||
pthread_join(doWorkThread, NULL);
|
||||
pthread_mutex_destroy(&taskMutex);
|
||||
after();
|
||||
}
|
||||
|
||||
if(newDone!=done)
|
||||
{
|
||||
done = newDone;
|
||||
if(listener)
|
||||
listener->NotifyDone(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +84,11 @@ Task::~Task()
|
||||
|
||||
}
|
||||
|
||||
void Task::before()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Task::doWork()
|
||||
{
|
||||
notifyStatus("Fake progress");
|
||||
@ -88,6 +99,11 @@ void Task::doWork()
|
||||
}
|
||||
}
|
||||
|
||||
void Task::after()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void * Task::doWork_helper(void * ref)
|
||||
{
|
||||
((Task*)ref)->doWork();
|
||||
@ -98,7 +114,6 @@ void * Task::doWork_helper(void * ref)
|
||||
void Task::notifyProgress(int progress)
|
||||
{
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
pthread_cond_wait(&taskCond, &taskMutex);
|
||||
thProgress = progress;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
@ -106,15 +121,13 @@ void Task::notifyProgress(int progress)
|
||||
void Task::notifyStatus(std::string status)
|
||||
{
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
pthread_cond_wait(&taskCond, &taskMutex);
|
||||
thStatus = status;
|
||||
thStatus = std::string(status);
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
|
||||
void Task::notifyDone()
|
||||
{
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
pthread_cond_wait(&taskCond, &taskMutex);
|
||||
thDone = true;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
|
@ -37,6 +37,9 @@ protected:
|
||||
pthread_mutex_t taskMutex;
|
||||
pthread_cond_t taskCond;
|
||||
|
||||
|
||||
virtual void before();
|
||||
virtual void after();
|
||||
virtual void doWork();
|
||||
static void * doWork_helper(void * ref);
|
||||
|
||||
|
@ -9,12 +9,13 @@
|
||||
#include "TaskWindow.h"
|
||||
#include "Task.h"
|
||||
|
||||
TaskWindow::TaskWindow(std::string title_, Task * task_):
|
||||
TaskWindow::TaskWindow(std::string title_, Task * task_, bool closeOnDone):
|
||||
task(task_),
|
||||
title(title_),
|
||||
ui::Window(ui::Point(-1, -1), ui::Point(300, 200)),
|
||||
progress(0),
|
||||
done(false)
|
||||
done(false),
|
||||
closeOnDone(closeOnDone)
|
||||
{
|
||||
|
||||
ui::Label * tempLabel = new ui::Label(ui::Point(3, 3), ui::Point(Size.X-6, 16), title);
|
||||
@ -35,6 +36,12 @@ void TaskWindow::NotifyStatus(Task * task)
|
||||
}
|
||||
|
||||
void TaskWindow::NotifyDone(Task * task)
|
||||
{
|
||||
if(closeOnDone)
|
||||
Exit();
|
||||
}
|
||||
|
||||
void TaskWindow::Exit()
|
||||
{
|
||||
if(ui::Engine::Ref().GetWindow()==this)
|
||||
{
|
||||
@ -50,6 +57,9 @@ void TaskWindow::NotifyProgress(Task * task)
|
||||
|
||||
void TaskWindow::OnTick(float dt)
|
||||
{
|
||||
intermediatePos += 1.0f*dt;
|
||||
if(intermediatePos>100.0f)
|
||||
intermediatePos = 0.0f;
|
||||
task->Poll();
|
||||
}
|
||||
|
||||
@ -61,8 +71,24 @@ void TaskWindow::OnDraw()
|
||||
|
||||
g->drawrect(Position.X + 20, Position.Y + 36, Size.X-40, 24, 255, 255, 255, 255);
|
||||
|
||||
float size = float(Size.X-40)*(float(progress)/100.0f); // TIL...
|
||||
g->fillrect(Position.X + 20, Position.Y + 36, size, 24, 255, 255, 255, 255);
|
||||
if(progress!=-1)
|
||||
{
|
||||
float size = float(Size.X-40)*(float(progress)/100.0f); // TIL...
|
||||
g->fillrect(Position.X + 20, Position.Y + 36, size, 24, 255, 255, 255, 255);
|
||||
} else {
|
||||
int size = 40, rsize = 0;
|
||||
float position = float(Size.X-40)*(intermediatePos/100.0f);
|
||||
if(position + size > Size.X-40)
|
||||
{
|
||||
size = (Size.X-40)-position;
|
||||
rsize = 40-size;
|
||||
}
|
||||
g->fillrect(Position.X + 20 + position, Position.Y + 36, size, 24, 255, 255, 255, 255);
|
||||
if(rsize)
|
||||
{
|
||||
g->fillrect(Position.X + 20, Position.Y + 36, rsize, 24, 255, 255, 255, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TaskWindow::~TaskWindow() {
|
||||
|
@ -18,15 +18,18 @@ class TaskWindow: public ui::Window, public TaskListener {
|
||||
Task * task;
|
||||
std::string title;
|
||||
int progress;
|
||||
float intermediatePos;
|
||||
bool done;
|
||||
bool closeOnDone;
|
||||
ui::Label * statusLabel;
|
||||
public:
|
||||
TaskWindow(std::string title_, Task * task_);
|
||||
TaskWindow(std::string title_, Task * task_, bool closeOnDone = true);
|
||||
virtual void NotifyStatus(Task * task);
|
||||
virtual void NotifyDone(Task * task);
|
||||
virtual void NotifyProgress(Task * task);
|
||||
virtual void OnTick(float dt);
|
||||
virtual void OnDraw();
|
||||
virtual void Exit();
|
||||
virtual ~TaskWindow();
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user