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