mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 18:13:05 +02:00
Merge pull request #6021 from jherico/homer
Support reload-on-change for local scripts
This commit is contained in:
commit
65473cadcb
2 changed files with 57 additions and 6 deletions
|
@ -11,12 +11,13 @@
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
#include <QtCore/QEventLoop>
|
#include <QtCore/QEventLoop>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
#include <QtNetwork/QNetworkRequest>
|
#include <QtNetwork/QNetworkRequest>
|
||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
#include <QScriptEngine>
|
#include <QtScript/QScriptEngine>
|
||||||
#include <QScriptValue>
|
#include <QtScript/QScriptValue>
|
||||||
|
|
||||||
#include <AudioConstants.h>
|
#include <AudioConstants.h>
|
||||||
#include <AudioEffectOptions.h>
|
#include <AudioEffectOptions.h>
|
||||||
|
@ -942,6 +943,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto scriptCache = DependencyManager::get<ScriptCache>();
|
auto scriptCache = DependencyManager::get<ScriptCache>();
|
||||||
|
bool isFileUrl = isURL && scriptOrURL.startsWith("file://");
|
||||||
|
|
||||||
// first check the syntax of the script contents
|
// first check the syntax of the script contents
|
||||||
QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents);
|
QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents);
|
||||||
|
@ -950,7 +952,9 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
||||||
qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":"
|
qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":"
|
||||||
<< syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber();
|
<< syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber();
|
||||||
qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
|
qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
|
||||||
|
if (!isFileUrl) {
|
||||||
scriptCache->addScriptToBadScriptList(scriptOrURL);
|
scriptCache->addScriptToBadScriptList(scriptOrURL);
|
||||||
|
}
|
||||||
return; // done processing script
|
return; // done processing script
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -965,14 +969,21 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
||||||
qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID;
|
qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID;
|
||||||
qCDebug(scriptengine) << " NOT CONSTRUCTOR";
|
qCDebug(scriptengine) << " NOT CONSTRUCTOR";
|
||||||
qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
|
qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
|
||||||
|
if (!isFileUrl) {
|
||||||
scriptCache->addScriptToBadScriptList(scriptOrURL);
|
scriptCache->addScriptToBadScriptList(scriptOrURL);
|
||||||
|
}
|
||||||
return; // done processing script
|
return; // done processing script
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue entityScriptConstructor = evaluate(contents);
|
int64_t lastModified = 0;
|
||||||
|
if (isFileUrl) {
|
||||||
|
QString file = QUrl(scriptOrURL).toLocalFile();
|
||||||
|
lastModified = (quint64)QFileInfo(file).lastModified().toMSecsSinceEpoch();
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue entityScriptConstructor = evaluate(contents);
|
||||||
QScriptValue entityScriptObject = entityScriptConstructor.construct();
|
QScriptValue entityScriptObject = entityScriptConstructor.construct();
|
||||||
EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject };
|
EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified };
|
||||||
_entityScripts[entityID] = newDetails;
|
_entityScripts[entityID] = newDetails;
|
||||||
if (isURL) {
|
if (isURL) {
|
||||||
setParentURL("");
|
setParentURL("");
|
||||||
|
@ -1022,6 +1033,41 @@ void ScriptEngine::unloadAllEntityScripts() {
|
||||||
_entityScripts.clear();
|
_entityScripts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::refreshFileScript(const EntityItemID& entityID) {
|
||||||
|
if (!_entityScripts.contains(entityID)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool recurseGuard = false;
|
||||||
|
if (recurseGuard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
recurseGuard = true;
|
||||||
|
|
||||||
|
EntityScriptDetails details = _entityScripts[entityID];
|
||||||
|
// Check to see if a file based script needs to be reloaded (easier debugging)
|
||||||
|
if (details.lastModified > 0) {
|
||||||
|
QString filePath = QUrl(details.scriptText).toLocalFile();
|
||||||
|
auto lastModified = QFileInfo(filePath).lastModified().toMSecsSinceEpoch();
|
||||||
|
if (lastModified > details.lastModified) {
|
||||||
|
qDebug() << "Reloading modified script " << details.scriptText;
|
||||||
|
|
||||||
|
QFile file(filePath);
|
||||||
|
file.open(QIODevice::ReadOnly);
|
||||||
|
QString scriptContents = QTextStream(&file).readAll();
|
||||||
|
this->unloadEntityScript(entityID);
|
||||||
|
this->entityScriptContentAvailable(entityID, details.scriptText, scriptContents, true, true);
|
||||||
|
if (!_entityScripts.contains(entityID)) {
|
||||||
|
qWarning() << "Reload script " << details.scriptText << " failed";
|
||||||
|
} else {
|
||||||
|
details = _entityScripts[entityID];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recurseGuard = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName) {
|
void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
#ifdef THREAD_DEBUGGING
|
#ifdef THREAD_DEBUGGING
|
||||||
|
@ -1039,6 +1085,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
"entityID:" << entityID << "methodName:" << methodName;
|
"entityID:" << entityID << "methodName:" << methodName;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
refreshFileScript(entityID);
|
||||||
if (_entityScripts.contains(entityID)) {
|
if (_entityScripts.contains(entityID)) {
|
||||||
EntityScriptDetails details = _entityScripts[entityID];
|
EntityScriptDetails details = _entityScripts[entityID];
|
||||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||||
|
@ -1069,6 +1116,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
"entityID:" << entityID << "methodName:" << methodName << "event: mouseEvent";
|
"entityID:" << entityID << "methodName:" << methodName << "event: mouseEvent";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
refreshFileScript(entityID);
|
||||||
if (_entityScripts.contains(entityID)) {
|
if (_entityScripts.contains(entityID)) {
|
||||||
EntityScriptDetails details = _entityScripts[entityID];
|
EntityScriptDetails details = _entityScripts[entityID];
|
||||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||||
|
@ -1101,6 +1149,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
"entityID:" << entityID << "methodName:" << methodName << "otherID:" << otherID << "collision: collision";
|
"entityID:" << entityID << "methodName:" << methodName << "otherID:" << otherID << "collision: collision";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
refreshFileScript(entityID);
|
||||||
if (_entityScripts.contains(entityID)) {
|
if (_entityScripts.contains(entityID)) {
|
||||||
EntityScriptDetails details = _entityScripts[entityID];
|
EntityScriptDetails details = _entityScripts[entityID];
|
||||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||||
|
|
|
@ -45,6 +45,7 @@ class EntityScriptDetails {
|
||||||
public:
|
public:
|
||||||
QString scriptText;
|
QString scriptText;
|
||||||
QScriptValue scriptObject;
|
QScriptValue scriptObject;
|
||||||
|
int64_t lastModified;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScriptEngine : public QScriptEngine, public ScriptUser, public EntitiesScriptEngineProvider {
|
class ScriptEngine : public QScriptEngine, public ScriptUser, public EntitiesScriptEngineProvider {
|
||||||
|
@ -171,6 +172,7 @@ private:
|
||||||
bool evaluatePending() const { return _evaluatesPending > 0; }
|
bool evaluatePending() const { return _evaluatesPending > 0; }
|
||||||
void timerFired();
|
void timerFired();
|
||||||
void stopAllTimers();
|
void stopAllTimers();
|
||||||
|
void refreshFileScript(const EntityItemID& entityID);
|
||||||
|
|
||||||
void setParentURL(const QString& parentURL) { _parentURL = parentURL; }
|
void setParentURL(const QString& parentURL) { _parentURL = parentURL; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue