From 12ba6834ebff1271000f6232b1b6bce16665c10a Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Thu, 21 Jun 2012 13:22:52 +0100 Subject: [PATCH] Make status updates on tasks safe - add intermediate progress bar for TaskWindow --- src/tasks/Task.cpp | 41 ++++++++++++++++++++++++++-------------- src/tasks/Task.h | 3 +++ src/tasks/TaskWindow.cpp | 34 +++++++++++++++++++++++++++++---- src/tasks/TaskWindow.h | 5 ++++- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/tasks/Task.cpp b/src/tasks/Task.cpp index ec0ae9957..dfb8a2ba0 100644 --- a/src/tasks/Task.cpp +++ b/src/tasks/Task.cpp @@ -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); } diff --git a/src/tasks/Task.h b/src/tasks/Task.h index d5ccd4b92..10a8b905f 100644 --- a/src/tasks/Task.h +++ b/src/tasks/Task.h @@ -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); diff --git a/src/tasks/TaskWindow.cpp b/src/tasks/TaskWindow.cpp index e0e71bfe2..c705d36ec 100644 --- a/src/tasks/TaskWindow.cpp +++ b/src/tasks/TaskWindow.cpp @@ -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() { diff --git a/src/tasks/TaskWindow.h b/src/tasks/TaskWindow.h index d7edf8b64..09893bc9b 100644 --- a/src/tasks/TaskWindow.h +++ b/src/tasks/TaskWindow.h @@ -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(); };