mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 20:29:10 +02:00
first cut at script caching
This commit is contained in:
parent
099a2b5319
commit
36657c9473
8 changed files with 309 additions and 4 deletions
|
@ -76,7 +76,7 @@
|
|||
#include <PhysicsEngine.h>
|
||||
#include <ProgramObject.h>
|
||||
#include <ResourceCache.h>
|
||||
//#include <ScriptCache.h>
|
||||
#include <ScriptCache.h>
|
||||
#include <SettingHandle.h>
|
||||
#include <SoundCache.h>
|
||||
#include <TextRenderer.h>
|
||||
|
@ -221,7 +221,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
auto addressManager = DependencyManager::set<AddressManager>();
|
||||
auto nodeList = DependencyManager::set<NodeList>(NodeType::Agent, listenPort);
|
||||
auto geometryCache = DependencyManager::set<GeometryCache>();
|
||||
//auto scriptCache = DependencyManager::set<ScriptCache>();
|
||||
auto scriptCache = DependencyManager::set<ScriptCache>();
|
||||
auto soundCache = DependencyManager::set<SoundCache>();
|
||||
auto glowEffect = DependencyManager::set<GlowEffect>();
|
||||
auto faceshift = DependencyManager::set<Faceshift>();
|
||||
|
@ -612,7 +612,7 @@ Application::~Application() {
|
|||
DependencyManager::destroy<AnimationCache>();
|
||||
DependencyManager::destroy<TextureCache>();
|
||||
DependencyManager::destroy<GeometryCache>();
|
||||
//DependencyManager::destroy<ScriptCache>();
|
||||
DependencyManager::destroy<ScriptCache>();
|
||||
DependencyManager::destroy<SoundCache>();
|
||||
|
||||
QThread* nodeThread = DependencyManager::get<NodeList>()->thread();
|
||||
|
|
|
@ -148,6 +148,7 @@ QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorTe
|
|||
qDebug() << "ERROR Loading file:" << fileName;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkRequest networkRequest = QNetworkRequest(url);
|
||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
|
@ -162,6 +163,10 @@ QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorTe
|
|||
qDebug() << "ERROR Loading file:" << url.toString();
|
||||
}
|
||||
delete reply;
|
||||
*/
|
||||
auto scriptCache = DependencyManager::get<ScriptCache>();
|
||||
scriptContents = scriptCache->getScript(url);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
49
libraries/script-engine/src/Script.cpp
Normal file
49
libraries/script-engine/src/Script.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// Script.cpp
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2015-03-30
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/*
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <qendian.h>
|
||||
|
||||
#include <LimitedNodeList.h>
|
||||
#include <NetworkAccessManager.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "AudioRingBuffer.h"
|
||||
#include "AudioFormat.h"
|
||||
#include "AudioBuffer.h"
|
||||
#include "AudioEditBuffer.h"
|
||||
*/
|
||||
|
||||
#include "Script.h"
|
||||
|
||||
Script::Script(const QUrl& url) :
|
||||
Resource(url),
|
||||
_isReady(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Script::downloadFinished(QNetworkReply* reply) {
|
||||
// replace our byte array with the downloaded data
|
||||
_contents = reply->readAll();
|
||||
qDebug() << "Script downloaded from:" << getURL();
|
||||
_isReady = true;
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
37
libraries/script-engine/src/Script.h
Normal file
37
libraries/script-engine/src/Script.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// Script.h
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2015-03-30
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_Script_h
|
||||
#define hifi_Script_h
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtScript/qscriptengine.h>
|
||||
|
||||
#include <ResourceCache.h>
|
||||
|
||||
class Script : public Resource {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Script(const QUrl& url);
|
||||
bool isReady() const { return _isReady; }
|
||||
const QString& getContents() { return _contents; }
|
||||
|
||||
private:
|
||||
QString _contents;
|
||||
bool _isReady;
|
||||
|
||||
virtual void downloadFinished(QNetworkReply* reply);
|
||||
};
|
||||
|
||||
typedef QSharedPointer<Script> SharedScriptPointer;
|
||||
|
||||
#endif // hifi_Script_h
|
146
libraries/script-engine/src/ScriptCache.cpp
Normal file
146
libraries/script-engine/src/ScriptCache.cpp
Normal file
|
@ -0,0 +1,146 @@
|
|||
//
|
||||
// ScriptCache.cpp
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2015-03-30
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QObject>
|
||||
|
||||
#include <NetworkAccessManager.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "ScriptCache.h"
|
||||
|
||||
ScriptCache::ScriptCache(QObject* parent) {
|
||||
// nothing to do here...
|
||||
}
|
||||
|
||||
// QHash<QUrl, QString> _scriptCache;
|
||||
|
||||
void ScriptCache::getScript(const QUrl& url, ScriptUser* scriptUser) {
|
||||
if (_scriptCache.contains(url)) {
|
||||
scriptUser->scriptContentsAvailable(url, _scriptCache[url]);
|
||||
return;
|
||||
}
|
||||
_scriptUsers.insert(url, scriptUser);
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkRequest networkRequest = QNetworkRequest(url);
|
||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
QNetworkReply* reply = networkAccessManager.get(networkRequest);
|
||||
connect(reply, &QNetworkReply::finished, this, &ScriptCache::scriptDownloaded);
|
||||
}
|
||||
|
||||
void ScriptCache::scriptDownloaded() {
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
QUrl url = reply->url();
|
||||
QList<ScriptUser*> scriptUsers = _scriptUsers.values(url);
|
||||
_scriptUsers.remove(url);
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) {
|
||||
_scriptCache[url] = reply->readAll();
|
||||
qDebug() << "_scriptCache.size:" << _scriptCache.size();
|
||||
|
||||
foreach(ScriptUser* user, scriptUsers) {
|
||||
user->scriptContentsAvailable(url, _scriptCache[url]);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "ERROR Loading file:" << reply->url().toString();
|
||||
foreach(ScriptUser* user, scriptUsers) {
|
||||
user->errorInLoadingScript(url);
|
||||
}
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
QString ScriptCache::getScript(const QUrl& url) {
|
||||
qDebug() << "Script requested: " << url.toString();
|
||||
QString scriptContents;
|
||||
if (_scriptCache.contains(url)) {
|
||||
qDebug() << "Script found in cache: " << url.toString();
|
||||
scriptContents = _scriptCache[url];
|
||||
} else {
|
||||
qDebug() << "Script not found in cache: " << url.toString();
|
||||
|
||||
if (_blockingScriptsPending.contains(url)) {
|
||||
// if we're already downloading this script, wait for it to complete...
|
||||
qDebug() << "Already downloading script: " << url.toString();
|
||||
while (_blockingScriptsPending.contains(url)) {
|
||||
QEventLoop loop;
|
||||
qDebug() << "about to call loop.processEvents()....";
|
||||
loop.processEvents(QEventLoop::AllEvents, 1);
|
||||
qDebug() << "AFTER loop.processEvents()....";
|
||||
}
|
||||
qDebug() << "Done waiting on downloading script: " << url.toString();
|
||||
scriptContents = _scriptCache[url];
|
||||
} else {
|
||||
_blockingScriptsPending.insert(url);
|
||||
qDebug() << "_blockingScriptsPending: " << _blockingScriptsPending;
|
||||
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkRequest networkRequest = QNetworkRequest(url);
|
||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
QNetworkReply* reply = networkAccessManager.get(networkRequest);
|
||||
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, &ScriptCache::scriptDownloadedSyncronously);
|
||||
qDebug() << "Downloading script at" << url.toString();
|
||||
//QEventLoop loop;
|
||||
//QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||
//qDebug() << "starting loop....";
|
||||
//loop.exec();
|
||||
//qDebug() << "after loop....";
|
||||
|
||||
/*
|
||||
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) {
|
||||
scriptContents = reply->readAll();
|
||||
_scriptCache[url] = scriptContents;
|
||||
qDebug() << "_scriptCache.size:" << _scriptCache.size();
|
||||
} else {
|
||||
qDebug() << "ERROR Loading file:" << url.toString();
|
||||
}
|
||||
delete reply;
|
||||
_blockingScriptsPending.remove(url);
|
||||
qDebug() << "_blockingScriptsPending: " << _blockingScriptsPending;
|
||||
*/
|
||||
while (_blockingScriptsPending.contains(url)) {
|
||||
QEventLoop loop;
|
||||
qDebug() << "about to call loop.processEvents()....";
|
||||
loop.processEvents(QEventLoop::AllEvents, 1);
|
||||
qDebug() << "AFTER loop.processEvents()....";
|
||||
}
|
||||
qDebug() << "Done waiting on downloading script: " << url.toString();
|
||||
scriptContents = _scriptCache[url];
|
||||
}
|
||||
}
|
||||
return scriptContents;
|
||||
}
|
||||
|
||||
void ScriptCache::scriptDownloadedSyncronously() {
|
||||
|
||||
qDebug() << "ScriptCache::scriptDownloadedSyncronously()....";
|
||||
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
QUrl url = reply->url();
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) {
|
||||
_scriptCache[url] = reply->readAll();
|
||||
qDebug() << "_scriptCache.size:" << _scriptCache.size();
|
||||
} else {
|
||||
qDebug() << "ERROR Loading file:" << reply->url().toString();
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
_blockingScriptsPending.remove(url);
|
||||
qDebug() << "_blockingScriptsPending: " << _blockingScriptsPending;
|
||||
}
|
||||
|
46
libraries/script-engine/src/ScriptCache.h
Normal file
46
libraries/script-engine/src/ScriptCache.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// ScriptCache.h
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2015-03-30
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ScriptCache_h
|
||||
#define hifi_ScriptCache_h
|
||||
|
||||
#include <ResourceCache.h>
|
||||
#include "Script.h"
|
||||
|
||||
class ScriptUser {
|
||||
public:
|
||||
virtual void scriptContentsAvailable(const QUrl& url, const QString& scriptContents) = 0;
|
||||
virtual void errorInLoadingScript(const QUrl& url) = 0;
|
||||
};
|
||||
|
||||
/// Interface for loading scripts
|
||||
class ScriptCache : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
void getScript(const QUrl& url, ScriptUser* scriptUser); // asynchronous
|
||||
QString getScript(const QUrl& url); // blocking call
|
||||
|
||||
private slots:
|
||||
void scriptDownloaded();
|
||||
void scriptDownloadedSyncronously();
|
||||
|
||||
|
||||
private:
|
||||
ScriptCache(QObject* parent = NULL);
|
||||
|
||||
QHash<QUrl, QString> _scriptCache;
|
||||
QMultiMap<QUrl, ScriptUser*> _scriptUsers;
|
||||
QSet<QUrl> _blockingScriptsPending;
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptCache_h
|
|
@ -34,6 +34,7 @@
|
|||
#include "EventTypes.h"
|
||||
#include "MenuItemProperties.h"
|
||||
#include "ScriptAudioInjector.h"
|
||||
#include "ScriptCache.h"
|
||||
#include "ScriptEngine.h"
|
||||
#include "TypedArrays.h"
|
||||
#include "XMLHttpRequestClass.h"
|
||||
|
@ -279,16 +280,22 @@ void ScriptEngine::loadURL(const QUrl& scriptURL) {
|
|||
emit errorLoadingScript(_fileNameString);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkRequest networkRequest = QNetworkRequest(url);
|
||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
QNetworkReply* reply = networkAccessManager.get(networkRequest);
|
||||
connect(reply, &QNetworkReply::finished, this, &ScriptEngine::handleScriptDownload);
|
||||
*/
|
||||
auto scriptCache = DependencyManager::get<ScriptCache>();
|
||||
scriptCache->getScript(url, this);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::handleScriptDownload() {
|
||||
/*
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) {
|
||||
|
@ -300,6 +307,17 @@ void ScriptEngine::handleScriptDownload() {
|
|||
}
|
||||
|
||||
reply->deleteLater();
|
||||
*/
|
||||
}
|
||||
|
||||
void ScriptEngine::scriptContentsAvailable(const QUrl& url, const QString& scriptContents) {
|
||||
_scriptContents = scriptContents;
|
||||
emit scriptLoaded(_fileNameString);
|
||||
}
|
||||
|
||||
void ScriptEngine::errorInLoadingScript(const QUrl& url) {
|
||||
qDebug() << "ERROR Loading file:" << url.toString();
|
||||
emit errorLoadingScript(_fileNameString); // ??
|
||||
}
|
||||
|
||||
void ScriptEngine::init() {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "ArrayBufferClass.h"
|
||||
#include "AudioScriptingInterface.h"
|
||||
#include "Quat.h"
|
||||
#include "ScriptCache.h"
|
||||
#include "ScriptUUID.h"
|
||||
#include "Vec3.h"
|
||||
|
||||
|
@ -35,7 +36,7 @@ const QString NO_SCRIPT("");
|
|||
|
||||
const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 1000) + 0.5);
|
||||
|
||||
class ScriptEngine : public QScriptEngine {
|
||||
class ScriptEngine : public QScriptEngine, public ScriptUser {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScriptEngine(const QString& scriptContents = NO_SCRIPT,
|
||||
|
@ -94,6 +95,9 @@ public:
|
|||
|
||||
void waitTillDoneRunning();
|
||||
|
||||
virtual void scriptContentsAvailable(const QUrl& url, const QString& scriptContents);
|
||||
virtual void errorInLoadingScript(const QUrl& url);
|
||||
|
||||
public slots:
|
||||
void loadURL(const QUrl& scriptURL);
|
||||
void stop();
|
||||
|
|
Loading…
Reference in a new issue