History

rework ScriptEngine lifetimes using 'smart' pointers

Seth Alves committed 9 years ago

Commit d89f2b71 parent 49ab8af18 files · +135 −146Browse files

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

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+22−24
@@ -153,6 +153,15 @@ QString ScriptEngine::logException(const QScriptValue& exception) { · 152 unmodified lines
153 return message;153 return message;
154}154}
155 155
156QSharedPointer<ScriptEngine> scriptEngineFactory(ScriptEngine::Context context,
157 const QString& scriptContents,
158 const QString& fileNameString) {
159 ScriptEngine* engine = new ScriptEngine(context, scriptContents, fileNameString);
160 QSharedPointer<ScriptEngine> engineSP = QSharedPointer<ScriptEngine>(engine);
161 DependencyManager::get<ScriptEngines>()->addScriptEngine(qSharedPointerCast<ScriptEngine>(engineSP));
162 return engineSP;
163}
164
156int ScriptEngine::processLevelMaxRetries { ScriptRequest::MAX_RETRIES };165int ScriptEngine::processLevelMaxRetries { ScriptRequest::MAX_RETRIES };
157ScriptEngine::ScriptEngine(Context context, const QString& scriptContents, const QString& fileNameString) :166ScriptEngine::ScriptEngine(Context context, const QString& scriptContents, const QString& fileNameString) :
158 BaseScriptEngine(),167 BaseScriptEngine(),
@@ -160,10 +169,10 @@ ScriptEngine::ScriptEngine(Context context, const QString& scriptContents, const · 1 unmodified line
160 _scriptContents(scriptContents),169 _scriptContents(scriptContents),
161 _timerFunctionMap(),170 _timerFunctionMap(),
162 _fileNameString(fileNameString),171 _fileNameString(fileNameString),
163 _arrayBufferClass(new ArrayBufferClass(this))172 _arrayBufferClass(new ArrayBufferClass(this)),
173 // don't delete `ScriptEngines` until all `ScriptEngine`s are gone
174 _scriptEngines(DependencyManager::get<ScriptEngines>())
164{175{
165 DependencyManager::get<ScriptEngines>()->addScriptEngine(this);
166
167 connect(this, &QScriptEngine::signalHandlerException, this, [this](const QScriptValue& exception) {176 connect(this, &QScriptEngine::signalHandlerException, this, [this](const QScriptValue& exception) {
168 if (hasUncaughtException()) {177 if (hasUncaughtException()) {
169 // the engine's uncaughtException() seems to produce much better stack traces here178 // the engine's uncaughtException() seems to produce much better stack traces here
@@ -208,22 +217,9 @@ QString ScriptEngine::getContext() const { · 38 unmodified lines
208}217}
209 218
210ScriptEngine::~ScriptEngine() {219ScriptEngine::~ScriptEngine() {
211 // FIXME: are these scriptInfoMessage/scriptWarningMessage segfaulting anybody else at app shutdown?
212#if !defined(Q_OS_LINUX)
213 scriptInfoMessage("Script Engine shutting down:" + getFilename());
214#else
215 qCDebug(scriptengine) << "~ScriptEngine()" << this;
216#endif
217
218 auto scriptEngines = DependencyManager::get<ScriptEngines>();220 auto scriptEngines = DependencyManager::get<ScriptEngines>();
219 if (scriptEngines) {221 if (scriptEngines) {
220 scriptEngines->removeScriptEngine(this);222 scriptEngines->removeScriptEngine(qSharedPointerCast<ScriptEngine>(sharedFromThis()));
221 } else {
222#if !defined(Q_OS_LINUX)
223 scriptWarningMessage("Script destroyed after ScriptEngines!");
224#else
225 qCWarning(scriptengine) << ("Script destroyed after ScriptEngines!");
226#endif
227 }223 }
228}224}
229 225
@@ -294,7 +290,7 @@ void ScriptEngine::runDebuggable() { · 64 unmodified lines
294 stopAllTimers(); // make sure all our timers are stopped if the script is ending290 stopAllTimers(); // make sure all our timers are stopped if the script is ending
295 291
296 emit scriptEnding();292 emit scriptEnding();
297 emit finished(_fileNameString, this);293 emit finished(_fileNameString, qSharedPointerCast<ScriptEngine>(sharedFromThis()));
298 _isRunning = false;294 _isRunning = false;
299 295
300 emit runningStateChanged();296 emit runningStateChanged();
@@ -503,7 +499,8 @@ static void animVarMapFromScriptValue(const QScriptValue& value, AnimVariantMap& · 202 unmodified lines
503 parameters.animVariantMapFromScriptValue(value);499 parameters.animVariantMapFromScriptValue(value);
504}500}
505// ... while these two are not. But none of the four are ever used.501// ... while these two are not. But none of the four are ever used.
506static QScriptValue resultHandlerToScriptValue(QScriptEngine* engine, const AnimVariantResultHandler& resultHandler) {502static QScriptValue resultHandlerToScriptValue(QScriptEngine* engine,
503 const AnimVariantResultHandler& resultHandler) {
507 qCCritical(scriptengine) << "Attempt to marshall result handler to javascript";504 qCCritical(scriptengine) << "Attempt to marshall result handler to javascript";
508 assert(false);505 assert(false);
509 return QScriptValue();506 return QScriptValue();
@@ -516,7 +513,8 @@ static void resultHandlerFromScriptValue(const QScriptValue& value, AnimVariantR · 6 unmodified lines
516// Templated qScriptRegisterMetaType fails to compile with raw pointers513// Templated qScriptRegisterMetaType fails to compile with raw pointers
517using ScriptableResourceRawPtr = ScriptableResource*;514using ScriptableResourceRawPtr = ScriptableResource*;
518 515
519static QScriptValue scriptableResourceToScriptValue(QScriptEngine* engine, const ScriptableResourceRawPtr& resource) {516static QScriptValue scriptableResourceToScriptValue(QScriptEngine* engine,
517 const ScriptableResourceRawPtr& resource) {
520 // The first script to encounter this resource will track its memory.518 // The first script to encounter this resource will track its memory.
521 // In this way, it will be more likely to GC.519 // In this way, it will be more likely to GC.
522 // This fails in the case that the resource is used across many scripts, but520 // This fails in the case that the resource is used across many scripts, but
@@ -539,11 +537,11 @@ static void scriptableResourceFromScriptValue(const QScriptValue& value, Scripta · 16 unmodified lines
539 resource = static_cast<ScriptableResourceRawPtr>(value.toQObject());537 resource = static_cast<ScriptableResourceRawPtr>(value.toQObject());
540}538}
541 539
542static QScriptValue createScriptableResourcePrototype(QScriptEngine* engine) {540static QScriptValue createScriptableResourcePrototype(QSharedPointer<ScriptEngine> engine) {
543 auto prototype = engine->newObject();541 auto prototype = engine->newObject();
544 542
545 // Expose enum State to JS/QML via properties543 // Expose enum State to JS/QML via properties
546 QObject* state = new QObject(engine);544 QObject* state = new QObject(engine.data());
547 state->setObjectName("ResourceState");545 state->setObjectName("ResourceState");
548 auto metaEnum = QMetaEnum::fromType<ScriptableResource::State>();546 auto metaEnum = QMetaEnum::fromType<ScriptableResource::State>();
549 for (int i = 0; i < metaEnum.keyCount(); ++i) {547 for (int i = 0; i < metaEnum.keyCount(); ++i) {
@@ -693,7 +691,7 @@ void ScriptEngine::init() { · 143 unmodified lines
693 qScriptRegisterMetaType(this, resultHandlerToScriptValue, resultHandlerFromScriptValue);691 qScriptRegisterMetaType(this, resultHandlerToScriptValue, resultHandlerFromScriptValue);
694 692
695 // Scriptable cache access693 // Scriptable cache access
696 auto resourcePrototype = createScriptableResourcePrototype(this);694 auto resourcePrototype = createScriptableResourcePrototype(qSharedPointerCast<ScriptEngine>(sharedFromThis()));
697 globalObject().setProperty("Resource", resourcePrototype);695 globalObject().setProperty("Resource", resourcePrototype);
698 setDefaultPrototype(qMetaTypeId<ScriptableResource*>(), resourcePrototype);696 setDefaultPrototype(qMetaTypeId<ScriptableResource*>(), resourcePrototype);
699 qScriptRegisterMetaType(this, scriptableResourceToScriptValue, scriptableResourceFromScriptValue);697 qScriptRegisterMetaType(this, scriptableResourceToScriptValue, scriptableResourceFromScriptValue);
@@ -1178,7 +1176,7 @@ void ScriptEngine::run() { · 478 unmodified lines
1178 }1176 }
1179 }1177 }
1180 1178
1181 emit finished(_fileNameString, this);1179 emit finished(_fileNameString, qSharedPointerCast<ScriptEngine>(sharedFromThis()));
1182 1180
1183 _isRunning = false;1181 _isRunning = false;
1184 emit runningStateChanged();1182 emit runningStateChanged();