Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Job handles, aka Here comes the future #754

Merged
merged 10 commits into from
May 13, 2024
2 changes: 2 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ IncludeCategories:
Priority: 12
- Regex: '<Quotient/.+\.h>|"\.\./[^/]+\.h"'
Priority: 16
- Regex: 'moc_.+\.cpp'
Priority: 20
- Regex: '<Qt.+(/.+)?'
Priority: 24
- Regex: '<(openssl|olm)/.+'
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ target_sources(${QUOTIENT_LIB_NAME} PUBLIC FILE_SET HEADERS BASE_DIRS .
Quotient/events/filesourceinfo.h
Quotient/jobs/requestdata.h
Quotient/jobs/basejob.h
Quotient/jobs/jobhandle.h
Quotient/jobs/syncjob.h
Quotient/jobs/mediathumbnailjob.h
Quotient/jobs/downloadfilejob.h
Expand Down
39 changes: 22 additions & 17 deletions Quotient/avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "jobs/mediathumbnailjob.h"

#include <QtCore/QDir>
#include <QtCore/QPointer>
#include <QtCore/QStandardPaths>
#include <QtCore/QStringBuilder>
#include <QtGui/QPainter>
Expand All @@ -21,17 +20,15 @@ class Q_DECL_HIDDEN Avatar::Private : public QObject {
explicit Private(QUrl url = {}) : _url(std::move(url)) {}
~Private() override
{
if (isJobPending(_thumbnailRequest))
_thumbnailRequest->abandon();
if (isJobPending(_uploadRequest))
_uploadRequest->abandon();
_thumbnailRequest.abandon();
_uploadRequest.abandon();
}
Q_DISABLE_COPY_MOVE(Private)

QImage get(Connection* connection, QSize size,
get_callback_t callback) const;
void thumbnailRequestFinished();
bool upload(UploadContentJob* job, upload_callback_t&& callback);
QFuture<QUrl> upload(JobHandle<UploadContentJob>&& job);

bool checkUrl(const QUrl& url) const;
QString localFile() const;
Expand All @@ -44,8 +41,8 @@ class Q_DECL_HIDDEN Avatar::Private : public QObject {
mutable QSize _largestRequestedSize{};
enum ImageSource : quint8 { Unknown, Cache, Network, Invalid };
mutable ImageSource _imageSource = Unknown;
mutable QPointer<MediaThumbnailJob> _thumbnailRequest = nullptr;
mutable QPointer<BaseJob> _uploadRequest = nullptr;
mutable JobHandle<MediaThumbnailJob> _thumbnailRequest = nullptr;
mutable JobHandle<UploadContentJob> _uploadRequest = nullptr;
mutable std::vector<get_callback_t> callbacks{};
};

Expand All @@ -70,15 +67,27 @@ bool Avatar::upload(Connection* connection, const QString& fileName,
{
if (isJobPending(d->_uploadRequest))
return false;
return d->upload(connection->uploadFile(fileName), std::move(callback));
upload(connection, fileName).then(std::move(callback));
return true;
}

bool Avatar::upload(Connection* connection, QIODevice* source,
upload_callback_t callback) const
{
if (isJobPending(d->_uploadRequest) || !source->isReadable())
return false;
return d->upload(connection->uploadContent(source), std::move(callback));
upload(connection, source).then(std::move(callback));
return true;
}

QFuture<QUrl> Avatar::upload(Connection* connection, const QString& fileName) const
{
return d->upload(connection->uploadFile(fileName));
}

QFuture<QUrl> Avatar::upload(Connection* connection, QIODevice* source) const
{
return d->upload(connection->uploadContent(source));
}

QString Avatar::mediaId() const { return d->_url.authority() + d->_url.path(); }
Expand Down Expand Up @@ -162,14 +171,10 @@ void Avatar::Private::thumbnailRequestFinished()
callbacks.clear();
}

bool Avatar::Private::upload(UploadContentJob* job, upload_callback_t &&callback)
QFuture<QUrl> Avatar::Private::upload(JobHandle<UploadContentJob>&& job)
{
_uploadRequest = job;
if (!isJobPending(_uploadRequest))
return false;
_uploadRequest->connect(_uploadRequest, &BaseJob::success, _uploadRequest,
[job, callback] { callback(job->contentUri()); });
return true;
_uploadRequest = std::move(job);
return _uploadRequest.then([](const auto* j) { return j->contentUri(); });
}

bool Avatar::Private::checkUrl(const QUrl& url) const
Expand Down
5 changes: 5 additions & 0 deletions Quotient/avatar.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "util.h"

#include <QtCore/QFuture>
#include <QtCore/QUrl>
#include <QtGui/QIcon>

Expand All @@ -27,10 +28,14 @@ class QUOTIENT_API Avatar {
QImage get(Connection* connection, int w, int h,
get_callback_t callback) const;

[[deprecated("Use the QFuture-returning overload instead")]]
bool upload(Connection* connection, const QString& fileName,
upload_callback_t callback) const;
[[deprecated("Use the QFuture-returning overload instead")]]
bool upload(Connection* connection, QIODevice* source,
upload_callback_t callback) const;
QFuture<QUrl> upload(Connection* connection, const QString& fileName) const;
QFuture<QUrl> upload(Connection* connection, QIODevice* source) const;

QString mediaId() const;
QUrl url() const;
Expand Down
Loading
Loading