diff options
Diffstat (limited to 'logic/tasks')
-rw-r--r-- | logic/tasks/StandardTask.cpp | 120 | ||||
-rw-r--r-- | logic/tasks/StandardTask.h | 43 | ||||
-rw-r--r-- | logic/tasks/Task.cpp | 1 | ||||
-rw-r--r-- | logic/tasks/Task.h | 2 |
4 files changed, 166 insertions, 0 deletions
diff --git a/logic/tasks/StandardTask.cpp b/logic/tasks/StandardTask.cpp new file mode 100644 index 00000000..3201d674 --- /dev/null +++ b/logic/tasks/StandardTask.cpp @@ -0,0 +1,120 @@ +// Licensed under the Apache-2.0 license. See README.md for details. + +#include "StandardTask.h" + +#include <QEventLoop> +#include <QProcess> + +#include "net/CacheDownload.h" +#include "net/ByteArrayDownload.h" +#include "net/NetJob.h" +#include "FileSystem.h" +#include "Exception.h" +#include "Env.h" + +StandardTask::StandardTask(QObject *parent) + : Task(parent) +{ + m_loop = new QEventLoop(this); +} + +void StandardTask::runTask(QObjectPtr<Task> other) +{ + connect(other.get(), &Task::succeeded, m_loop, &QEventLoop::quit); + connect(other.get(), &Task::failed, m_loop, &QEventLoop::quit); + connect(other.get(), &Task::progress, this, [this](qint64 current, qint64 total){setProgress(current / total);}); + connect(other.get(), &Task::status, this, &StandardTask::setStatus); + if (!other->isRunning()) + { + other->start(); + } + if (other->isRunning()) + { + m_loop->exec(); + } + disconnect(other.get(), 0, m_loop, 0); + disconnect(other.get(), 0, this, 0); + other->deleteLater(); + if (!other->successful()) + { + throw Exception(other->failReason()); + } +} +void StandardTask::runTaskNonBlocking(QObjectPtr<Task> other) +{ + if (!other) + { + return; + } + m_pendingTasks.append(other.get()); + m_pendingTaskPtrs.append(other); + other->start(); +} +QByteArray StandardTask::networkGet(const QUrl &url) +{ + ByteArrayDownloadPtr task = ByteArrayDownload::make(url); + runTask(wrapDownload("", task)); + return task->m_data; +} +QByteArray StandardTask::networkGetCached(const QString &name, const QString &base, const QString &path, const QUrl &url, const bool alwaysRefetch, + INetworkValidator *validator) +{ + MetaEntryPtr entry = ENV.metacache()->resolveEntry(base, path); + if (!alwaysRefetch && !entry->stale) + { + if (validator) { delete validator; } + return FS::read(entry->getFullPath()); + } + else if (alwaysRefetch) + { + entry->stale = true; + } + CacheDownloadPtr task = CacheDownload::make(url, entry); + task->setValidator(validator); + runTask(wrapDownload(name, task)); + return FS::read(entry->getFullPath()); +} +QByteArray StandardTask::networkGetCached(const QString &name, const QString &base, const QString &path, const QUrl &url, const QMap<QString, QString> &headers, + INetworkValidator *validator) +{ + MetaEntryPtr entry = ENV.metacache()->resolveEntry(base, path); + if (!entry->stale) + { + if (validator) { delete validator; } + return FS::read(entry->getFullPath()); + } + CacheDownloadPtr task = CacheDownload::make(url, entry); + //task->setHeaders(headers); + task->setValidator(validator); + runTask(wrapDownload(name, task)); + return FS::read(entry->getFullPath()); +} +void StandardTask::networkGetCachedNonBlocking(const QString &name, const QString &base, const QString &path, const QUrl &url, const bool alwaysRefetch, + INetworkValidator *validator) +{ + MetaEntryPtr entry = ENV.metacache()->resolveEntry(base, path); + if (!alwaysRefetch && !entry->stale) + { + return; + } + CacheDownloadPtr dl = CacheDownload::make(url, entry); + dl->setValidator(validator); + runTaskNonBlocking(wrapDownload(name, dl)); +} +void StandardTask::waitOnPending() +{ + for (int i = 0; i < m_pendingTasks.size(); ++i) + { + if (m_pendingTasks.at(i) && m_pendingTasks.at(i)->isRunning()) + { + runTask(m_pendingTaskPtrs.at(i)); + } + } +} + +QObjectPtr<NetJob> StandardTask::wrapDownload(const QString &name, std::shared_ptr<NetAction> action) +{ + NetJobPtr task = NetJobPtr(new NetJob(name)); + task->addNetAction(action); + return task; +} diff --git a/logic/tasks/StandardTask.h b/logic/tasks/StandardTask.h new file mode 100644 index 00000000..6f283dcd --- /dev/null +++ b/logic/tasks/StandardTask.h @@ -0,0 +1,43 @@ +// Licensed under the Apache-2.0 license. See README.md for details. + +#pragma once + +#include "Task.h" + +#include <QPointer> +#include <memory> + +#include "QObjectPtr.h" + +class QEventLoop; +class QDir; +class NetAction; +class NetJob; +class INetworkValidator; + +class StandardTask : public Task +{ + Q_OBJECT +public: + explicit StandardTask(QObject *parent = nullptr); + +protected: + // TODO: switch to a future-based system + void runTask(QObjectPtr<Task> other); + void runTaskNonBlocking(QObjectPtr<Task> other); + QByteArray networkGet(const QUrl &url); + QByteArray networkGetCached(const QString &name, const QString &base, const QString &path, const QUrl &url, const bool alwaysRefetch = false, + INetworkValidator *validator = nullptr); + QByteArray networkGetCached(const QString &name, const QString &base, const QString &path, const QUrl &url, const QMap<QString, QString> &headers, + INetworkValidator *validator = nullptr); + void networkGetCachedNonBlocking(const QString &name, const QString &base, const QString &path, const QUrl &url, const bool alwaysRefetch = false, + INetworkValidator *validator = nullptr); + void waitOnPending(); + +private: + QEventLoop *m_loop; + QList<QPointer<Task>> m_pendingTasks; // only used to check if the object was deleted + QList<QObjectPtr<Task>> m_pendingTaskPtrs; + + QObjectPtr<NetJob> wrapDownload(const QString &name, std::shared_ptr<NetAction> action); +}; diff --git a/logic/tasks/Task.cpp b/logic/tasks/Task.cpp index 8fed810b..eaeff4c2 100644 --- a/logic/tasks/Task.cpp +++ b/logic/tasks/Task.cpp @@ -14,6 +14,7 @@ */ #include "Task.h" + #include <QDebug> Task::Task(QObject *parent) : QObject(parent) diff --git a/logic/tasks/Task.h b/logic/tasks/Task.h index 3ab85d7d..93ca620d 100644 --- a/logic/tasks/Task.h +++ b/logic/tasks/Task.h @@ -39,6 +39,8 @@ public: */ virtual QString failReason() const; + virtual bool canAbort() const { return false; } + signals: void started(); void progress(qint64 current, qint64 total); |