From 8e1b8334a1f084cb5a00f3580ec5c08056afe552 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 3 Jul 2014 14:46:17 -0700 Subject: [PATCH] Fixed invokeMethod unable to find method + fixed children in different thread --- assignment-client/src/Agent.cpp | 11 +++++++---- interface/src/Application.cpp | 11 +++++++---- libraries/networking/src/NetworkAccessManager.cpp | 12 ++++++++++++ libraries/networking/src/NetworkAccessManager.h | 5 ++++- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index fcd983873d..4a3346fc83 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -210,12 +210,15 @@ void Agent::run() { NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply *reply = networkAccessManager.get(QNetworkRequest(scriptURL)); - QNetworkDiskCache* cache = new QNetworkDiskCache(&networkAccessManager); + + // Make sure cache on same thread than its parent (NetworkAccessManager) + QNetworkDiskCache* cache = new QNetworkDiskCache(); + cache->moveToThread(networkAccessManager.thread()); + cache->setParent(&networkAccessManager); + QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "agentCache"); - QMetaObject::invokeMethod(&networkAccessManager, "setCache", - Qt::BlockingQueuedConnection, - Q_ARG(QAbstractNetworkCache*, cache)); + networkAccessManager.setCache(cache); qDebug() << "Downloading script at" << scriptURL.toString(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9b2ed7b63d..c263b71238 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -316,11 +316,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkDiskCache* cache = new QNetworkDiskCache(&networkAccessManager); + + // Make sure cache on same thread than its parent (NetworkAccessManager) + QNetworkDiskCache* cache = new QNetworkDiskCache(); + cache->moveToThread(networkAccessManager.thread()); + cache->setParent(&networkAccessManager); + cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "interfaceCache"); - QMetaObject::invokeMethod(&networkAccessManager, "setCache", - Qt::BlockingQueuedConnection, - Q_ARG(QAbstractNetworkCache*, cache)); + networkAccessManager.setCache(cache); ResourceCache::setRequestLimit(3); diff --git a/libraries/networking/src/NetworkAccessManager.cpp b/libraries/networking/src/NetworkAccessManager.cpp index b9eda27947..c2b4bfcd11 100644 --- a/libraries/networking/src/NetworkAccessManager.cpp +++ b/libraries/networking/src/NetworkAccessManager.cpp @@ -10,6 +10,7 @@ // #include +#include #include #include "NetworkAccessManager.h" @@ -146,4 +147,15 @@ QNetworkReply* NetworkAccessManager::sendCustomRequest(const QNetworkRequest& re return result; } return QNetworkAccessManager::sendCustomRequest(request, verb, data); +} + +void NetworkAccessManager::setCache(QAbstractNetworkCache* cache) { + if (QThread::currentThread() != thread()) { + qRegisterMetaType(); + QMetaObject::invokeMethod(this, + "setCache", + Qt::QueuedConnection, + Q_ARG(QAbstractNetworkCache*, cache)); + } + QNetworkAccessManager::setCache(cache); } \ No newline at end of file diff --git a/libraries/networking/src/NetworkAccessManager.h b/libraries/networking/src/NetworkAccessManager.h index ba97f12552..1b49cc9dee 100644 --- a/libraries/networking/src/NetworkAccessManager.h +++ b/libraries/networking/src/NetworkAccessManager.h @@ -18,7 +18,9 @@ /// Wrapper around QNetworkAccessManager wo that we only use one instance /// For any other method you should need, make sure to be on the right thread -/// or call the method using QMetaObject::invokeMethod() +/// or if it is not but is a slot, use QMetaObject::invokeMethod() +/// In the case what you want to call isn't a slot and you aren't on the same thread, +/// then add then method to the method to the wrapper with the Q_INVKABLE flag class NetworkAccessManager : public QNetworkAccessManager { Q_OBJECT public: @@ -33,6 +35,7 @@ public: Q_INVOKABLE QNetworkReply* put(const QNetworkRequest& request, QHttpMultiPart* multiPart); Q_INVOKABLE QNetworkReply* put(const QNetworkRequest& request, const QByteArray& data); Q_INVOKABLE QNetworkReply* sendCustomRequest(const QNetworkRequest& request, const QByteArray& verb, QIODevice* data = 0); + Q_INVOKABLE void setCache(QAbstractNetworkCache* cache); private: NetworkAccessManager();