Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 783 files). Show all
Unified · Split
| @@ -24,6 +24,8 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #include <QtWidgets/QMainWindow> |
| 26 | 26 | #include <QtWidgets/QApplication> |
| 27 | +#include <QtWidgets/QMenuBar> | |
| 28 | +#include <QtWidgets/QMenu> | |
| 27 | 29 | |
| 28 | 30 | #include <QtNetwork/QNetworkRequest> |
| 29 | 31 | #include <QtNetwork/QNetworkReply> |
| @@ -34,6 +36,7 @@ · 4 unmodified lines | ||
| 34 | 36 | |
| 35 | 37 | #include <QtScriptTools/QScriptEngineDebugger> |
| 36 | 38 | |
| 39 | +#include <shared/QtHelpers.h> | |
| 37 | 40 | #include <AudioConstants.h> |
| 38 | 41 | #include <AudioEffectOptions.h> |
| 39 | 42 | #include <AvatarData.h> |
| @@ -48,7 +51,6 @@ · 8 unmodified lines | ||
| 48 | 51 | #include <ScriptAvatarData.h> |
| 49 | 52 | #include <udt/PacketHeaders.h> |
| 50 | 53 | #include <UUID.h> |
| 51 | −#include <ui/Menu.h> | |
| 52 | 54 | |
| 53 | 55 | #include <controllers/ScriptingInterface.h> |
| 54 | 56 | #include <AnimationObject.h> |
| @@ -70,7 +72,6 @@ · 15 unmodified lines | ||
| 70 | 72 | #include "WebSocketClass.h" |
| 71 | 73 | #include "RecordingScriptingInterface.h" |
| 72 | 74 | #include "ScriptEngines.h" |
| 73 | −#include "TabletScriptingInterface.h" | |
| 74 | 75 | #include "ModelScriptingInterface.h" |
| 75 | 76 | |
| 76 | 77 | |
| @@ -173,7 +174,7 @@ ScriptEngine::ScriptEngine(Context context, const QString& scriptContents, const · 96 unmodified lines | ||
| 173 | 174 | emit unhandledException(exception); |
| 174 | 175 | } |
| 175 | 176 | }, Qt::DirectConnection); |
| 176 | − | |
| 177 | + | |
| 177 | 178 | setProcessEventsInterval(MSECS_PER_SECOND); |
| 178 | 179 | if (isEntityServerScript()) { |
| 179 | 180 | qCDebug(scriptengine) << "isEntityServerScript() -- limiting maxRetries to 1"; |
| @@ -282,7 +283,7 @@ void ScriptEngine::runDebuggable() { · 102 unmodified lines | ||
| 282 | 283 | scriptDebugMenu = nullptr; |
| 283 | 284 | } |
| 284 | 285 | } |
| 285 | − disconnect(timer); | |
| 286 | + disconnect(timer); | |
| 286 | 287 | }); |
| 287 | 288 | |
| 288 | 289 | connect(timer, &QTimer::timeout, [this, timer] { |
| @@ -341,7 +342,7 @@ void ScriptEngine::runInThread() { · 52 unmodified lines | ||
| 341 | 342 | QThread* workerThread = new QThread(); |
| 342 | 343 | workerThread->setObjectName(QString("js:") + getFilename().replace("about:","")); |
| 343 | 344 | moveToThread(workerThread); |
| 344 | − | |
| 345 | + | |
| 345 | 346 | // NOTE: If you connect any essential signals for proper shutdown or cleanup of |
| 346 | 347 | // the script engine, make sure to add code to "reconnect" them to the |
| 347 | 348 | // disconnectNonEssentialSignals() method |
| @@ -437,12 +438,12 @@ void ScriptEngine::loadURL(const QUrl& scriptURL, bool reload) { · 89 unmodified lines | ||
| 437 | 438 | _fileNameString = url.toString(); |
| 438 | 439 | _isReloading = reload; |
| 439 | 440 | |
| 440 | − // Check that script has a supported file extension | |
| 441 | + // Check that script has a supported file extension | |
| 441 | 442 | if (!hasValidScriptSuffix(_fileNameString)) { |
| 442 | 443 | scriptErrorMessage("File extension of file: " + _fileNameString + " is not a currently supported script type"); |
| 443 | 444 | emit errorLoadingScript(_fileNameString); |
| 444 | 445 | return; |
| 445 | − } | |
| 446 | + } | |
| 446 | 447 | |
| 447 | 448 | const auto maxRetries = 0; // for consistency with previous scriptCache->getScript() behavior |
| 448 | 449 | auto scriptCache = DependencyManager::get<ScriptCache>(); |
| @@ -473,20 +474,24 @@ void ScriptEngine::scriptErrorMessage(const QString& message) { · 24 unmodified lines | ||
| 473 | 474 | } |
| 474 | 475 | |
| 475 | 476 | void ScriptEngine::scriptWarningMessage(const QString& message) { |
| 476 | − qCWarning(scriptengine) << message; | |
| 477 | + qCWarning(scriptengine) << qPrintable(message); | |
| 477 | 478 | emit warningMessage(message, getFilename()); |
| 478 | 479 | } |
| 479 | 480 | |
| 480 | 481 | void ScriptEngine::scriptInfoMessage(const QString& message) { |
| 481 | − qCInfo(scriptengine) << message; | |
| 482 | + qCInfo(scriptengine) << qPrintable(message); | |
| 482 | 483 | emit infoMessage(message, getFilename()); |
| 483 | 484 | } |
| 484 | 485 | |
| 485 | 486 | void ScriptEngine::scriptPrintedMessage(const QString& message) { |
| 486 | − qCDebug(scriptengine) << message; | |
| 487 | + qCDebug(scriptengine) << qPrintable(message); | |
| 487 | 488 | emit printedMessage(message, getFilename()); |
| 488 | 489 | } |
| 489 | 490 | |
| 491 | +void ScriptEngine::clearDebugLogWindow() { | |
| 492 | + emit clearDebugWindow(); | |
| 493 | +} | |
| 494 | + | |
| 490 | 495 | // Even though we never pass AnimVariantMap directly to and from javascript, the queued invokeMethod of |
| 491 | 496 | // callAnimationStateHandler requires that the type be registered. |
| 492 | 497 | // These two are meaningful, if we ever do want to use them... |
| @@ -671,8 +676,18 @@ void ScriptEngine::init() { · 178 unmodified lines | ||
| 671 | 676 | registerGlobalObject("Mat4", &_mat4Library); |
| 672 | 677 | registerGlobalObject("Uuid", &_uuidLibrary); |
| 673 | 678 | registerGlobalObject("Messages", DependencyManager::get<MessagesClient>().data()); |
| 674 | − | |
| 675 | 679 | registerGlobalObject("File", new FileScriptingInterface(this)); |
| 680 | + registerGlobalObject("console", &_consoleScriptingInterface); | |
| 681 | + registerFunction("console", "info", ConsoleScriptingInterface::info, currentContext()->argumentCount()); | |
| 682 | + registerFunction("console", "log", ConsoleScriptingInterface::log, currentContext()->argumentCount()); | |
| 683 | + registerFunction("console", "debug", ConsoleScriptingInterface::debug, currentContext()->argumentCount()); | |
| 684 | + registerFunction("console", "warn", ConsoleScriptingInterface::warn, currentContext()->argumentCount()); | |
| 685 | + registerFunction("console", "error", ConsoleScriptingInterface::error, currentContext()->argumentCount()); | |
| 686 | + registerFunction("console", "exception", ConsoleScriptingInterface::exception, currentContext()->argumentCount()); | |
| 687 | + registerFunction("console", "assert", ConsoleScriptingInterface::assertion, currentContext()->argumentCount()); | |
| 688 | + registerFunction("console", "group", ConsoleScriptingInterface::group, 1); | |
| 689 | + registerFunction("console", "groupCollapsed", ConsoleScriptingInterface::groupCollapsed, 1); | |
| 690 | + registerFunction("console", "groupEnd", ConsoleScriptingInterface::groupEnd, 0); | |
| 676 | 691 | |
| 677 | 692 | qScriptRegisterMetaType(this, animVarMapToScriptValue, animVarMapFromScriptValue); |
| 678 | 693 | qScriptRegisterMetaType(this, resultHandlerToScriptValue, resultHandlerFromScriptValue); |
| @@ -686,8 +701,6 @@ void ScriptEngine::init() { · 7 unmodified lines | ||
| 686 | 701 | // constants |
| 687 | 702 | globalObject().setProperty("TREE_SCALE", newVariant(QVariant(TREE_SCALE))); |
| 688 | 703 | |
| 689 | − registerGlobalObject("Tablet", DependencyManager::get<TabletScriptingInterface>().data()); | |
| 690 | − qScriptRegisterMetaType(this, tabletToScriptValue, tabletFromScriptValue); | |
| 691 | 704 | registerGlobalObject("Assets", &_assetScriptingInterface); |
| 692 | 705 | registerGlobalObject("Resources", DependencyManager::get<ResourceScriptingInterface>().data()); |
| 693 | 706 | |
| @@ -955,7 +968,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi · 261 unmodified lines | ||
| 955 | 968 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::evaluate() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] " |
| 956 | 969 | "sourceCode:" << sourceCode << " fileName:" << fileName << "lineNumber:" << lineNumber; |
| 957 | 970 | #endif |
| 958 | − QMetaObject::invokeMethod(this, "evaluate", Qt::BlockingQueuedConnection, | |
| 971 | + BLOCKING_INVOKE_METHOD(this, "evaluate", | |
| 959 | 972 | Q_RETURN_ARG(QScriptValue, result), |
| 960 | 973 | Q_ARG(const QString&, sourceCode), |
| 961 | 974 | Q_ARG(const QString&, fileName), |
| @@ -1009,6 +1022,7 @@ void ScriptEngine::run() { · 47 unmodified lines | ||
| 1009 | 1022 | emit runningStateChanged(); |
| 1010 | 1023 | |
| 1011 | 1024 | { |
| 1025 | + PROFILE_RANGE(script, _fileNameString); | |
| 1012 | 1026 | evaluate(_scriptContents, _fileNameString); |
| 1013 | 1027 | maybeEmitUncaughtException(__FUNCTION__); |
| 1014 | 1028 | } |
| @@ -1035,46 +1049,43 @@ void ScriptEngine::run() { · 20 unmodified lines | ||
| 1035 | 1049 | auto beforeSleep = clock::now(); |
| 1036 | 1050 | |
| 1037 | 1051 | // Throttle to SCRIPT_FPS |
| 1038 | − // We'd like to try to keep the script at a solid SCRIPT_FPS update rate. And so we will | |
| 1052 | + // We'd like to try to keep the script at a solid SCRIPT_FPS update rate. And so we will | |
| 1039 | 1053 | // calculate a sleepUntil to be the time from our start time until the original target |
| 1040 | − // sleepUntil for this frame. This approach will allow us to "catch up" in the event | |
| 1041 | − // that some of our script udpates/frames take a little bit longer than the target average | |
| 1054 | + // sleepUntil for this frame. This approach will allow us to "catch up" in the event | |
| 1055 | + // that some of our script udpates/frames take a little bit longer than the target average | |
| 1042 | 1056 | // to execute. |
| 1043 | 1057 | // NOTE: if we go to variable SCRIPT_FPS, then we will need to reconsider this approach |
| 1044 | 1058 | const std::chrono::microseconds TARGET_SCRIPT_FRAME_DURATION(USECS_PER_SECOND / SCRIPT_FPS + 1); |
| 1045 | 1059 | clock::time_point targetSleepUntil(startTime + (thisFrame++ * TARGET_SCRIPT_FRAME_DURATION)); |
| 1046 | 1060 | |
| 1047 | − // However, if our sleepUntil is not at least our average update and timer execution time | |
| 1048 | − // into the future it means our script is taking too long in its updates, and we want to | |
| 1049 | − // punish the script a little bit. So we will force the sleepUntil to be at least our | |
| 1061 | + // However, if our sleepUntil is not at least our average update and timer execution time | |
| 1062 | + // into the future it means our script is taking too long in its updates, and we want to | |
| 1063 | + // punish the script a little bit. So we will force the sleepUntil to be at least our | |
| 1050 | 1064 | // averageUpdate + averageTimerPerFrame time into the future. |
| 1051 | 1065 | auto averageUpdate = totalUpdates / thisFrame; |
| 1052 | 1066 | auto averageTimerPerFrame = _totalTimerExecution / thisFrame; |
| 1053 | 1067 | auto averageTimerAndUpdate = averageUpdate + averageTimerPerFrame; |
| 1054 | 1068 | auto sleepUntil = std::max(targetSleepUntil, beforeSleep + averageTimerAndUpdate); |
| 1055 | 1069 | |
| 1056 | − // We don't want to actually sleep for too long, because it causes our scripts to hang | |
| 1057 | − // on shutdown and stop... so we want to loop and sleep until we've spent our time in | |
| 1070 | + // We don't want to actually sleep for too long, because it causes our scripts to hang | |
| 1071 | + // on shutdown and stop... so we want to loop and sleep until we've spent our time in | |
| 1058 | 1072 | // purgatory, constantly checking to see if our script was asked to end |
| 1059 | 1073 | bool processedEvents = false; |
| 1060 | − while (!_isFinished && clock::now() < sleepUntil) { | |
| 1061 | − | |
| 1062 | − { | |
| 1063 | − PROFILE_RANGE(script, "processEvents-sleep"); | |
| 1064 | − QCoreApplication::processEvents(); // before we sleep again, give events a chance to process | |
| 1074 | + if (!_isFinished) { | |
| 1075 | + PROFILE_RANGE(script, "processEvents-sleep"); | |
| 1076 | + std::chrono::milliseconds sleepFor = | |
| 1077 | + std::chrono::duration_cast<std::chrono::milliseconds>(sleepUntil - clock::now()); | |
| 1078 | + if (sleepFor > std::chrono::milliseconds(0)) { | |
| 1079 | + QEventLoop loop; | |
| 1080 | + QTimer timer; | |
| 1081 | + timer.setSingleShot(true); | |
| 1082 | + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); | |
| 1083 | + timer.start(sleepFor.count()); | |
| 1084 | + loop.exec(); | |
| 1085 | + } else { | |
| 1086 | + QCoreApplication::processEvents(); | |
| 1065 | 1087 | } |
| 1066 | 1088 | processedEvents = true; |
| 1067 | − | |
| 1068 | − // If after processing events, we're past due, exit asap | |
| 1069 | − if (clock::now() >= sleepUntil) { | |
| 1070 | − break; | |
| 1071 | − } | |
| 1072 | − | |
| 1073 | − // We only want to sleep a small amount so that any pending events (like timers or invokeMethod events) | |
| 1074 | − // will be able to process quickly. | |
| 1075 | − static const int SMALL_SLEEP_AMOUNT = 100; | |
| 1076 | − auto smallSleepUntil = clock::now() + static_cast<std::chrono::microseconds>(SMALL_SLEEP_AMOUNT); | |
| 1077 | − std::this_thread::sleep_until(smallSleepUntil); | |
| 1078 | 1089 | } |
| 1079 | 1090 | |
| 1080 | 1091 | PROFILE_RANGE(script, "ScriptMainLoop"); |
| @@ -1272,6 +1283,7 @@ void ScriptEngine::timerFired() { · 191 unmodified lines | ||
| 1272 | 1283 | |
| 1273 | 1284 | // call the associated JS function, if it exists |
| 1274 | 1285 | if (timerData.function.isValid()) { |
| 1286 | + PROFILE_RANGE(script, __FUNCTION__); | |
| 1275 | 1287 | auto preTimer = p_high_resolution_clock::now(); |
| 1276 | 1288 | callWithEnvironment(timerData.definingEntityIdentifier, timerData.definingSandboxURL, timerData.function, timerData.function, QScriptValueList()); |
| 1277 | 1289 | auto postTimer = p_high_resolution_clock::now(); |
| @@ -1298,6 +1310,7 @@ QObject* ScriptEngine::setupTimerWithInterval(const QScriptValue& function, int · 20 unmodified lines | ||
| 1298 | 1310 | // make sure the timer stops when the script does |
| 1299 | 1311 | connect(this, &ScriptEngine::scriptEnding, newTimer, &QTimer::stop); |
| 1300 | 1312 | |
| 1313 | + | |
| 1301 | 1314 | CallbackData timerData = { function, currentEntityIdentifier, currentSandboxURL }; |
| 1302 | 1315 | _timerFunctionMap.insert(newTimer, timerData); |
| 1303 | 1316 | |
| @@ -1381,12 +1394,21 @@ void ScriptEngine::print(const QString& message) { · 77 unmodified lines | ||
| 1381 | 1394 | emit printedMessage(message, getFilename()); |
| 1382 | 1395 | } |
| 1383 | 1396 | |
| 1397 | + | |
| 1398 | +void ScriptEngine::beginProfileRange(const QString& label) const { | |
| 1399 | + PROFILE_SYNC_BEGIN(script, label.toStdString().c_str(), label.toStdString().c_str()); | |
| 1400 | +} | |
| 1401 | + | |
| 1402 | +void ScriptEngine::endProfileRange(const QString& label) const { | |
| 1403 | + PROFILE_SYNC_END(script, label.toStdString().c_str(), label.toStdString().c_str()); | |
| 1404 | +} | |
| 1405 | + | |
| 1384 | 1406 | // Script.require.resolve -- like resolvePath, but performs more validation and throws exceptions on invalid module identifiers (for consistency with Node.js) |
| 1385 | 1407 | QString ScriptEngine::_requireResolve(const QString& moduleId, const QString& relativeTo) { |
| 1386 | 1408 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { |
| 1387 | 1409 | return QString(); |
| 1388 | 1410 | } |
| 1389 | − QUrl defaultScriptsLoc = defaultScriptsLocation(); | |
| 1411 | + QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation(); | |
| 1390 | 1412 | QUrl url(moduleId); |
| 1391 | 1413 | |
| 1392 | 1414 | auto displayId = moduleId; |
| @@ -1452,7 +1474,7 @@ QString ScriptEngine::_requireResolve(const QString& moduleId, const QString& re · 59 unmodified lines | ||
| 1452 | 1474 | canonical.setPath(file.canonicalFilePath()); |
| 1453 | 1475 | } |
| 1454 | 1476 | |
| 1455 | − bool disallowOutsideFiles = !defaultScriptsLocation().isParentOf(canonical) && !currentSandboxURL.isLocalFile(); | |
| 1477 | + bool disallowOutsideFiles = !PathUtils::defaultScriptsLocation().isParentOf(canonical) && !currentSandboxURL.isLocalFile(); | |
| 1456 | 1478 | if (disallowOutsideFiles && !PathUtils::isDescendantOf(canonical, currentSandboxURL)) { |
| 1457 | 1479 | return throwResolveError(makeError(message.arg( |
| 1458 | 1480 | QString("path '%1' outside of origin script '%2' '%3'") |
| @@ -1737,19 +1759,19 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 278 unmodified lines | ||
| 1737 | 1759 | return; |
| 1738 | 1760 | } |
| 1739 | 1761 | if (DependencyManager::get<ScriptEngines>()->isStopped()) { |
| 1740 | − scriptWarningMessage("Script.include() while shutting down is ignored... includeFiles:" | |
| 1762 | + scriptWarningMessage("Script.include() while shutting down is ignored... includeFiles:" | |
| 1741 | 1763 | + includeFiles.join(",") + "parent script:" + getFilename()); |
| 1742 | 1764 | return; // bail early |
| 1743 | 1765 | } |
| 1744 | 1766 | QList<QUrl> urls; |
| 1745 | 1767 | |
| 1746 | 1768 | for (QString includeFile : includeFiles) { |
| 1747 | − QString file = ResourceManager::normalizeURL(includeFile); | |
| 1769 | + QString file = DependencyManager::get<ResourceManager>()->normalizeURL(includeFile); | |
| 1748 | 1770 | QUrl thisURL; |
| 1749 | 1771 | bool isStandardLibrary = false; |
| 1750 | 1772 | if (file.startsWith("/~/")) { |
| 1751 | 1773 | thisURL = expandScriptUrl(QUrl::fromLocalFile(expandScriptPath(file))); |
| 1752 | − QUrl defaultScriptsLoc = defaultScriptsLocation(); | |
| 1774 | + QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation(); | |
| 1753 | 1775 | if (!defaultScriptsLoc.isParentOf(thisURL)) { |
| 1754 | 1776 | scriptWarningMessage("Script.include() -- skipping" + file + "-- outside of standard libraries"); |
| 1755 | 1777 | continue; |
| @@ -1761,7 +1783,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 5 unmodified lines | ||
| 1761 | 1783 | |
| 1762 | 1784 | bool disallowOutsideFiles = thisURL.isLocalFile() && !isStandardLibrary && !currentSandboxURL.isLocalFile(); |
| 1763 | 1785 | if (disallowOutsideFiles && !PathUtils::isDescendantOf(thisURL, currentSandboxURL)) { |
| 1764 | − scriptWarningMessage("Script.include() ignoring file path" + thisURL.toString() | |
| 1786 | + scriptWarningMessage("Script.include() ignoring file path" + thisURL.toString() | |
| 1765 | 1787 | + "outside of original entity script" + currentSandboxURL.toString()); |
| 1766 | 1788 | } else { |
| 1767 | 1789 | // We could also check here for CORS, but we don't yet. |
| @@ -1802,7 +1824,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 34 unmodified lines | ||
| 1802 | 1824 | clearExceptions(); |
| 1803 | 1825 | } |
| 1804 | 1826 | } else { |
| 1805 | − scriptWarningMessage("Script.include() skipping evaluation of previously included url:" + url.toString()); | |
| 1827 | + scriptPrintedMessage("Script.include() skipping evaluation of previously included url:" + url.toString()); | |
| 1806 | 1828 | } |
| 1807 | 1829 | } |
| 1808 | 1830 | } |
| @@ -1831,7 +1853,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 22 unmodified lines | ||
| 1831 | 1853 | |
| 1832 | 1854 | void ScriptEngine::include(const QString& includeFile, QScriptValue callback) { |
| 1833 | 1855 | if (DependencyManager::get<ScriptEngines>()->isStopped()) { |
| 1834 | − scriptWarningMessage("Script.include() while shutting down is ignored... includeFile:" | |
| 1856 | + scriptWarningMessage("Script.include() while shutting down is ignored... includeFile:" | |
| 1835 | 1857 | + includeFile + "parent script:" + getFilename()); |
| 1836 | 1858 | return; // bail early |
| 1837 | 1859 | } |
| @@ -1849,12 +1871,12 @@ void ScriptEngine::load(const QString& loadFile) { · 11 unmodified lines | ||
| 1849 | 1871 | return; |
| 1850 | 1872 | } |
| 1851 | 1873 | if (DependencyManager::get<ScriptEngines>()->isStopped()) { |
| 1852 | − scriptWarningMessage("Script.load() while shutting down is ignored... loadFile:" | |
| 1874 | + scriptWarningMessage("Script.load() while shutting down is ignored... loadFile:" | |
| 1853 | 1875 | + loadFile + "parent script:" + getFilename()); |
| 1854 | 1876 | return; // bail early |
| 1855 | 1877 | } |
| 1856 | 1878 | if (!currentEntityIdentifier.isInvalidID()) { |
| 1857 | − scriptWarningMessage("Script.load() from entity script is ignored... loadFile:" | |
| 1879 | + scriptWarningMessage("Script.load() from entity script is ignored... loadFile:" | |
| 1858 | 1880 | + loadFile + "parent script:" + getFilename() + "entity: " + currentEntityIdentifier.toString()); |
| 1859 | 1881 | return; // bail early |
| 1860 | 1882 | } |
| @@ -2535,7 +2557,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 674 unmodified lines | ||
| 2535 | 2557 | qCDebug(scriptengine) << "ScriptEngine::callEntityScriptMethod() called on correct thread [" << thread() << "] " |
| 2536 | 2558 | "entityID:" << entityID << "methodName:" << methodName << "otherID:" << otherID << "collision: collision"; |
| 2537 | 2559 | #endif |
| 2538 | − | |
| 2560 | + | |
| 2539 | 2561 | if (HIFI_AUTOREFRESH_FILE_SCRIPTS) { |
| 2540 | 2562 | refreshFileScript(entityID); |
| 2541 | 2563 | } |