Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 4 files). Show all
Unified · Split
| @@ -135,16 +135,31 @@ void ScriptEngine::stopAllScripts(QObject* application) { · 134 unmodified lines | |||
| 135 | // complete. After that we can handle the stop process appropriately | 135 | // complete. After that we can handle the stop process appropriately |
| 136 | if (scriptEngine->evaluatePending()) { | 136 | if (scriptEngine->evaluatePending()) { |
| 137 | while (scriptEngine->evaluatePending()) { | 137 | while (scriptEngine->evaluatePending()) { |
| 138 | |||
| 139 | // This event loop allows any started, but not yet finished evaluate() calls to complete | ||
| 140 | // we need to let these complete so that we can be guaranteed that the script engine isn't | ||
| 141 | // in a partially setup state, which can confuse our shutdown unwinding. | ||
| 138 | QEventLoop loop; | 142 | QEventLoop loop; |
| 139 | QObject::connect(scriptEngine, &ScriptEngine::evaluationFinished, &loop, &QEventLoop::quit); | 143 | QObject::connect(scriptEngine, &ScriptEngine::evaluationFinished, &loop, &QEventLoop::quit); |
| 140 | loop.exec(); | 144 | loop.exec(); |
| 141 | } | 145 | } |
| 142 | } | 146 | } |
| 143 | 147 | ||
| 148 | // We disconnect any script engine signals from the application because we don't want to do any | ||
| 149 | // extra stopScript/loadScript processing that the Application normally does when scripts start | ||
| 150 | // and stop. We can safely short circuit this because we know we're in the "quitting" process | ||
| 144 | scriptEngine->disconnect(application); | 151 | scriptEngine->disconnect(application); |
| 152 | |||
| 153 | // Calling stop on the script engine will set it's internal _isFinished state to true, and result | ||
| 154 | // in the ScriptEngine gracefully ending it's run() method. | ||
| 145 | scriptEngine->stop(); | 155 | scriptEngine->stop(); |
| 146 | 156 | ||
| 157 | // We need to wait for the engine to be done running before we proceed, because we don't | ||
| 158 | // want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing | ||
| 159 | // any application state after we leave this stopAllScripts() method | ||
| 147 | scriptEngine->waitTillDoneRunning(); | 160 | scriptEngine->waitTillDoneRunning(); |
| 161 | |||
| 162 | // If the script is stopped, we can remove it from our set | ||
| 148 | i.remove(); | 163 | i.remove(); |
| 149 | } | 164 | } |
| 150 | } | 165 | } |
| @@ -156,10 +171,11 @@ void ScriptEngine::stopAllScripts(QObject* application) { · 5 unmodified lines | |||
| 156 | void ScriptEngine::waitTillDoneRunning() { | 171 | void ScriptEngine::waitTillDoneRunning() { |
| 157 | QString scriptName = getFilename(); | 172 | QString scriptName = getFilename(); |
| 158 | 173 | ||
| 174 | // If the script never started running or finished running before we got here, we don't need to wait for it | ||
| 159 | if (_isRunning) { | 175 | if (_isRunning) { |
| 160 | _doneRunningThisScript = false; | ||
| 161 | _isWaitingForDoneRunning = true; | ||
| 162 | 176 | ||
| 177 | _doneRunningThisScript = false; // NOTE: this is static, we serialize our waiting for scripts to finish | ||
| 178 | |||
| 163 | // What can we do here??? | 179 | // What can we do here??? |
| 164 | // we will be calling this on the main Application thread, inside of stopAllScripts() | 180 | // we will be calling this on the main Application thread, inside of stopAllScripts() |
| 165 | // we want the application thread to continue to process events, because the script will | 181 | // we want the application thread to continue to process events, because the script will |
| @@ -178,8 +194,6 @@ void ScriptEngine::waitTillDoneRunning() { · 12 unmodified lines | |||
| 178 | break; | 194 | break; |
| 179 | } | 195 | } |
| 180 | } | 196 | } |
| 181 | |||
| 182 | _isWaitingForDoneRunning = false; | ||
| 183 | } | 197 | } |
| 184 | } | 198 | } |
| 185 | 199 | ||