Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 20 files). Show all
Unified · Split
| @@ -46,11 +46,13 @@ · 45 unmodified lines | ||
| 46 | 46 | #include "TypedArrays.h" |
| 47 | 47 | #include "XMLHttpRequestClass.h" |
| 48 | 48 | #include "WebSocketClass.h" |
| 49 | − | |
| 50 | 49 | #include "RecordingScriptingInterface.h" |
| 50 | +#include "ScriptEngines.h" | |
| 51 | 51 | |
| 52 | 52 | #include "MIDIEvent.h" |
| 53 | 53 | |
| 54 | +std::atomic<bool> ScriptEngine::_stoppingAllScripts { false }; | |
| 55 | + | |
| 54 | 56 | static const QString SCRIPT_EXCEPTION_FORMAT = "[UncaughtException] %1 in %2:%3"; |
| 55 | 57 | |
| 56 | 58 | Q_DECLARE_METATYPE(QScriptEngine::FunctionSignature) |
| @@ -132,9 +134,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam · 75 unmodified lines | ||
| 132 | 134 | _fileNameString(fileNameString), |
| 133 | 135 | _arrayBufferClass(new ArrayBufferClass(this)) |
| 134 | 136 | { |
| 135 | − _allScriptsMutex.lock(); | |
| 136 | − _allKnownScriptEngines.insert(this); | |
| 137 | − _allScriptsMutex.unlock(); | |
| 137 | + DependencyManager::get<ScriptEngines>()->addScriptEngine(this); | |
| 138 | 138 | |
| 139 | 139 | connect(this, &QScriptEngine::signalHandlerException, this, [this](const QScriptValue& exception) { |
| 140 | 140 | hadUncaughtExceptions(*this, _fileNameString); |
| @@ -144,14 +144,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam · 3 unmodified lines | ||
| 144 | 144 | ScriptEngine::~ScriptEngine() { |
| 145 | 145 | qCDebug(scriptengine) << "Script Engine shutting down (destructor) for script:" << getFilename(); |
| 146 | 146 | |
| 147 | − // If we're not already in the middle of stopping all scripts, then we should remove ourselves | |
| 148 | − // from the list of running scripts. We don't do this if we're in the process of stopping all scripts | |
| 149 | − // because that method removes scripts from its list as it iterates them | |
| 150 | − if (!_stoppingAllScripts) { | |
| 151 | − _allScriptsMutex.lock(); | |
| 152 | − _allKnownScriptEngines.remove(this); | |
| 153 | − _allScriptsMutex.unlock(); | |
| 154 | − } | |
| 147 | + DependencyManager::get<ScriptEngines>()->removeScriptEngine(this); | |
| 155 | 148 | } |
| 156 | 149 | |
| 157 | 150 | void ScriptEngine::disconnectNonEssentialSignals() { |
| @@ -187,67 +180,6 @@ void ScriptEngine::runInThread() { · 29 unmodified lines | ||
| 187 | 180 | workerThread->start(); |
| 188 | 181 | } |
| 189 | 182 | |
| 190 | −QSet<ScriptEngine*> ScriptEngine::_allKnownScriptEngines; | |
| 191 | −QMutex ScriptEngine::_allScriptsMutex; | |
| 192 | −std::atomic<bool> ScriptEngine::_stoppingAllScripts { false }; | |
| 193 | − | |
| 194 | −void ScriptEngine::stopAllScripts(QObject* application) { | |
| 195 | − _allScriptsMutex.lock(); | |
| 196 | − _stoppingAllScripts = true; | |
| 197 | − | |
| 198 | − qCDebug(scriptengine) << "Stopping all scripts.... currently known scripts:" << _allKnownScriptEngines.size(); | |
| 199 | − | |
| 200 | − QMutableSetIterator<ScriptEngine*> i(_allKnownScriptEngines); | |
| 201 | − while (i.hasNext()) { | |
| 202 | − ScriptEngine* scriptEngine = i.next(); | |
| 203 | − | |
| 204 | − QString scriptName = scriptEngine->getFilename(); | |
| 205 | − | |
| 206 | − // NOTE: typically all script engines are running. But there's at least one known exception to this, the | |
| 207 | − // "entities sandbox" which is only used to evaluate entities scripts to test their validity before using | |
| 208 | − // them. We don't need to stop scripts that aren't running. | |
| 209 | − if (scriptEngine->isRunning()) { | |
| 210 | − | |
| 211 | − // If the script is running, but still evaluating then we need to wait for its evaluation step to | |
| 212 | − // complete. After that we can handle the stop process appropriately | |
| 213 | − if (scriptEngine->evaluatePending()) { | |
| 214 | − while (scriptEngine->evaluatePending()) { | |
| 215 | − | |
| 216 | − // This event loop allows any started, but not yet finished evaluate() calls to complete | |
| 217 | − // we need to let these complete so that we can be guaranteed that the script engine isn't | |
| 218 | − // in a partially setup state, which can confuse our shutdown unwinding. | |
| 219 | − QEventLoop loop; | |
| 220 | − QObject::connect(scriptEngine, &ScriptEngine::evaluationFinished, &loop, &QEventLoop::quit); | |
| 221 | − loop.exec(); | |
| 222 | − } | |
| 223 | − } | |
| 224 | − | |
| 225 | − // We disconnect any script engine signals from the application because we don't want to do any | |
| 226 | − // extra stopScript/loadScript processing that the Application normally does when scripts start | |
| 227 | − // and stop. We can safely short circuit this because we know we're in the "quitting" process | |
| 228 | − scriptEngine->disconnect(application); | |
| 229 | − | |
| 230 | − // Calling stop on the script engine will set it's internal _isFinished state to true, and result | |
| 231 | − // in the ScriptEngine gracefully ending it's run() method. | |
| 232 | − scriptEngine->stop(); | |
| 233 | − | |
| 234 | − // We need to wait for the engine to be done running before we proceed, because we don't | |
| 235 | − // want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing | |
| 236 | − // any application state after we leave this stopAllScripts() method | |
| 237 | − qCDebug(scriptengine) << "waiting on script:" << scriptName; | |
| 238 | − scriptEngine->waitTillDoneRunning(); | |
| 239 | − qCDebug(scriptengine) << "done waiting on script:" << scriptName; | |
| 240 | − | |
| 241 | − // If the script is stopped, we can remove it from our set | |
| 242 | − i.remove(); | |
| 243 | − } | |
| 244 | − } | |
| 245 | − _stoppingAllScripts = false; | |
| 246 | − _allScriptsMutex.unlock(); | |
| 247 | − qCDebug(scriptengine) << "DONE Stopping all scripts...."; | |
| 248 | −} | |
| 249 | − | |
| 250 | − | |
| 251 | 183 | void ScriptEngine::waitTillDoneRunning() { |
| 252 | 184 | // If the script never started running or finished running before we got here, we don't need to wait for it |
| 253 | 185 | if (_isRunning && _isThreaded) { |