Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 2 files). Show all
Unified · Split
| @@ -11,12 +11,13 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #include <QtCore/QCoreApplication> |
| 13 | 13 | #include <QtCore/QEventLoop> |
| 14 | +#include <QtCore/QFileInfo> | |
| 14 | 15 | #include <QtCore/QTimer> |
| 15 | 16 | #include <QtCore/QThread> |
| 16 | 17 | #include <QtNetwork/QNetworkRequest> |
| 17 | 18 | #include <QtNetwork/QNetworkReply> |
| 18 | −#include <QScriptEngine> | |
| 19 | −#include <QScriptValue> | |
| 19 | +#include <QtScript/QScriptEngine> | |
| 20 | +#include <QtScript/QScriptValue> | |
| 20 | 21 | |
| 21 | 22 | #include <AudioConstants.h> |
| 22 | 23 | #include <AudioEffectOptions.h> |
| @@ -942,6 +943,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 919 unmodified lines | ||
| 942 | 943 | #endif |
| 943 | 944 | |
| 944 | 945 | auto scriptCache = DependencyManager::get<ScriptCache>(); |
| 946 | + bool isFileUrl = isURL && scriptOrURL.startsWith("file://"); | |
| 945 | 947 | |
| 946 | 948 | // first check the syntax of the script contents |
| 947 | 949 | QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents); |
| @@ -950,7 +952,9 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 2 unmodified lines | ||
| 950 | 952 | qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":" |
| 951 | 953 | << syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber(); |
| 952 | 954 | qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL; |
| 953 | − scriptCache->addScriptToBadScriptList(scriptOrURL); | |
| 955 | + if (!isFileUrl) { | |
| 956 | + scriptCache->addScriptToBadScriptList(scriptOrURL); | |
| 957 | + } | |
| 954 | 958 | return; // done processing script |
| 955 | 959 | } |
| 956 | 960 | |
| @@ -965,14 +969,21 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 8 unmodified lines | ||
| 965 | 969 | qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID; |
| 966 | 970 | qCDebug(scriptengine) << " NOT CONSTRUCTOR"; |
| 967 | 971 | qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL; |
| 968 | − scriptCache->addScriptToBadScriptList(scriptOrURL); | |
| 972 | + if (!isFileUrl) { | |
| 973 | + scriptCache->addScriptToBadScriptList(scriptOrURL); | |
| 974 | + } | |
| 969 | 975 | return; // done processing script |
| 970 | 976 | } |
| 971 | 977 | |
| 972 | − QScriptValue entityScriptConstructor = evaluate(contents); | |
| 978 | + int64_t lastModified = 0; | |
| 979 | + if (isFileUrl) { | |
| 980 | + QString file = QUrl(scriptOrURL).toLocalFile(); | |
| 981 | + lastModified = (quint64)QFileInfo(file).lastModified().toMSecsSinceEpoch(); | |
| 982 | + } | |
| 973 | 983 | |
| 984 | + QScriptValue entityScriptConstructor = evaluate(contents); | |
| 974 | 985 | QScriptValue entityScriptObject = entityScriptConstructor.construct(); |
| 975 | − EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject }; | |
| 986 | + EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified }; | |
| 976 | 987 | _entityScripts[entityID] = newDetails; |
| 977 | 988 | if (isURL) { |
| 978 | 989 | setParentURL(""); |
| @@ -1022,6 +1033,41 @@ void ScriptEngine::unloadAllEntityScripts() { · 43 unmodified lines | ||
| 1022 | 1033 | _entityScripts.clear(); |
| 1023 | 1034 | } |
| 1024 | 1035 | |
| 1036 | +void ScriptEngine::refreshFileScript(const EntityItemID& entityID) { | |
| 1037 | + if (!_entityScripts.contains(entityID)) { | |
| 1038 | + return; | |
| 1039 | + } | |
| 1040 | + | |
| 1041 | + static bool recurseGuard = false; | |
| 1042 | + if (recurseGuard) { | |
| 1043 | + return; | |
| 1044 | + } | |
| 1045 | + recurseGuard = true; | |
| 1046 | + | |
| 1047 | + EntityScriptDetails details = _entityScripts[entityID]; | |
| 1048 | + // Check to see if a file based script needs to be reloaded (easier debugging) | |
| 1049 | + if (details.lastModified > 0) { | |
| 1050 | + QString filePath = QUrl(details.scriptText).toLocalFile(); | |
| 1051 | + auto lastModified = QFileInfo(filePath).lastModified().toMSecsSinceEpoch(); | |
| 1052 | + if (lastModified > details.lastModified) { | |
| 1053 | + qDebug() << "Reloading modified script " << details.scriptText; | |
| 1054 | + | |
| 1055 | + QFile file(filePath); | |
| 1056 | + file.open(QIODevice::ReadOnly); | |
| 1057 | + QString scriptContents = QTextStream(&file).readAll(); | |
| 1058 | + this->unloadEntityScript(entityID); | |
| 1059 | + this->entityScriptContentAvailable(entityID, details.scriptText, scriptContents, true, true); | |
| 1060 | + if (!_entityScripts.contains(entityID)) { | |
| 1061 | + qWarning() << "Reload script " << details.scriptText << " failed"; | |
| 1062 | + } else { | |
| 1063 | + details = _entityScripts[entityID]; | |
| 1064 | + } | |
| 1065 | + } | |
| 1066 | + } | |
| 1067 | + recurseGuard = false; | |
| 1068 | +} | |
| 1069 | + | |
| 1070 | + | |
| 1025 | 1071 | void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName) { |
| 1026 | 1072 | if (QThread::currentThread() != thread()) { |
| 1027 | 1073 | #ifdef THREAD_DEBUGGING |
| @@ -1039,6 +1085,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 11 unmodified lines | ||
| 1039 | 1085 | "entityID:" << entityID << "methodName:" << methodName; |
| 1040 | 1086 | #endif |
| 1041 | 1087 | |
| 1088 | + refreshFileScript(entityID); | |
| 1042 | 1089 | if (_entityScripts.contains(entityID)) { |
| 1043 | 1090 | EntityScriptDetails details = _entityScripts[entityID]; |
| 1044 | 1091 | QScriptValue entityScript = details.scriptObject; // previously loaded |
| @@ -1069,6 +1116,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 24 unmodified lines | ||
| 1069 | 1116 | "entityID:" << entityID << "methodName:" << methodName << "event: mouseEvent"; |
| 1070 | 1117 | #endif |
| 1071 | 1118 | |
| 1119 | + refreshFileScript(entityID); | |
| 1072 | 1120 | if (_entityScripts.contains(entityID)) { |
| 1073 | 1121 | EntityScriptDetails details = _entityScripts[entityID]; |
| 1074 | 1122 | QScriptValue entityScript = details.scriptObject; // previously loaded |
| @@ -1101,6 +1149,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 26 unmodified lines | ||
| 1101 | 1149 | "entityID:" << entityID << "methodName:" << methodName << "otherID:" << otherID << "collision: collision"; |
| 1102 | 1150 | #endif |
| 1103 | 1151 | |
| 1152 | + refreshFileScript(entityID); | |
| 1104 | 1153 | if (_entityScripts.contains(entityID)) { |
| 1105 | 1154 | EntityScriptDetails details = _entityScripts[entityID]; |
| 1106 | 1155 | QScriptValue entityScript = details.scriptObject; // previously loaded |