mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:23:54 +02:00
Move all resource requests to the same thread
This commit is contained in:
parent
c1b3858193
commit
2c1762526d
12 changed files with 106 additions and 71 deletions
|
@ -55,14 +55,6 @@ Agent::Agent(ReceivedMessage& message) :
|
|||
{
|
||||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||
|
||||
auto assetClient = DependencyManager::set<AssetClient>();
|
||||
|
||||
QThread* assetThread = new QThread;
|
||||
assetThread->setObjectName("Asset Thread");
|
||||
assetClient->moveToThread(assetThread);
|
||||
connect(assetThread, &QThread::started, assetClient.data(), &AssetClient::init);
|
||||
assetThread->start();
|
||||
|
||||
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
||||
|
||||
DependencyManager::set<ResourceCacheSharedItems>();
|
||||
|
@ -81,6 +73,8 @@ Agent::Agent(ReceivedMessage& message) :
|
|||
{ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
|
||||
this, "handleOctreePacket");
|
||||
packetReceiver.registerListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket");
|
||||
|
||||
ResourceManager::init();
|
||||
}
|
||||
|
||||
void Agent::handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
|
@ -470,13 +464,9 @@ void Agent::aboutToFinish() {
|
|||
|
||||
// our entity tree is going to go away so tell that to the EntityScriptingInterface
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntityTree(nullptr);
|
||||
|
||||
// cleanup the AssetClient thread
|
||||
QThread* assetThread = DependencyManager::get<AssetClient>()->thread();
|
||||
DependencyManager::destroy<AssetClient>();
|
||||
assetThread->quit();
|
||||
assetThread->wait();
|
||||
|
||||
// cleanup the AudioInjectorManager (and any still running injectors)
|
||||
DependencyManager::destroy<AudioInjectorManager>();
|
||||
|
||||
ResourceManager::cleanup();
|
||||
}
|
||||
|
|
|
@ -370,7 +370,6 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
DependencyManager::set<AutoUpdater>();
|
||||
DependencyManager::set<PathUtils>();
|
||||
DependencyManager::set<InterfaceActionFactory>();
|
||||
DependencyManager::set<AssetClient>();
|
||||
DependencyManager::set<AudioInjectorManager>();
|
||||
DependencyManager::set<MessagesClient>();
|
||||
DependencyManager::set<UserInputMapper>();
|
||||
|
@ -528,13 +527,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
|
||||
audioThread->start();
|
||||
|
||||
// Setup AssetClient
|
||||
auto assetClient = DependencyManager::get<AssetClient>();
|
||||
QThread* assetThread = new QThread;
|
||||
assetThread->setObjectName("Asset Thread");
|
||||
assetClient->moveToThread(assetThread);
|
||||
connect(assetThread, &QThread::started, assetClient.data(), &AssetClient::init);
|
||||
assetThread->start();
|
||||
ResourceManager::init();
|
||||
|
||||
// Setup MessagesClient
|
||||
auto messagesClient = DependencyManager::get<MessagesClient>();
|
||||
|
@ -644,13 +637,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
connect(&identityPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendIdentityPacket);
|
||||
identityPacketTimer.start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
||||
|
||||
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkDiskCache* cache = new QNetworkDiskCache();
|
||||
cache->setMaximumCacheSize(MAXIMUM_CACHE_SIZE);
|
||||
cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "interfaceCache");
|
||||
networkAccessManager.setCache(cache);
|
||||
|
||||
ResourceCache::setRequestLimit(3);
|
||||
|
||||
_glWidget = new GLCanvas();
|
||||
|
@ -1129,12 +1115,6 @@ Application::~Application() {
|
|||
DependencyManager::destroy<ScriptCache>();
|
||||
DependencyManager::destroy<SoundCache>();
|
||||
|
||||
// cleanup the AssetClient thread
|
||||
QThread* assetThread = DependencyManager::get<AssetClient>()->thread();
|
||||
DependencyManager::destroy<AssetClient>();
|
||||
assetThread->quit();
|
||||
assetThread->wait();
|
||||
|
||||
QThread* nodeThread = DependencyManager::get<NodeList>()->thread();
|
||||
|
||||
// remove the NodeList from the DependencyManager
|
||||
|
@ -1150,6 +1130,8 @@ Application::~Application() {
|
|||
ConnexionClient::getInstance().destroy();
|
||||
#endif
|
||||
|
||||
ResourceManager::cleanup();
|
||||
|
||||
qInstallMessageHandler(NULL); // NOTE: Do this as late as possible so we continue to get our log messages
|
||||
}
|
||||
|
||||
|
|
|
@ -47,22 +47,20 @@ AssetClient::AssetClient() {
|
|||
}
|
||||
|
||||
void AssetClient::init() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "init", Qt::BlockingQueuedConnection);
|
||||
}
|
||||
|
||||
Q_ASSERT(QThread::currentThread() == thread());
|
||||
|
||||
// Setup disk cache if not already
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
auto& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
if (!networkAccessManager.cache()) {
|
||||
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
cachePath = !cachePath.isEmpty() ? cachePath : "interfaceCache";
|
||||
|
||||
|
||||
QNetworkDiskCache* cache = new QNetworkDiskCache();
|
||||
cache->setMaximumCacheSize(MAXIMUM_CACHE_SIZE);
|
||||
cache->setCacheDirectory(cachePath);
|
||||
networkAccessManager.setCache(cache);
|
||||
qCDebug(asset_client) << "AssetClient disk cache setup at" << cachePath
|
||||
<< "(size:" << MAXIMUM_CACHE_SIZE / BYTES_PER_GIGABYTES << "GB)";
|
||||
qDebug() << "ResourceManager disk cache setup at" << cachePath
|
||||
<< "(size:" << MAXIMUM_CACHE_SIZE / BYTES_PER_GIGABYTES << "GB)";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,13 +43,14 @@ class AssetClient : public QObject, public Dependency {
|
|||
Q_OBJECT
|
||||
public:
|
||||
AssetClient();
|
||||
|
||||
Q_INVOKABLE void init();
|
||||
|
||||
Q_INVOKABLE AssetRequest* createRequest(const QString& hash, const QString& extension);
|
||||
Q_INVOKABLE AssetUpload* createUpload(const QString& filename);
|
||||
Q_INVOKABLE AssetUpload* createUpload(const QByteArray& data, const QString& extension);
|
||||
|
||||
public slots:
|
||||
void init();
|
||||
|
||||
private slots:
|
||||
void handleAssetGetInfoReply(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleAssetGetReply(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
class AssetResourceRequest : public ResourceRequest {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AssetResourceRequest(QObject* parent, const QUrl& url) : ResourceRequest(parent, url) { }
|
||||
AssetResourceRequest(const QUrl& url) : ResourceRequest(url) { }
|
||||
~AssetResourceRequest();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
class FileResourceRequest : public ResourceRequest {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FileResourceRequest(QObject* parent, const QUrl& url) : ResourceRequest(parent, url) { }
|
||||
FileResourceRequest(const QUrl& url) : ResourceRequest(url) { }
|
||||
|
||||
protected:
|
||||
virtual void doSend() override;
|
||||
|
|
|
@ -28,6 +28,25 @@ HTTPResourceRequest::~HTTPResourceRequest() {
|
|||
}
|
||||
}
|
||||
|
||||
void HTTPResourceRequest::setupTimer() {
|
||||
Q_ASSERT(!_sendTimer);
|
||||
static const int TIMEOUT_MS = 10000;
|
||||
|
||||
_sendTimer = new QTimer();
|
||||
connect(this, &QObject::destroyed, _sendTimer, &QTimer::deleteLater);
|
||||
connect(_sendTimer, &QTimer::timeout, this, &HTTPResourceRequest::onTimeout);
|
||||
|
||||
_sendTimer->setSingleShot(true);
|
||||
_sendTimer->start(TIMEOUT_MS);
|
||||
}
|
||||
|
||||
void HTTPResourceRequest::cleanupTimer() {
|
||||
Q_ASSERT(_sendTimer);
|
||||
_sendTimer->disconnect(this);
|
||||
_sendTimer->deleteLater();
|
||||
_sendTimer = nullptr;
|
||||
}
|
||||
|
||||
void HTTPResourceRequest::doSend() {
|
||||
QNetworkRequest networkRequest(_url);
|
||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
|
@ -42,18 +61,15 @@ void HTTPResourceRequest::doSend() {
|
|||
|
||||
connect(_reply, &QNetworkReply::finished, this, &HTTPResourceRequest::onRequestFinished);
|
||||
connect(_reply, &QNetworkReply::downloadProgress, this, &HTTPResourceRequest::onDownloadProgress);
|
||||
connect(&_sendTimer, &QTimer::timeout, this, &HTTPResourceRequest::onTimeout);
|
||||
|
||||
static const int TIMEOUT_MS = 10000;
|
||||
_sendTimer.setSingleShot(true);
|
||||
_sendTimer.start(TIMEOUT_MS);
|
||||
setupTimer();
|
||||
}
|
||||
|
||||
void HTTPResourceRequest::onRequestFinished() {
|
||||
Q_ASSERT(_state == InProgress);
|
||||
Q_ASSERT(_reply);
|
||||
|
||||
_sendTimer.stop();
|
||||
cleanupTimer();
|
||||
|
||||
switch(_reply->error()) {
|
||||
case QNetworkReply::NoError:
|
||||
|
@ -80,7 +96,7 @@ void HTTPResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesT
|
|||
Q_ASSERT(_state == InProgress);
|
||||
|
||||
// We've received data, so reset the timer
|
||||
_sendTimer.start();
|
||||
_sendTimer->start();
|
||||
|
||||
emit progress(bytesReceived, bytesTotal);
|
||||
}
|
||||
|
@ -91,6 +107,8 @@ void HTTPResourceRequest::onTimeout() {
|
|||
_reply->abort();
|
||||
_reply->deleteLater();
|
||||
_reply = nullptr;
|
||||
|
||||
cleanupTimer();
|
||||
|
||||
_result = Timeout;
|
||||
_state = Finished;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
class HTTPResourceRequest : public ResourceRequest {
|
||||
Q_OBJECT
|
||||
public:
|
||||
HTTPResourceRequest(QObject* parent, const QUrl& url) : ResourceRequest(parent, url) { }
|
||||
HTTPResourceRequest(const QUrl& url) : ResourceRequest(url) { }
|
||||
~HTTPResourceRequest();
|
||||
|
||||
protected:
|
||||
|
@ -33,7 +33,10 @@ private slots:
|
|||
void onRequestFinished();
|
||||
|
||||
private:
|
||||
QTimer _sendTimer;
|
||||
void setupTimer();
|
||||
void cleanupTimer();
|
||||
|
||||
QTimer* _sendTimer { nullptr };
|
||||
QNetworkReply* _reply { nullptr };
|
||||
};
|
||||
|
||||
|
|
|
@ -11,12 +11,20 @@
|
|||
|
||||
#include "ResourceManager.h"
|
||||
|
||||
#include "AssetResourceRequest.h"
|
||||
#include "FileResourceRequest.h"
|
||||
#include "HTTPResourceRequest.h"
|
||||
#include <QNetworkDiskCache>
|
||||
#include <QStandardPaths>
|
||||
#include <QThread>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
||||
#include "AssetResourceRequest.h"
|
||||
#include "FileResourceRequest.h"
|
||||
#include "HTTPResourceRequest.h"
|
||||
#include "NetworkAccessManager.h"
|
||||
|
||||
|
||||
QThread ResourceManager::_thread;
|
||||
ResourceManager::PrefixMap ResourceManager::_prefixMap;
|
||||
QMutex ResourceManager::_prefixMapLock;
|
||||
|
||||
|
@ -67,18 +75,41 @@ QUrl ResourceManager::normalizeURL(const QUrl& originalUrl) {
|
|||
return url;
|
||||
}
|
||||
|
||||
void ResourceManager::init() {
|
||||
_thread.setObjectName("Ressource Manager Thread");
|
||||
|
||||
auto assetClient = DependencyManager::set<AssetClient>();
|
||||
assetClient->moveToThread(&_thread);
|
||||
QObject::connect(&_thread, &QThread::started, assetClient.data(), &AssetClient::init);
|
||||
|
||||
_thread.start();
|
||||
}
|
||||
|
||||
void ResourceManager::cleanup() {
|
||||
// cleanup the AssetClient thread
|
||||
DependencyManager::destroy<AssetClient>();
|
||||
_thread.quit();
|
||||
_thread.wait();
|
||||
}
|
||||
|
||||
ResourceRequest* ResourceManager::createResourceRequest(QObject* parent, const QUrl& url) {
|
||||
auto normalizedURL = normalizeURL(url);
|
||||
auto scheme = normalizedURL.scheme();
|
||||
|
||||
ResourceRequest* request = nullptr;
|
||||
|
||||
if (scheme == URL_SCHEME_FILE) {
|
||||
return new FileResourceRequest(parent, normalizedURL);
|
||||
request = new FileResourceRequest(normalizedURL);
|
||||
} else if (scheme == URL_SCHEME_HTTP || scheme == URL_SCHEME_HTTPS || scheme == URL_SCHEME_FTP) {
|
||||
return new HTTPResourceRequest(parent, normalizedURL);
|
||||
request = new HTTPResourceRequest(normalizedURL);
|
||||
} else if (scheme == URL_SCHEME_ATP) {
|
||||
return new AssetResourceRequest(parent, normalizedURL);
|
||||
request = new AssetResourceRequest(normalizedURL);
|
||||
} else {
|
||||
qDebug() << "Unknown scheme (" << scheme << ") for URL: " << url.url();
|
||||
return nullptr;
|
||||
}
|
||||
Q_ASSERT(request);
|
||||
|
||||
qDebug() << "Unknown scheme (" << scheme << ") for URL: " << url.url();
|
||||
|
||||
return nullptr;
|
||||
request->moveToThread(&_thread);
|
||||
return request;
|
||||
}
|
||||
|
|
|
@ -29,8 +29,15 @@ public:
|
|||
static void setUrlPrefixOverride(const QString& prefix, const QString& replacement);
|
||||
static QString normalizeURL(const QString& urlString);
|
||||
static QUrl normalizeURL(const QUrl& url);
|
||||
|
||||
static ResourceRequest* createResourceRequest(QObject* parent, const QUrl& url);
|
||||
|
||||
static void init();
|
||||
static void cleanup();
|
||||
|
||||
private:
|
||||
static QThread _thread;
|
||||
|
||||
using PrefixMap = std::map<QString, QString>;
|
||||
|
||||
static PrefixMap _prefixMap;
|
||||
|
|
|
@ -11,12 +11,15 @@
|
|||
|
||||
#include "ResourceRequest.h"
|
||||
|
||||
ResourceRequest::ResourceRequest(QObject* parent, const QUrl& url) :
|
||||
QObject(parent),
|
||||
_url(url) {
|
||||
}
|
||||
#include <QtCore/QThread>
|
||||
|
||||
ResourceRequest::ResourceRequest(const QUrl& url) : _url(url) { }
|
||||
|
||||
void ResourceRequest::send() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "send", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
Q_ASSERT(_state == NotStarted);
|
||||
|
||||
_state = InProgress;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
class ResourceRequest : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ResourceRequest(QObject* parent, const QUrl& url);
|
||||
ResourceRequest(const QUrl& url);
|
||||
|
||||
enum State {
|
||||
NotStarted = 0,
|
||||
|
@ -38,7 +38,6 @@ public:
|
|||
NotFound
|
||||
};
|
||||
|
||||
void send();
|
||||
QByteArray getData() { return _data; }
|
||||
State getState() const { return _state; }
|
||||
Result getResult() const { return _result; }
|
||||
|
@ -47,8 +46,11 @@ public:
|
|||
|
||||
void setCacheEnabled(bool value) { _cacheEnabled = value; }
|
||||
|
||||
public slots:
|
||||
void send();
|
||||
|
||||
signals:
|
||||
void progress(uint64_t bytesReceived, uint64_t bytesTotal);
|
||||
void progress(qint64 bytesReceived, qint64 bytesTotal);
|
||||
void finished();
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in a new issue