From 399370816468f9f8d5a0418c00c3938337c90e07 Mon Sep 17 00:00:00 2001 From: fourtf Date: Fri, 6 Jul 2018 17:56:11 +0200 Subject: [PATCH] Refactored NetworkRequest and misc --- src/common/Channel.cpp | 6 +- src/common/CompletionModel.cpp | 2 +- src/common/Emotemap.hpp | 6 +- src/common/LockedObject.hpp | 12 +- src/common/MutexValue.hpp | 17 +-- src/common/NetworkManager.hpp | 16 --- src/common/NetworkRequest.cpp | 208 +++++++++++++++++++++++++++++++ src/common/NetworkRequest.hpp | 220 +++------------------------------ 8 files changed, 244 insertions(+), 243 deletions(-) diff --git a/src/common/Channel.cpp b/src/common/Channel.cpp index 2a86d38fa..04e7cc7de 100644 --- a/src/common/Channel.cpp +++ b/src/common/Channel.cpp @@ -22,10 +22,10 @@ Channel::Channel(const QString &_name, Type _type) , completionModel(this->name) , type_(_type) { - QObject::connect(&this->clearCompletionModelTimer, &QTimer::timeout, [this]() { - this->completionModel.ClearExpiredStrings(); // + QObject::connect(&this->clearCompletionModelTimer_, &QTimer::timeout, [this]() { + this->completionModel.clearExpiredStrings(); // }); - this->clearCompletionModelTimer.start(60 * 1000); + this->clearCompletionModelTimer_.start(60 * 1000); } Channel::~Channel() diff --git a/src/common/CompletionModel.cpp b/src/common/CompletionModel.cpp index 8b326af0b..9df3dfd2e 100644 --- a/src/common/CompletionModel.cpp +++ b/src/common/CompletionModel.cpp @@ -213,7 +213,7 @@ void CompletionModel::clearExpiredStrings() for (auto it = this->emotes_.begin(); it != this->emotes_.end();) { const auto &taggedString = *it; - if (taggedString.HasExpired(now)) { + if (taggedString.isExpired(now)) { // Log("String {} expired", taggedString.str); it = this->emotes_.erase(it); } else { diff --git a/src/common/Emotemap.hpp b/src/common/Emotemap.hpp index d5862a9f2..3c8b86a08 100644 --- a/src/common/Emotemap.hpp +++ b/src/common/Emotemap.hpp @@ -14,12 +14,12 @@ struct EmoteData { bool isValid() const; Image *getImage(float scale) const; + // Link to the emote page i.e. https://www.frankerfacez.com/emoticon/144722-pajaCringe + QString pageLink; + Image *image1x = nullptr; Image *image2x = nullptr; Image *image3x = nullptr; - - // Link to the emote page i.e. https://www.frankerfacez.com/emoticon/144722-pajaCringe - QString pageLink; }; using EmoteMap = ConcurrentMap; diff --git a/src/common/LockedObject.hpp b/src/common/LockedObject.hpp index edf57b404..01ffe3b66 100644 --- a/src/common/LockedObject.hpp +++ b/src/common/LockedObject.hpp @@ -10,29 +10,29 @@ class LockedObject public: LockedObject &operator=(const LockedObject &other) { - this->mutex.lock(); + this->mutex_.lock(); this->data = other.getValue(); - this->mutex.unlock(); + this->mutex_.unlock(); return *this; } LockedObject &operator=(const Type &other) { - this->mutex.lock(); + this->mutex_.lock(); this->data = other; - this->mutex.unlock(); + this->mutex_.unlock(); return *this; } private: - Type value; - std::mutex mutex; + Type value_; + std::mutex mutex_; }; } // namespace chatterino diff --git a/src/common/MutexValue.hpp b/src/common/MutexValue.hpp index 05d390817..112257370 100644 --- a/src/common/MutexValue.hpp +++ b/src/common/MutexValue.hpp @@ -8,32 +8,33 @@ namespace chatterino { template class MutexValue : boost::noncopyable { - mutable std::mutex mutex; - T value; - public: MutexValue() { } MutexValue(T &&val) - : value(val) + : value_(val) { } T get() const { - std::lock_guard guard(this->mutex); + std::lock_guard guard(this->mutex_); - return this->value; + return this->value_; } void set(const T &val) { - std::lock_guard guard(this->mutex); + std::lock_guard guard(this->mutex_); - this->value = val; + this->value_ = val; } + +private: + mutable std::mutex mutex_; + T value_; }; } // namespace chatterino diff --git a/src/common/NetworkManager.hpp b/src/common/NetworkManager.hpp index f9971427f..7e02caf4d 100644 --- a/src/common/NetworkManager.hpp +++ b/src/common/NetworkManager.hpp @@ -14,22 +14,6 @@ namespace chatterino { -static QJsonObject parseJSONFromReplyxD(QNetworkReply *reply) -{ - if (reply->error() != QNetworkReply::NetworkError::NoError) { - return QJsonObject(); - } - - QByteArray data = reply->readAll(); - QJsonDocument jsonDoc(QJsonDocument::fromJson(data)); - - if (jsonDoc.isNull()) { - return QJsonObject(); - } - - return jsonDoc.object(); -} - class NetworkManager : public QObject { Q_OBJECT diff --git a/src/common/NetworkRequest.cpp b/src/common/NetworkRequest.cpp index 3c5b4f977..74698a986 100644 --- a/src/common/NetworkRequest.cpp +++ b/src/common/NetworkRequest.cpp @@ -19,6 +19,48 @@ NetworkRequest::NetworkRequest(const QString &url) this->data.request.setUrl(QUrl(url)); } +void NetworkRequest::setRequestType(RequestType newRequestType) +{ + this->data.requestType = newRequestType; +} + +void NetworkRequest::setCaller(const QObject *_caller) +{ + this->data.caller = _caller; +} + +void NetworkRequest::setOnReplyCreated(std::function f) +{ + this->data.onReplyCreated = f; +} + +void NetworkRequest::setRawHeader(const char *headerName, const char *value) +{ + this->data.request.setRawHeader(headerName, value); +} + +void NetworkRequest::setRawHeader(const char *headerName, const QByteArray &value) +{ + this->data.request.setRawHeader(headerName, value); +} + +void NetworkRequest::setRawHeader(const char *headerName, const QString &value) +{ + this->data.request.setRawHeader(headerName, value.toUtf8()); +} + +void NetworkRequest::setTimeout(int ms) +{ + this->data.timeoutMS = ms; +} + +void NetworkRequest::makeAuthorizedV5(const QString &clientID, const QString &oauthToken) +{ + this->setRawHeader("Client-ID", clientID); + this->setRawHeader("Accept", "application/vnd.twitchtv.v5+json"); + this->setRawHeader("Authorization", "OAuth " + oauthToken); +} + void NetworkRequest::setUseQuickLoadCache(bool value) { this->data.useQuickLoadCache = value; @@ -39,4 +81,170 @@ void NetworkRequest::Data::writeToCache(const QByteArray &bytes) } } +void NetworkRequest::execute() +{ + switch (this->data.requestType) { + case GetRequest: { + this->executeGet(); + } break; + + case PutRequest: { + this->executePut(); + } break; + + case DeleteRequest: { + this->executeDelete(); + } break; + + default: { + Log("[Execute] Unhandled request type {}", (int)this->data.requestType); + } break; + } +} + +void NetworkRequest::useCache() +{ + if (this->data.useQuickLoadCache) { + auto app = getApp(); + + QFile cachedFile(app->paths->cacheDirectory + "/" + this->data.getHash()); + + if (cachedFile.exists()) { + if (cachedFile.open(QIODevice::ReadOnly)) { + QByteArray bytes = cachedFile.readAll(); + + // qDebug() << "Loaded cached resource" << this->data.request.url(); + + auto document = parseJSONFromData2(bytes); + + bool success = false; + + if (!document.IsNull()) { + success = this->data.onSuccess(document); + } + + cachedFile.close(); + + if (!success) { + // The images were not successfully loaded from the file + // XXX: Invalidate the cache file so we don't attempt to load it again next + // time + } + } + } + } +} + +void NetworkRequest::doRequest() +{ + QTimer *timer = nullptr; + if (this->data.timeoutMS > 0) { + timer = new QTimer; + } + + NetworkRequester requester; + NetworkWorker *worker = new NetworkWorker; + + worker->moveToThread(&NetworkManager::workerThread); + + if (this->data.caller != nullptr) { + QObject::connect(worker, &NetworkWorker::doneUrl, + this->data.caller, [data = this->data](auto reply) mutable { + if (reply->error() != QNetworkReply::NetworkError::NoError) { + if (data.onError) { + data.onError(reply->error()); + } + return; + } + + QByteArray readBytes = reply->readAll(); + QByteArray bytes; + bytes.setRawData(readBytes.data(), readBytes.size()); + data.writeToCache(bytes); + data.onSuccess(parseJSONFromData2(bytes)); + + reply->deleteLater(); + }); + } + + if (timer != nullptr) { + timer->start(this->data.timeoutMS); + } + + QObject::connect(&requester, &NetworkRequester::requestUrl, worker, + [ timer, data = std::move(this->data), worker ]() { + QNetworkReply *reply = nullptr; + switch (data.requestType) { + case GetRequest: { + reply = NetworkManager::NaM.get(data.request); + } break; + + case PutRequest: { + reply = NetworkManager::NaM.put(data.request, data.payload); + } break; + + case DeleteRequest: { + reply = NetworkManager::NaM.deleteResource(data.request); + } break; + } + + if (reply == nullptr) { + Log("Unhandled request type {}", (int)data.requestType); + return; + } + + if (timer != nullptr) { + QObject::connect(timer, &QTimer::timeout, worker, + [reply, timer, data]() { + Log("Aborted!"); + reply->abort(); + timer->deleteLater(); + data.onError(-2); + }); + } + + if (data.onReplyCreated) { + data.onReplyCreated(reply); + } + + QObject::connect(reply, &QNetworkReply::finished, worker, + [ data = std::move(data), worker, reply ]() mutable { + if (data.caller == nullptr) { + QByteArray bytes = reply->readAll(); + data.writeToCache(bytes); + + if (data.onSuccess) { + data.onSuccess(parseJSONFromData2(bytes)); + } else { + qWarning() << "data.onSuccess not found"; + } + + reply->deleteLater(); + } else { + emit worker->doneUrl(reply); + } + + delete worker; + }); + }); + + emit requester.requestUrl(); +} + +void NetworkRequest::executeGet() +{ + this->useCache(); + + this->doRequest(); +} + +void NetworkRequest::executePut() +{ + this->doRequest(); +} + +void NetworkRequest::executeDelete() +{ + this->doRequest(); +} } // namespace chatterino diff --git a/src/common/NetworkRequest.hpp b/src/common/NetworkRequest.hpp index a65358171..6fcc069a6 100644 --- a/src/common/NetworkRequest.hpp +++ b/src/common/NetworkRequest.hpp @@ -115,10 +115,7 @@ public: explicit NetworkRequest(const std::string &url); explicit NetworkRequest(const QString &url); - void setRequestType(RequestType newRequestType) - { - this->data.requestType = newRequestType; - } + void setRequestType(RequestType newRequestType); template void onError(Func cb) @@ -138,43 +135,13 @@ public: } void setUseQuickLoadCache(bool value); - - void setCaller(const QObject *_caller) - { - this->data.caller = _caller; - } - - void setOnReplyCreated(std::function f) - { - this->data.onReplyCreated = f; - } - - void setRawHeader(const char *headerName, const char *value) - { - this->data.request.setRawHeader(headerName, value); - } - - void setRawHeader(const char *headerName, const QByteArray &value) - { - this->data.request.setRawHeader(headerName, value); - } - - void setRawHeader(const char *headerName, const QString &value) - { - this->data.request.setRawHeader(headerName, value.toUtf8()); - } - - void setTimeout(int ms) - { - this->data.timeoutMS = ms; - } - - void makeAuthorizedV5(const QString &clientID, const QString &oauthToken) - { - this->setRawHeader("Client-ID", clientID); - this->setRawHeader("Accept", "application/vnd.twitchtv.v5+json"); - this->setRawHeader("Authorization", "OAuth " + oauthToken); - } + void setCaller(const QObject *_caller); + void setOnReplyCreated(std::function f); + void setRawHeader(const char *headerName, const char *value); + void setRawHeader(const char *headerName, const QByteArray &value); + void setRawHeader(const char *headerName, const QString &value); + void setTimeout(int ms); + void makeAuthorizedV5(const QString &clientID, const QString &oauthToken); template void get(FinishedCallback onFinished) @@ -300,173 +267,14 @@ public: }); } - void execute() - { - switch (this->data.requestType) { - case GetRequest: { - this->executeGet(); - } break; - - case PutRequest: { - this->executePut(); - } break; - - case DeleteRequest: { - this->executeDelete(); - } break; - - default: { - Log("[Execute] Unhandled request type {}", (int)this->data.requestType); - } break; - } - } + void execute(); private: - void useCache() - { - if (this->data.useQuickLoadCache) { - auto app = getApp(); - - QFile cachedFile(app->paths->cacheDirectory + "/" + this->data.getHash()); - - if (cachedFile.exists()) { - if (cachedFile.open(QIODevice::ReadOnly)) { - QByteArray bytes = cachedFile.readAll(); - - // qDebug() << "Loaded cached resource" << this->data.request.url(); - - auto document = parseJSONFromData2(bytes); - - bool success = false; - - if (!document.IsNull()) { - success = this->data.onSuccess(document); - } - - cachedFile.close(); - - if (!success) { - // The images were not successfully loaded from the file - // XXX: Invalidate the cache file so we don't attempt to load it again next - // time - } - } - } - } - } - - void doRequest() - { - QTimer *timer = nullptr; - if (this->data.timeoutMS > 0) { - timer = new QTimer; - } - - NetworkRequester requester; - NetworkWorker *worker = new NetworkWorker; - - worker->moveToThread(&NetworkManager::workerThread); - - if (this->data.caller != nullptr) { - QObject::connect(worker, &NetworkWorker::doneUrl, - this->data.caller, [data = this->data](auto reply) mutable { - if (reply->error() != QNetworkReply::NetworkError::NoError) { - if (data.onError) { - data.onError(reply->error()); - } - return; - } - - QByteArray readBytes = reply->readAll(); - QByteArray bytes; - bytes.setRawData(readBytes.data(), readBytes.size()); - data.writeToCache(bytes); - data.onSuccess(parseJSONFromData2(bytes)); - - reply->deleteLater(); - }); - } - - if (timer != nullptr) { - timer->start(this->data.timeoutMS); - } - - QObject::connect(&requester, &NetworkRequester::requestUrl, worker, - [ timer, data = std::move(this->data), worker ]() { - QNetworkReply *reply = nullptr; - switch (data.requestType) { - case GetRequest: { - reply = NetworkManager::NaM.get(data.request); - } break; - - case PutRequest: { - reply = NetworkManager::NaM.put(data.request, data.payload); - } break; - - case DeleteRequest: { - reply = NetworkManager::NaM.deleteResource(data.request); - } break; - } - - if (reply == nullptr) { - Log("Unhandled request type {}", (int)data.requestType); - return; - } - - if (timer != nullptr) { - QObject::connect(timer, &QTimer::timeout, worker, - [reply, timer, data]() { - Log("Aborted!"); - reply->abort(); - timer->deleteLater(); - data.onError(-2); - }); - } - - if (data.onReplyCreated) { - data.onReplyCreated(reply); - } - - QObject::connect(reply, &QNetworkReply::finished, worker, - [ data = std::move(data), worker, reply ]() mutable { - if (data.caller == nullptr) { - QByteArray bytes = reply->readAll(); - data.writeToCache(bytes); - - if (data.onSuccess) { - data.onSuccess(parseJSONFromData2(bytes)); - } else { - qWarning() << "data.onSuccess not found"; - } - - reply->deleteLater(); - } else { - emit worker->doneUrl(reply); - } - - delete worker; - }); - }); - - emit requester.requestUrl(); - } - - void executeGet() - { - this->useCache(); - - this->doRequest(); - } - - void executePut() - { - this->doRequest(); - } - - void executeDelete() - { - this->doRequest(); - } + void useCache(); + void doRequest(); + void executeGet(); + void executePut(); + void executeDelete(); }; } // namespace chatterino