Wait on old entity script engines in threadpool

This commit is contained in:
Zach Pomerantz 2016-05-12 17:49:47 -07:00
parent e1c130d02f
commit 806d06b552
2 changed files with 22 additions and 13 deletions

View file

@ -13,6 +13,7 @@
#include <QEventLoop>
#include <QScriptSyntaxCheckResult>
#include <QThreadPool>
#include <ColorUtils.h>
#include <AbstractScriptingServicesInterface.h>
@ -83,14 +84,22 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
auto newEngine = new ScriptEngine(NO_SCRIPT, QString("Entities %1").arg(++_entitiesScriptEngineCount));
_entitiesScriptEngine = QSharedPointer<ScriptEngine>(newEngine, [](ScriptEngine* engine){
// Gracefully exit
class WaitRunnable : public QRunnable {
public:
WaitRunnable(ScriptEngine* engine) : _engine(engine) {}
virtual void run() override {
_engine->wait();
_engine->deleteLater();
}
private:
ScriptEngine* _engine;
};
engine->unloadAllEntityScripts();
engine->stop();
// Disgracefully exit, if necessary
QTimer::singleShot(ScriptEngine::MAX_SCRIPT_EVALUATION_TIME, engine, &ScriptEngine::abort);
engine->deleteLater();
// Wait for the scripting thread from the thread pool to avoid hanging the main thread
QThreadPool::globalInstance()->start(new WaitRunnable(engine));
});
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine.data());

View file

@ -83,6 +83,13 @@ public:
/// run the script in the callers thread, exit when stop() is called.
void run();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts
Q_INVOKABLE void stop();
// Stop any evaluating scripts and wait for the scripting thread to finish.
void wait();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE - these are NOT intended to be public interfaces available to scripts, the are only Q_INVOKABLE so we can
// properly ensure they are only called on the correct thread
@ -138,10 +145,6 @@ public:
Q_INVOKABLE void requestGarbageCollection() { collectGarbage(); }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts
Q_INVOKABLE void stop();
bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget
bool isRunning() const { return _isRunning; } // used by ScriptWidget
@ -201,9 +204,6 @@ protected:
void init();
QString getFilename() const;
// Stop any evaluating scripts and wait for the scripting thread to finish.
void wait();
bool evaluatePending() const { return _evaluatesPending > 0; }
void timerFired();
void stopAllTimers();