diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 7643e446ec..d7f9f1343b 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -88,16 +88,13 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() { public: WaitRunnable(ScriptEngine* engine) : _engine(engine) {} virtual void run() override { - _engine->wait(); + _engine->waitTillDoneRunning(); _engine->deleteLater(); } private: ScriptEngine* _engine; }; - - engine->unloadAllEntityScripts(); - engine->stop(); // Wait for the scripting thread from the thread pool to avoid hanging the main thread QThreadPool::globalInstance()->start(new WaitRunnable(engine)); }); @@ -110,6 +107,13 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() { void EntityTreeRenderer::clear() { leaveAllEntities(); + if (_entitiesScriptEngine) { + // Unload and stop the engine here (instead of in its deleter) to + // avoid marshalling unload signals back to this thread + _entitiesScriptEngine->unloadAllEntityScripts(); + _entitiesScriptEngine->stop(); + } + if (_wantScripts && !_shuttingDown) { resetEntitiesScriptEngine(); } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 6ed7f7f684..843d714973 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -284,7 +284,7 @@ void ScriptEngine::runInThread() { workerThread->start(); } -void ScriptEngine::wait() { +void ScriptEngine::waitTillDoneRunning() { auto workerThread = thread(); if (_isThreaded && workerThread) { @@ -303,8 +303,9 @@ void ScriptEngine::wait() { // Process events for the main application thread, allowing invokeMethod calls to pass between threads. QCoreApplication::processEvents(); - // If the final evaluation takes too long, then tell the script engine to stop evaluating + // If the final evaluation takes too long, then tell the script engine to stop running auto elapsedUsecs = usecTimestampNow() - startedWaiting; + static const auto MAX_SCRIPT_EVALUATION_TIME = USECS_PER_SECOND; if (elapsedUsecs > MAX_SCRIPT_EVALUATION_TIME) { workerThread->quit(); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index b107e741f4..789958d57a 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -67,10 +67,7 @@ public: class ScriptEngine : public QScriptEngine, public ScriptUser, public EntitiesScriptEngineProvider { Q_OBJECT public: - static const auto MAX_SCRIPT_EVALUATION_TIME = USECS_PER_SECOND; - ScriptEngine(const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString("")); - ~ScriptEngine(); /// run the script in a dedicated thread. This will have the side effect of evalulating @@ -88,7 +85,7 @@ public: Q_INVOKABLE void stop(); // Stop any evaluating scripts and wait for the scripting thread to finish. - void wait(); + void waitTillDoneRunning(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - these are NOT intended to be public interfaces available to scripts, the are only Q_INVOKABLE so we can @@ -169,7 +166,6 @@ public: public slots: void callAnimationStateHandler(QScriptValue callback, AnimVariantMap parameters, QStringList names, bool useNames, AnimVariantResultHandler resultHandler); void updateMemoryCost(const qint64&); - void abort() { abortEvaluation(); } signals: void scriptLoaded(const QString& scriptFilename); diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 6e7c2bb839..b31c7ac07b 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -158,9 +158,6 @@ void ScriptEngines::shutdownScripting() { // and stop. We can safely short circuit this because we know we're in the "quitting" process scriptEngine->disconnect(this); - // If this is an entity script, we need to unload any entities - scriptEngine->unloadAllEntityScripts(); - // Gracefully stop the engine's scripting thread scriptEngine->stop(); @@ -168,7 +165,7 @@ void ScriptEngines::shutdownScripting() { // want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing // any application state after we leave this stopAllScripts() method qCDebug(scriptengine) << "waiting on script:" << scriptName; - scriptEngine->wait(); + scriptEngine->waitTillDoneRunning(); qCDebug(scriptengine) << "done waiting on script:" << scriptName; scriptEngine->deleteLater();