History

Moving running scripts functionality to scripting library

Brad Davis committed 10 years ago

Commit d28f80a1 parent ddd9b0820 files · +664 −569Browse files

Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 20 files). Show all

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+5−73
@@ -46,11 +46,13 @@ · 45 unmodified lines
46#include "TypedArrays.h"46#include "TypedArrays.h"
47#include "XMLHttpRequestClass.h"47#include "XMLHttpRequestClass.h"
48#include "WebSocketClass.h"48#include "WebSocketClass.h"
49
50#include "RecordingScriptingInterface.h"49#include "RecordingScriptingInterface.h"
50#include "ScriptEngines.h"
51 51
52#include "MIDIEvent.h"52#include "MIDIEvent.h"
53 53
54std::atomic<bool> ScriptEngine::_stoppingAllScripts { false };
55
54static const QString SCRIPT_EXCEPTION_FORMAT = "[UncaughtException] %1 in %2:%3";56static const QString SCRIPT_EXCEPTION_FORMAT = "[UncaughtException] %1 in %2:%3";
55 57
56Q_DECLARE_METATYPE(QScriptEngine::FunctionSignature)58Q_DECLARE_METATYPE(QScriptEngine::FunctionSignature)
@@ -132,9 +134,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam · 75 unmodified lines
132 _fileNameString(fileNameString),134 _fileNameString(fileNameString),
133 _arrayBufferClass(new ArrayBufferClass(this))135 _arrayBufferClass(new ArrayBufferClass(this))
134{136{
135 _allScriptsMutex.lock();137 DependencyManager::get<ScriptEngines>()->addScriptEngine(this);
136 _allKnownScriptEngines.insert(this);
137 _allScriptsMutex.unlock();
138 138
139 connect(this, &QScriptEngine::signalHandlerException, this, [this](const QScriptValue& exception) {139 connect(this, &QScriptEngine::signalHandlerException, this, [this](const QScriptValue& exception) {
140 hadUncaughtExceptions(*this, _fileNameString);140 hadUncaughtExceptions(*this, _fileNameString);
@@ -144,14 +144,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam · 3 unmodified lines
144ScriptEngine::~ScriptEngine() {144ScriptEngine::~ScriptEngine() {
145 qCDebug(scriptengine) << "Script Engine shutting down (destructor) for script:" << getFilename();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 ourselves147 DependencyManager::get<ScriptEngines>()->removeScriptEngine(this);
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 }
155}148}
156 149
157void ScriptEngine::disconnectNonEssentialSignals() {150void ScriptEngine::disconnectNonEssentialSignals() {
@@ -187,67 +180,6 @@ void ScriptEngine::runInThread() { · 29 unmodified lines
187 workerThread->start();180 workerThread->start();
188}181}
189 182
190QSet<ScriptEngine*> ScriptEngine::_allKnownScriptEngines;
191QMutex ScriptEngine::_allScriptsMutex;
192std::atomic<bool> ScriptEngine::_stoppingAllScripts { false };
193
194void 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
251void ScriptEngine::waitTillDoneRunning() {183void ScriptEngine::waitTillDoneRunning() {
252 // If the script never started running or finished running before we got here, we don't need to wait for it184 // If the script never started running or finished running before we got here, we don't need to wait for it
253 if (_isRunning && _isThreaded) {185 if (_isRunning && _isThreaded) {