KShare/worker/worker.cpp

74 lines
1.8 KiB
C++
Raw Normal View History

#include "worker.hpp"
#include <chrono>
#include <thread>
Worker *Worker::inst = 0;
QMutex Worker::workerLock;
QMutex Worker::lock;
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.
void Worker::queue(WorkerContext *context) {
2017-07-15 13:28:04 +02:00
init();
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;
c->underlyingThing = context;
2017-07-28 18:39:34 +02:00
inst->qqueue.enqueue(std::move(c));
}
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();
}
void Worker::end() {
2017-05-30 15:51:25 +02:00
inst->_end();
}
void Worker::_end() {
QMutexLocker ml(&endLock);
_ended = true;
}
bool Worker::ended() {
QMutexLocker ml(&endLock);
return _ended;
}
void Worker::process() {
while (!ended()) {
lock.lock();
if (!qqueue.isEmpty()) {
2017-05-29 23:00:08 +02:00
_WorkerContext *c = qqueue.dequeue();
lock.unlock();
2017-05-30 13:22:20 +02:00
c->consumer(c->image.convertToFormat(c->targetFormat));
delete c->underlyingThing;
delete c;
} 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
}
emit finished();
}