add Script.include()

This commit is contained in:
ZappoMan 2014-03-24 21:25:59 -07:00
parent db05523bc3
commit a613da8032
3 changed files with 75 additions and 4 deletions

View file

@ -0,0 +1,16 @@
//
// includeExample.js
// hifi
//
// Created by Brad Hefta-Gaub on 3/24/14
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
// This is an example script that demonstrates use of the Script.include() feature
//
// You can include scripts from URLs
Script.include("http://public.highfidelity.io/scripts/lookWithTouch.js");
// You can also include scripts that are relative to the current script
Script.include("editVoxels.js");
Script.include("../examples/selectAudioDevice.js");

View file

@ -113,11 +113,12 @@ void ScriptEngine::cleanupMenuItems() {
}
}
bool ScriptEngine::setScriptContents(const QString& scriptContents) {
bool ScriptEngine::setScriptContents(const QString& scriptContents, const QString& fileNameString) {
if (_isRunning) {
return false;
}
_scriptContents = scriptContents;
_fileNameString = fileNameString;
return true;
}
@ -436,3 +437,55 @@ void ScriptEngine::stopTimer(QTimer *timer) {
delete timer;
}
}
QUrl ScriptEngine::resolveInclude(const QString& include) const {
// first lets check to see if it's already a full URL
QUrl url(include);
if (!url.scheme().isEmpty()) {
return url;
}
// we apparently weren't a fully qualified url, so, let's assume we're relative
// to the original URL of our script
QUrl parentURL(_fileNameString);
// if the parent URL's scheme is empty, then this is probably a local file...
if (parentURL.scheme().isEmpty()) {
parentURL = QUrl::fromLocalFile(_fileNameString);
}
// at this point we should have a legitimate fully qualified URL for our parent
url = parentURL.resolved(url);
return url;
}
void ScriptEngine::include(const QString& includeFile) {
QUrl url = resolveInclude(includeFile);
QString includeContents;
if (url.scheme() == "file") {
QString fileName = url.toLocalFile();
QFile scriptFile(fileName);
if (scriptFile.open(QFile::ReadOnly | QFile::Text)) {
qDebug() << "Loading file:" << fileName;
QTextStream in(&scriptFile);
includeContents = in.readAll();
} else {
qDebug() << "ERROR Loading file:" << fileName;
}
} else {
QNetworkAccessManager* networkManager = new QNetworkAccessManager(this);
QNetworkReply* reply = networkManager->get(QNetworkRequest(url));
qDebug() << "Downloading included script at" << includeFile;
QEventLoop loop;
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
includeContents = reply->readAll();
}
QScriptValue result = _engine.evaluate(includeContents);
if (_engine.hasUncaughtException()) {
int line = _engine.uncaughtExceptionLineNumber();
qDebug() << "Uncaught exception at (" << includeFile << ") line" << line << ":" << result.toString();
}
}

View file

@ -33,8 +33,8 @@ const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 10
class ScriptEngine : public QObject {
Q_OBJECT
public:
ScriptEngine(const QString& scriptContents = NO_SCRIPT, bool wantMenuItems = false,
const QString& scriptMenuName = QString(""),
ScriptEngine(const QString& scriptContents = NO_SCRIPT, bool wantMenuItems = false,
const QString& fileNameString = QString(""),
AbstractControllerScriptingInterface* controllerScriptingInterface = NULL);
/// Access the VoxelsScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
@ -44,7 +44,7 @@ public:
static ParticlesScriptingInterface* getParticlesScriptingInterface() { return &_particlesScriptingInterface; }
/// sets the script contents, will return false if failed, will fail if script is already running
bool setScriptContents(const QString& scriptContents);
bool setScriptContents(const QString& scriptContents, const QString& fileNameString = QString(""));
const QString& getScriptMenuName() const { return _scriptMenuName; }
void cleanupMenuItems();
@ -75,6 +75,7 @@ public slots:
QObject* setTimeout(const QScriptValue& function, int timeoutMS);
void clearInterval(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); }
void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); }
void include(const QString& includeFile);
signals:
void update(float deltaTime);
@ -97,6 +98,7 @@ protected:
int _numAvatarSoundSentBytes;
private:
QUrl resolveInclude(const QString& include) const;
void sendAvatarIdentityPacket();
void sendAvatarBillboardPacket();