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 | #include <QtCore/QCoreApplication> | 12 | #include <QtCore/QCoreApplication> |
| 13 | #include <QtCore/QEventLoop> | 13 | #include <QtCore/QEventLoop> |
| 14 | #include <QtCore/QFileInfo> | ||
| 14 | #include <QtCore/QTimer> | 15 | #include <QtCore/QTimer> |
| 15 | #include <QtCore/QThread> | 16 | #include <QtCore/QThread> |
| 16 | #include <QtNetwork/QNetworkRequest> | 17 | #include <QtNetwork/QNetworkRequest> |
| 17 | #include <QtNetwork/QNetworkReply> | 18 | #include <QtNetwork/QNetworkReply> |
| 18 | #include <QScriptEngine> | 19 | #include <QtScript/QScriptEngine> |
| 19 | #include <QScriptValue> | 20 | #include <QtScript/QScriptValue> |
| 20 | 21 | ||
| 21 | #include <AudioConstants.h> | 22 | #include <AudioConstants.h> |
| 22 | #include <AudioEffectOptions.h> | 23 | #include <AudioEffectOptions.h> |
| @@ -942,6 +943,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 919 unmodified lines | |||
| 942 | #endif | 943 | #endif |
| 943 | 944 | ||
| 944 | auto scriptCache = DependencyManager::get<ScriptCache>(); | 945 | auto scriptCache = DependencyManager::get<ScriptCache>(); |
| 946 | bool isFileUrl = isURL && scriptOrURL.startsWith("file://"); | ||
| 945 | 947 | ||
| 946 | // first check the syntax of the script contents | 948 | // first check the syntax of the script contents |
| 947 | QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents); | 949 | QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents); |
| @@ -950,7 +952,9 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 2 unmodified lines | |||
| 950 | qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":" | 952 | qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":" |
| 951 | << syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber(); | 953 | << syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber(); |
| 952 | qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL; | 954 | qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL; |
| 953 | scriptCache->addScriptToBadScriptList(scriptOrURL); | 955 | if (!isFileUrl) { |
| 956 | scriptCache->addScriptToBadScriptList(scriptOrURL); | ||
| 957 | } | ||
| 954 | return; // done processing script | 958 | return; // done processing script |
| 955 | } | 959 | } |
| 956 | 960 | ||
| @@ -965,14 +969,21 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 8 unmodified lines | |||
| 965 | qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID; | 969 | qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID; |
| 966 | qCDebug(scriptengine) << " NOT CONSTRUCTOR"; | 970 | qCDebug(scriptengine) << " NOT CONSTRUCTOR"; |
| 967 | qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL; | 971 | qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL; |
| 968 | scriptCache->addScriptToBadScriptList(scriptOrURL); | 972 | if (!isFileUrl) { |
| 973 | scriptCache->addScriptToBadScriptList(scriptOrURL); | ||
| 974 | } | ||
| 969 | return; // done processing script | 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 | QScriptValue entityScriptObject = entityScriptConstructor.construct(); | 985 | QScriptValue entityScriptObject = entityScriptConstructor.construct(); |
| 975 | EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject }; | 986 | EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified }; |
| 976 | _entityScripts[entityID] = newDetails; | 987 | _entityScripts[entityID] = newDetails; |
| 977 | if (isURL) { | 988 | if (isURL) { |
| 978 | setParentURL(""); | 989 | setParentURL(""); |
| @@ -1022,6 +1033,41 @@ void ScriptEngine::unloadAllEntityScripts() { · 43 unmodified lines | |||
| 1022 | _entityScripts.clear(); | 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 | void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName) { | 1071 | void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName) { |
| 1026 | if (QThread::currentThread() != thread()) { | 1072 | if (QThread::currentThread() != thread()) { |
| 1027 | #ifdef THREAD_DEBUGGING | 1073 | #ifdef THREAD_DEBUGGING |
| @@ -1039,6 +1085,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 11 unmodified lines | |||
| 1039 | "entityID:" << entityID << "methodName:" << methodName; | 1085 | "entityID:" << entityID << "methodName:" << methodName; |
| 1040 | #endif | 1086 | #endif |
| 1041 | 1087 | ||
| 1088 | refreshFileScript(entityID); | ||
| 1042 | if (_entityScripts.contains(entityID)) { | 1089 | if (_entityScripts.contains(entityID)) { |
| 1043 | EntityScriptDetails details = _entityScripts[entityID]; | 1090 | EntityScriptDetails details = _entityScripts[entityID]; |
| 1044 | QScriptValue entityScript = details.scriptObject; // previously loaded | 1091 | QScriptValue entityScript = details.scriptObject; // previously loaded |
| @@ -1069,6 +1116,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 24 unmodified lines | |||
| 1069 | "entityID:" << entityID << "methodName:" << methodName << "event: mouseEvent"; | 1116 | "entityID:" << entityID << "methodName:" << methodName << "event: mouseEvent"; |
| 1070 | #endif | 1117 | #endif |
| 1071 | 1118 | ||
| 1119 | refreshFileScript(entityID); | ||
| 1072 | if (_entityScripts.contains(entityID)) { | 1120 | if (_entityScripts.contains(entityID)) { |
| 1073 | EntityScriptDetails details = _entityScripts[entityID]; | 1121 | EntityScriptDetails details = _entityScripts[entityID]; |
| 1074 | QScriptValue entityScript = details.scriptObject; // previously loaded | 1122 | QScriptValue entityScript = details.scriptObject; // previously loaded |
| @@ -1101,6 +1149,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 26 unmodified lines | |||
| 1101 | "entityID:" << entityID << "methodName:" << methodName << "otherID:" << otherID << "collision: collision"; | 1149 | "entityID:" << entityID << "methodName:" << methodName << "otherID:" << otherID << "collision: collision"; |
| 1102 | #endif | 1150 | #endif |
| 1103 | 1151 | ||
| 1152 | refreshFileScript(entityID); | ||
| 1104 | if (_entityScripts.contains(entityID)) { | 1153 | if (_entityScripts.contains(entityID)) { |
| 1105 | EntityScriptDetails details = _entityScripts[entityID]; | 1154 | EntityScriptDetails details = _entityScripts[entityID]; |
| 1106 | QScriptValue entityScript = details.scriptObject; // previously loaded | 1155 | QScriptValue entityScript = details.scriptObject; // previously loaded |