mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:41:20 +02:00
Merge pull request #4187 from huffman/parallel-script-loading
Parallel script loading
This commit is contained in:
commit
f5e092c0d2
5 changed files with 191 additions and 54 deletions
|
@ -12,34 +12,37 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||||
Script.include("libraries/stringHelpers.js");
|
|
||||||
Script.include("libraries/dataviewHelpers.js");
|
|
||||||
Script.include("libraries/httpMultiPart.js");
|
|
||||||
Script.include("libraries/modelUploader.js");
|
|
||||||
Script.include("libraries/toolBars.js");
|
|
||||||
Script.include("libraries/progressDialog.js");
|
|
||||||
|
|
||||||
Script.include("libraries/entitySelectionTool.js");
|
Script.include([
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/stringHelpers.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/dataviewHelpers.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/httpMultiPart.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/modelUploader.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/toolBars.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/progressDialog.js",
|
||||||
|
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/entitySelectionTool.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/ModelImporter.js",
|
||||||
|
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/ExportMenu.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/ToolTip.js",
|
||||||
|
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/entityPropertyDialogBox.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/entityCameraTool.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/gridTool.js",
|
||||||
|
"http://public.highfidelity.io/scripts/libraries/entityList.js",
|
||||||
|
]);
|
||||||
|
|
||||||
var selectionDisplay = SelectionDisplay;
|
var selectionDisplay = SelectionDisplay;
|
||||||
var selectionManager = SelectionManager;
|
var selectionManager = SelectionManager;
|
||||||
|
|
||||||
Script.include("libraries/ModelImporter.js");
|
|
||||||
var modelImporter = new ModelImporter();
|
var modelImporter = new ModelImporter();
|
||||||
|
|
||||||
Script.include("libraries/ExportMenu.js");
|
|
||||||
Script.include("libraries/ToolTip.js");
|
|
||||||
|
|
||||||
Script.include("libraries/entityPropertyDialogBox.js");
|
|
||||||
var entityPropertyDialogBox = EntityPropertyDialogBox;
|
var entityPropertyDialogBox = EntityPropertyDialogBox;
|
||||||
|
|
||||||
Script.include("libraries/entityCameraTool.js");
|
|
||||||
var cameraManager = new CameraManager();
|
var cameraManager = new CameraManager();
|
||||||
|
|
||||||
Script.include("libraries/gridTool.js");
|
|
||||||
var grid = Grid();
|
var grid = Grid();
|
||||||
gridTool = GridTool({ horizontalGrid: grid });
|
gridTool = GridTool({ horizontalGrid: grid });
|
||||||
|
|
||||||
Script.include("libraries/entityList.js");
|
|
||||||
var entityListTool = EntityListTool();
|
var entityListTool = EntityListTool();
|
||||||
|
|
||||||
var hasShownPropertiesTool = false;
|
var hasShownPropertiesTool = false;
|
||||||
|
|
79
libraries/script-engine/src/BatchLoader.cpp
Normal file
79
libraries/script-engine/src/BatchLoader.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
//
|
||||||
|
// BatchLoader.cpp
|
||||||
|
// libraries/script-engine/src
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 01/22/15
|
||||||
|
// 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 <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include "BatchLoader.h"
|
||||||
|
#include <NetworkAccessManager.h>
|
||||||
|
|
||||||
|
BatchLoader::BatchLoader(const QList<QUrl>& urls)
|
||||||
|
: QObject(),
|
||||||
|
_started(false),
|
||||||
|
_finished(false),
|
||||||
|
_urls(urls.toSet()),
|
||||||
|
_data() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void BatchLoader::start() {
|
||||||
|
if (_started) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_started = true;
|
||||||
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
for (QUrl url : _urls) {
|
||||||
|
if (url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "ftp") {
|
||||||
|
QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url));
|
||||||
|
|
||||||
|
qDebug() << "Downloading file at" << url;
|
||||||
|
|
||||||
|
connect(reply, &QNetworkReply::finished, [=]() {
|
||||||
|
if (reply->error()) {
|
||||||
|
_data.insert(url, QString());
|
||||||
|
} else {
|
||||||
|
_data.insert(url, reply->readAll());
|
||||||
|
}
|
||||||
|
reply->deleteLater();
|
||||||
|
checkFinished();
|
||||||
|
});
|
||||||
|
|
||||||
|
// If we end up being destroyed before the reply finishes, clean it up
|
||||||
|
connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#ifdef _WIN32
|
||||||
|
QString fileName = url.toString();
|
||||||
|
#else
|
||||||
|
QString fileName = url.toLocalFile();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
qDebug() << "Reading file at " << fileName;
|
||||||
|
|
||||||
|
QFile scriptFile(fileName);
|
||||||
|
if (scriptFile.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
|
QTextStream in(&scriptFile);
|
||||||
|
_data.insert(url, in.readAll());
|
||||||
|
} else {
|
||||||
|
_data.insert(url, QString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BatchLoader::checkFinished() {
|
||||||
|
if (!_finished && _urls.size() == _data.size()) {
|
||||||
|
_finished = true;
|
||||||
|
emit finished(_data);
|
||||||
|
}
|
||||||
|
}
|
42
libraries/script-engine/src/BatchLoader.h
Normal file
42
libraries/script-engine/src/BatchLoader.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
//
|
||||||
|
// BatchLoader.h
|
||||||
|
// libraries/script-engine/src
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 01/22/15
|
||||||
|
// 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_BatchLoader_h
|
||||||
|
#define hifi_BatchLoader_h
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QSet>
|
||||||
|
#include <QString>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
class BatchLoader : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
BatchLoader(const QList<QUrl>& urls) ;
|
||||||
|
|
||||||
|
void start();
|
||||||
|
bool isFinished() const { return _finished; };
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(const QMap<QUrl, QString>& data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkFinished();
|
||||||
|
|
||||||
|
bool _started;
|
||||||
|
bool _finished;
|
||||||
|
QSet<QUrl> _urls;
|
||||||
|
QMap<QUrl, QString> _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_BatchLoader_h
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include "AnimationObject.h"
|
#include "AnimationObject.h"
|
||||||
#include "ArrayBufferViewClass.h"
|
#include "ArrayBufferViewClass.h"
|
||||||
|
#include "BatchLoader.h"
|
||||||
#include "DataViewClass.h"
|
#include "DataViewClass.h"
|
||||||
#include "EventTypes.h"
|
#include "EventTypes.h"
|
||||||
#include "MenuItemProperties.h"
|
#include "MenuItemProperties.h"
|
||||||
|
@ -111,7 +112,7 @@ void ScriptEngine::setIsAvatar(bool isAvatar) {
|
||||||
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
||||||
_avatarBillboardTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS);
|
_avatarBillboardTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_isAvatar) {
|
if (!_isAvatar) {
|
||||||
delete _avatarIdentityTimer;
|
delete _avatarIdentityTimer;
|
||||||
_avatarIdentityTimer = NULL;
|
_avatarIdentityTimer = NULL;
|
||||||
|
@ -304,7 +305,7 @@ QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileN
|
||||||
QScriptValue result = QScriptEngine::evaluate(program, fileName, lineNumber);
|
QScriptValue result = QScriptEngine::evaluate(program, fileName, lineNumber);
|
||||||
if (hasUncaughtException()) {
|
if (hasUncaughtException()) {
|
||||||
int line = uncaughtExceptionLineNumber();
|
int line = uncaughtExceptionLineNumber();
|
||||||
qDebug() << "Uncaught exception at (" << _fileNameString << ") line" << line << ": " << result.toString();
|
qDebug() << "Uncaught exception at (" << _fileNameString << " : " << fileName << ") line" << line << ": " << result.toString();
|
||||||
}
|
}
|
||||||
emit evaluationFinished(result, hasUncaughtException());
|
emit evaluationFinished(result, hasUncaughtException());
|
||||||
clearExceptions();
|
clearExceptions();
|
||||||
|
@ -595,46 +596,57 @@ void ScriptEngine::print(const QString& message) {
|
||||||
emit printedMessage(message);
|
emit printedMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::include(const QString& includeFile) {
|
/**
|
||||||
QUrl url = resolvePath(includeFile);
|
* If a callback is specified, the included files will be loaded asynchronously and the callback will be called
|
||||||
QString includeContents;
|
* when all of the files have finished loading.
|
||||||
|
* If no callback is specified, the included files will be loaded synchronously and will block execution until
|
||||||
|
* all of the files have finished loading.
|
||||||
|
*/
|
||||||
|
void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) {
|
||||||
|
QList<QUrl> urls;
|
||||||
|
for (QString file : includeFiles) {
|
||||||
|
urls.append(resolvePath(file));
|
||||||
|
}
|
||||||
|
|
||||||
if (url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "ftp") {
|
BatchLoader* loader = new BatchLoader(urls);
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
|
||||||
QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url));
|
auto evaluateScripts = [=](const QMap<QUrl, QString>& data) {
|
||||||
qDebug() << "Downloading included script at" << includeFile;
|
for (QUrl url : urls) {
|
||||||
QEventLoop loop;
|
QString contents = data[url];
|
||||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
if (contents.isNull()) {
|
||||||
loop.exec();
|
qDebug() << "Error loading file: " << url;
|
||||||
includeContents = reply->readAll();
|
} else {
|
||||||
reply->deleteLater();
|
QScriptValue result = evaluate(contents, url.toString());
|
||||||
} else {
|
}
|
||||||
#ifdef _WIN32
|
|
||||||
QString fileName = url.toString();
|
|
||||||
#else
|
|
||||||
QString fileName = url.toLocalFile();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QFile scriptFile(fileName);
|
|
||||||
if (scriptFile.open(QFile::ReadOnly | QFile::Text)) {
|
|
||||||
qDebug() << "Including file:" << fileName;
|
|
||||||
QTextStream in(&scriptFile);
|
|
||||||
includeContents = in.readAll();
|
|
||||||
} else {
|
|
||||||
qDebug() << "ERROR Including file:" << fileName;
|
|
||||||
emit errorMessage("ERROR Including file:" + fileName);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue result = evaluate(includeContents);
|
if (callback.isFunction()) {
|
||||||
if (hasUncaughtException()) {
|
QScriptValue(callback).call();
|
||||||
int line = uncaughtExceptionLineNumber();
|
}
|
||||||
qDebug() << "Uncaught exception at (" << includeFile << ") line" << line << ":" << result.toString();
|
|
||||||
emit errorMessage("Uncaught exception at (" + includeFile + ") line" + QString::number(line) + ":" + result.toString());
|
loader->deleteLater();
|
||||||
clearExceptions();
|
};
|
||||||
|
|
||||||
|
connect(loader, &BatchLoader::finished, this, evaluateScripts);
|
||||||
|
|
||||||
|
// If we are destroyed before the loader completes, make sure to clean it up
|
||||||
|
connect(this, &QObject::destroyed, loader, &QObject::deleteLater);
|
||||||
|
|
||||||
|
loader->start();
|
||||||
|
|
||||||
|
if (!callback.isFunction() && !loader->isFinished()) {
|
||||||
|
QEventLoop loop;
|
||||||
|
QObject::connect(loader, &BatchLoader::finished, &loop, &QEventLoop::quit);
|
||||||
|
loop.exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::include(const QString& includeFile, QScriptValue callback) {
|
||||||
|
QStringList urls;
|
||||||
|
urls.append(includeFile);
|
||||||
|
include(urls, callback);
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEngine::load(const QString& loadFile) {
|
void ScriptEngine::load(const QString& loadFile) {
|
||||||
QUrl url = resolvePath(loadFile);
|
QUrl url = resolvePath(loadFile);
|
||||||
emit loadScript(url.toString(), false);
|
emit loadScript(url.toString(), false);
|
||||||
|
|
|
@ -96,7 +96,8 @@ public slots:
|
||||||
QObject* setTimeout(const QScriptValue& function, int timeoutMS);
|
QObject* setTimeout(const QScriptValue& function, int timeoutMS);
|
||||||
void clearInterval(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); }
|
void clearInterval(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); }
|
||||||
void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); }
|
void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); }
|
||||||
void include(const QString& includeFile);
|
void include(const QStringList& includeFiles, QScriptValue callback = QScriptValue());
|
||||||
|
void include(const QString& includeFile, QScriptValue callback = QScriptValue());
|
||||||
void load(const QString& loadfile);
|
void load(const QString& loadfile);
|
||||||
void print(const QString& message);
|
void print(const QString& message);
|
||||||
QUrl resolvePath(const QString& path) const;
|
QUrl resolvePath(const QString& path) const;
|
||||||
|
|
Loading…
Reference in a new issue