gui: ipc: Support cancellation of preview generation

This commit is contained in:
Albert S. 2022-05-28 17:24:42 +02:00
parent 065dcf8906
commit 773325f2de
4 changed files with 37 additions and 19 deletions

View File

@ -3,29 +3,24 @@
#include "previewgeneratormapfunctor.h" #include "previewgeneratormapfunctor.h"
IPCPreviewWorker::IPCPreviewWorker() IPCPreviewWorker::IPCPreviewWorker()
{ {
this->connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::resultReadyAt, this,
[this](int index) { emit previewGenerated(previewWorkerWatcher.resultAt(index)); });
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::finished, this, [this] { emit finished(); });
} }
void IPCPreviewWorker::start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer) void IPCPreviewWorker::start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer)
{ {
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::resultReadyAt, this,
[peer, this](int index)
{
QDataStream stream{peer};
stream << previewWorkerWatcher.resultAt(index);
peer->flush();
});
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::finished, this,
[peer]
{
/* TODO /
/*peer->waitForBytesWritten();
peer->disconnectFromServer();
peer->deleteLater();*/
});
stop();
/* TODO: memleak */
auto mapFunctor = new PreviewGeneratorMapFunctor(); auto mapFunctor = new PreviewGeneratorMapFunctor();
mapFunctor->setRenderConfig(config); mapFunctor->setRenderConfig(config);
previewWorkerWatcher.setFuture(QtConcurrent::mapped(targets, *mapFunctor)); previewWorkerWatcher.setFuture(QtConcurrent::mapped(targets, *mapFunctor));
} }
void IPCPreviewWorker::stop()
{
previewWorkerWatcher.cancel();
previewWorkerWatcher.waitForFinished();
}

View File

@ -15,6 +15,10 @@ class IPCPreviewWorker : public QObject
public: public:
IPCPreviewWorker(); IPCPreviewWorker();
void start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer); void start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer);
void stop();
signals:
void previewGenerated(QByteArray);
void finished();
}; };
#endif // IPCPREVIEWWORKER_H #endif // IPCPREVIEWWORKER_H

View File

@ -15,7 +15,11 @@
IpcServer::IpcServer() IpcServer::IpcServer()
{ {
/* Only 1, we are doing work for the GUI, not a service for general availability */
this->spawningServer.setMaxPendingConnections(1);
connect(&this->spawningServer, &QLocalServer::newConnection, this, &IpcServer::spawnerNewConnection); connect(&this->spawningServer, &QLocalServer::newConnection, this, &IpcServer::spawnerNewConnection);
connect(&this->previewWorker, &IPCPreviewWorker::previewGenerated, this, &IpcServer::handlePreviewGenerated);
connect(&this->previewWorker, &IPCPreviewWorker::finished, this, [this] { this->currentSocket->flush(); });
} }
bool IpcServer::startSpawner(QString socketPath) bool IpcServer::startSpawner(QString socketPath)
@ -28,6 +32,7 @@ void IpcServer::spawnerNewConnection()
{ {
QLocalSocket *socket = this->spawningServer.nextPendingConnection(); QLocalSocket *socket = this->spawningServer.nextPendingConnection();
connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater); connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
this->currentSocket = socket;
if(socket != nullptr) if(socket != nullptr)
{ {
if(!socket->waitForReadyRead()) if(!socket->waitForReadyRead())
@ -39,10 +44,8 @@ void IpcServer::spawnerNewConnection()
stream >> command; stream >> command;
if(command == GeneratePreviews) if(command == GeneratePreviews)
{ {
IPCPreviewWorker *worker = new IPCPreviewWorker();
RenderConfig renderConfig; RenderConfig renderConfig;
QVector<RenderTarget> targets; QVector<RenderTarget> targets;
do do
{ {
/* TODO: this is not entirely robust */ /* TODO: this is not entirely robust */
@ -53,7 +56,18 @@ void IpcServer::spawnerNewConnection()
stream << targets.count(); stream << targets.count();
socket->flush(); socket->flush();
worker->start(renderConfig, targets, socket); previewWorker.start(renderConfig, targets, socket);
}
if(command == StopGeneratePreviews)
{
previewWorker.stop();
} }
} }
} }
void IpcServer::handlePreviewGenerated(QByteArray ba)
{
QDataStream stream{this->currentSocket};
stream << ba;
this->currentSocket->flush();
}

View File

@ -4,14 +4,19 @@
#include <QLocalServer> #include <QLocalServer>
#include "ipc.h" #include "ipc.h"
#include "filesaver.h" #include "filesaver.h"
#include "ipcpreviewworker.h"
class IpcServer : public QObject class IpcServer : public QObject
{ {
Q_OBJECT Q_OBJECT
private: private:
IPCPreviewWorker previewWorker;
QLocalServer spawningServer; QLocalServer spawningServer;
QLocalSocket *currentSocket = nullptr;
SaveFileResult addFile(QString file); SaveFileResult addFile(QString file);
private slots: private slots:
void spawnerNewConnection(); void spawnerNewConnection();
void handlePreviewGenerated(QByteArray ba);
public: public:
IpcServer(); IpcServer();