2017-05-29 22:42:10 +02:00
|
|
|
#include "worker.hpp"
|
|
|
|
#include <chrono>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
Worker *Worker::inst = 0;
|
|
|
|
QMutex Worker::workerLock;
|
2017-06-04 01:04:42 +02:00
|
|
|
QMutex Worker::lock;
|
2017-05-29 22:42:10 +02:00
|
|
|
|
2017-05-29 23:02:06 +02:00
|
|
|
// QPixmaps don't like existing on non GUI threads.
|
|
|
|
// Because of this we have to:
|
|
|
|
// 1. Convert to image on the GUI thread
|
|
|
|
// 2. Queue onto the worker, where:
|
|
|
|
// 1. Convert the image to the right format
|
|
|
|
// 2. Consume the image.
|
2017-05-29 22:42:10 +02:00
|
|
|
void Worker::queue(WorkerContext *context) {
|
2017-07-15 13:28:04 +02:00
|
|
|
init();
|
2017-05-29 22:42:10 +02:00
|
|
|
QMutexLocker ml(&lock);
|
2017-05-29 23:00:08 +02:00
|
|
|
_WorkerContext *c = new _WorkerContext;
|
2017-05-29 23:02:06 +02:00
|
|
|
c->image = context->pixmap.toImage();
|
2017-05-29 23:00:08 +02:00
|
|
|
c->consumer = context->consumer;
|
2017-05-30 13:22:20 +02:00
|
|
|
c->targetFormat = context->targetFormat;
|
2017-06-06 01:26:26 +02:00
|
|
|
c->underlyingThing = context;
|
2017-06-04 01:04:42 +02:00
|
|
|
inst->qqueue.enqueue(c);
|
2017-05-29 22:42:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Worker::init() {
|
|
|
|
QMutexLocker ml(&workerLock);
|
|
|
|
if (!inst) inst = new Worker;
|
|
|
|
}
|
|
|
|
|
|
|
|
Worker::Worker() : QObject() {
|
|
|
|
thr = new QThread;
|
|
|
|
moveToThread(thr);
|
|
|
|
connect(thr, &QThread::started, this, &Worker::process);
|
|
|
|
connect(thr, &QThread::finished, thr, &QThread::deleteLater);
|
|
|
|
connect(this, &Worker::finished, this, &Worker::deleteLater);
|
|
|
|
connect(thr, &QThread::finished, thr, &QThread::deleteLater);
|
|
|
|
thr->start();
|
|
|
|
}
|
|
|
|
|
|
|
|
Worker::~Worker() {
|
2017-05-30 15:51:25 +02:00
|
|
|
_end();
|
2017-05-29 22:42:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Worker::end() {
|
2017-05-30 15:51:25 +02:00
|
|
|
inst->_end();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Worker::_end() {
|
2017-05-29 22:42:10 +02:00
|
|
|
QMutexLocker ml(&endLock);
|
|
|
|
_ended = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Worker::ended() {
|
|
|
|
QMutexLocker ml(&endLock);
|
|
|
|
return _ended;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Worker::process() {
|
|
|
|
while (!ended()) {
|
2017-07-20 14:18:28 +02:00
|
|
|
lock.lock();
|
2017-05-29 22:42:10 +02:00
|
|
|
if (!qqueue.isEmpty()) {
|
2017-05-29 23:00:08 +02:00
|
|
|
_WorkerContext *c = qqueue.dequeue();
|
2017-07-20 14:18:28 +02:00
|
|
|
lock.unlock();
|
2017-05-30 13:22:20 +02:00
|
|
|
c->consumer(c->image.convertToFormat(c->targetFormat));
|
2017-06-06 01:26:26 +02:00
|
|
|
delete c->underlyingThing;
|
|
|
|
delete c;
|
2017-07-20 14:18:28 +02:00
|
|
|
} else
|
|
|
|
lock.unlock();
|
2017-05-30 15:51:25 +02:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // STL likes it's scopes
|
2017-05-29 22:42:10 +02:00
|
|
|
}
|
|
|
|
emit finished();
|
|
|
|
}
|