mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 19:04:27 +02:00
more hacking on script shutdown behavior
This commit is contained in:
parent
6be8f4c0ec
commit
fd93b99f03
4 changed files with 231 additions and 57 deletions
|
@ -3552,9 +3552,11 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
||||||
ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUserLoaded,
|
ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUserLoaded,
|
||||||
bool loadScriptFromEditor, bool activateMainWindow) {
|
bool loadScriptFromEditor, bool activateMainWindow) {
|
||||||
|
|
||||||
qDebug() << "Application::loadScript() " << scriptFilename << "line:" << __LINE__;
|
qDebug() << "Application::loadScript() ---- BEGIN ---- Script:" << scriptFilename;
|
||||||
|
|
||||||
if (isAboutToQuit()) {
|
if (isAboutToQuit()) {
|
||||||
qDebug() << "Application::loadScript() WHILE QUITTING.... what to do????" << scriptFilename << "line:" << __LINE__;
|
qDebug() << "Requests to load scripts while quitting are ignored. Script:" << scriptFilename;
|
||||||
|
qDebug() << "Application::loadScript() ---- END ---- Script:" << scriptFilename;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3563,6 +3565,8 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
|
||||||
if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor
|
if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor
|
||||||
&& !_scriptEnginesHash[scriptURLString]->isFinished()) {
|
&& !_scriptEnginesHash[scriptURLString]->isFinished()) {
|
||||||
|
|
||||||
|
qDebug() << "Application::loadScript() from _scriptEnginesHash[scriptURLString].... Script:" << scriptFilename;
|
||||||
|
qDebug() << "Application::loadScript() ---- END ---- Script:" << scriptFilename;
|
||||||
return _scriptEnginesHash[scriptURLString];
|
return _scriptEnginesHash[scriptURLString];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3581,6 +3585,7 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
|
||||||
connect(scriptEngine, &ScriptEngine::errorLoadingScript, this, &Application::handleScriptLoadError);
|
connect(scriptEngine, &ScriptEngine::errorLoadingScript, this, &Application::handleScriptLoadError);
|
||||||
|
|
||||||
// get the script engine object to load the script at the designated script URL
|
// get the script engine object to load the script at the designated script URL
|
||||||
|
qDebug() << "Application::loadScript() about to call loadURL() scriptUrl:" << scriptUrl;
|
||||||
scriptEngine->loadURL(scriptUrl);
|
scriptEngine->loadURL(scriptUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3589,6 +3594,9 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
|
||||||
_window->activateWindow();
|
_window->activateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "Application::loadScript() newly created scriptEngine.... Script:" << scriptFilename;
|
||||||
|
qDebug() << "Application::loadScript() ---- END ---- Script:" << scriptFilename;
|
||||||
|
|
||||||
return scriptEngine;
|
return scriptEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,8 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTreeRenderer::~EntityTreeRenderer() {
|
EntityTreeRenderer::~EntityTreeRenderer() {
|
||||||
qDebug() << "EntityTreeRenderer::~EntityTreeRenderer() -------- BEGIN -----------";
|
|
||||||
// NOTE: we don't need to delete _entitiesScriptEngine because it's owned by the application and gets cleaned up
|
// NOTE: we don't need to delete _entitiesScriptEngine because it's owned by the application and gets cleaned up
|
||||||
// automatically but we do need to delete our sandbox script engine.
|
// automatically but we do need to delete our sandbox script engine.
|
||||||
|
|
||||||
if (_sandboxScriptEngine) {
|
if (_sandboxScriptEngine) {
|
||||||
// NOTE: is it possible this is a problem? I think that we hook the script engine object up to a deleteLater()
|
// NOTE: is it possible this is a problem? I think that we hook the script engine object up to a deleteLater()
|
||||||
// call inside of registerScriptEngineWithApplicationServices() but do we not call that for _sandboxScriptEngine???
|
// call inside of registerScriptEngineWithApplicationServices() but do we not call that for _sandboxScriptEngine???
|
||||||
|
@ -72,7 +70,6 @@ EntityTreeRenderer::~EntityTreeRenderer() {
|
||||||
delete _sandboxScriptEngine;
|
delete _sandboxScriptEngine;
|
||||||
_sandboxScriptEngine = NULL;
|
_sandboxScriptEngine = NULL;
|
||||||
}
|
}
|
||||||
qDebug() << "EntityTreeRenderer::~EntityTreeRenderer() -------- DONE -----------";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::clear() {
|
void EntityTreeRenderer::clear() {
|
||||||
|
|
|
@ -94,33 +94,32 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
|
||||||
_isUserLoaded(false),
|
_isUserLoaded(false),
|
||||||
_arrayBufferClass(new ArrayBufferClass(this))
|
_arrayBufferClass(new ArrayBufferClass(this))
|
||||||
{
|
{
|
||||||
qDebug() << "ScriptEngine::ScriptEngine() " << getFilename() << "[" << ((void*)this) << "]" << " -------- BEGIN -----------";
|
|
||||||
_allScriptsMutex.lock();
|
_allScriptsMutex.lock();
|
||||||
_allKnownScriptEngines.insert(this);
|
_allKnownScriptEngines.insert(this);
|
||||||
_allScriptsMutex.unlock();
|
_allScriptsMutex.unlock();
|
||||||
qDebug() << "ScriptEngine::ScriptEngine() " << getFilename() << " -------- DONE -----------";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngine::~ScriptEngine() {
|
ScriptEngine::~ScriptEngine() {
|
||||||
qDebug() << "ScriptEngine::~ScriptEngine() " << getFilename() << "[" << ((void*)this) << "]" << " -------- BEGIN -----------";
|
qDebug() << "ScriptEngine::~ScriptEngine() ------- BEGIN ------- script:" << getFilename();
|
||||||
|
// If we're not already in the middle of stopping all scripts, then we should remove ourselves
|
||||||
|
// from the list of running scripts. We don't do this if we're in the process of stopping all scripts
|
||||||
|
// because that method removes scripts from its list as it iterates them
|
||||||
if (!_stoppingAllScripts) {
|
if (!_stoppingAllScripts) {
|
||||||
_allScriptsMutex.lock();
|
_allScriptsMutex.lock();
|
||||||
qDebug() << "ScriptEngine::~ScriptEngine() " << getFilename() << " removing from list of scripts";
|
|
||||||
_allKnownScriptEngines.remove(this);
|
_allKnownScriptEngines.remove(this);
|
||||||
_allScriptsMutex.unlock();
|
_allScriptsMutex.unlock();
|
||||||
} else {
|
|
||||||
qDebug() << "ScriptEngine::~ScriptEngine() " << getFilename() << " NOT removing from list of scripts here...";
|
|
||||||
}
|
}
|
||||||
qDebug() << "ScriptEngine::~ScriptEngine() " << getFilename() << " -------- DONE -----------";
|
qDebug() << "ScriptEngine::~ScriptEngine() ------- END ------- script:" << getFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<ScriptEngine*> ScriptEngine::_allKnownScriptEngines;
|
QSet<ScriptEngine*> ScriptEngine::_allKnownScriptEngines;
|
||||||
QMutex ScriptEngine::_allScriptsMutex;
|
QMutex ScriptEngine::_allScriptsMutex;
|
||||||
bool ScriptEngine::_stoppingAllScripts = false;
|
bool ScriptEngine::_stoppingAllScripts = false;
|
||||||
|
bool ScriptEngine::_doneRunningThisScript = false;
|
||||||
|
|
||||||
void ScriptEngine::stopAllScripts(QObject* application) {
|
void ScriptEngine::stopAllScripts(QObject* application) {
|
||||||
|
qDebug() << "ScriptEngine::stopAllScripts() ------- BEGIN -------";
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() -------- BEGIN -----------";
|
|
||||||
_allScriptsMutex.lock();
|
_allScriptsMutex.lock();
|
||||||
_stoppingAllScripts = true;
|
_stoppingAllScripts = true;
|
||||||
|
|
||||||
|
@ -128,44 +127,92 @@ void ScriptEngine::stopAllScripts(QObject* application) {
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
ScriptEngine* scriptEngine = i.next();
|
ScriptEngine* scriptEngine = i.next();
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() scriptEngine: " << (void*)scriptEngine;
|
|
||||||
|
|
||||||
QString scriptName = scriptEngine->getFilename();
|
QString scriptName = scriptEngine->getFilename();
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() considering script: " << scriptName << "evaluatePending:" << scriptEngine->evaluatePending();
|
qDebug() << "ScriptEngine::stopAllScripts() considering:" << scriptName
|
||||||
|
<< "isRunning():" << scriptEngine->isRunning()
|
||||||
|
<< "evaluatePending():" << scriptEngine->evaluatePending();
|
||||||
|
|
||||||
// NOTE: typically all script engines are running. But there's at least one known exception to this, the
|
// NOTE: typically all script engines are running. But there's at least one known exception to this, the
|
||||||
// "entities sandbox" which is only used to evaluate entities scripts to test their validity before using
|
// "entities sandbox" which is only used to evaluate entities scripts to test their validity before using
|
||||||
// them. We don't need to stop scripts that aren't running.
|
// them. We don't need to stop scripts that aren't running.
|
||||||
if (scriptEngine->isRunning()) {
|
if (scriptEngine->isRunning()) {
|
||||||
|
|
||||||
|
// If the script is running, but still evaluating then we need to wait for its evaluation step to
|
||||||
|
// complete. After that we can handle the stop process appropriately
|
||||||
if (scriptEngine->evaluatePending()) {
|
if (scriptEngine->evaluatePending()) {
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() handling script: " << scriptName << "line:" << __LINE__ << "waiting for evaluation to complete....";
|
while (scriptEngine->evaluatePending()) {
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
QObject::connect(scriptEngine, &ScriptEngine::evaluationFinished, &loop, &QEventLoop::quit);
|
QObject::connect(scriptEngine, &ScriptEngine::evaluationFinished, &loop, &QEventLoop::quit);
|
||||||
|
qDebug() << "ScriptEngine::stopAllScripts() while(evaluatePending()) STARTING loop.exec() script:" << scriptName;
|
||||||
loop.exec();
|
loop.exec();
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() handling script: " << scriptName << "line:" << __LINE__ << "evaluation complete....";
|
qDebug() << "ScriptEngine::stopAllScripts() while(evaluatePending()) AFTER loop.exec() script:" << scriptName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() handling script: " << scriptName << "line:" << __LINE__;
|
|
||||||
|
|
||||||
QEventLoop loop;
|
|
||||||
QObject::connect(scriptEngine, &ScriptEngine::doneRunning, &loop, &QEventLoop::quit);
|
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() handling script: " << scriptName << "line:" << __LINE__;
|
|
||||||
scriptEngine->disconnect(application);
|
scriptEngine->disconnect(application);
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() handling script: " << scriptName << "line:" << __LINE__;
|
|
||||||
scriptEngine->stop();
|
scriptEngine->stop();
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() handling script: " << scriptName << "line:" << __LINE__;
|
|
||||||
loop.exec();
|
qDebug() << "ScriptEngine::stopAllScripts() -- WAITING for waitTillDoneRunning() script:" << scriptName;
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() handling script: " << scriptName << "line:" << __LINE__;
|
scriptEngine->waitTillDoneRunning();
|
||||||
|
qDebug() << "ScriptEngine::stopAllScripts() -- AFTER waitTillDoneRunning() script:" << scriptName;
|
||||||
i.remove();
|
i.remove();
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() script: " << scriptName << " was not running... skipping it's stop() call.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_stoppingAllScripts = false;
|
_stoppingAllScripts = false;
|
||||||
_allScriptsMutex.unlock();
|
_allScriptsMutex.unlock();
|
||||||
qDebug() << "ScriptEngine::stopAllScripts() -------- DONE -----------";
|
qDebug() << "ScriptEngine::stopAllScripts() ------- DONE -------";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScriptEngine::waitTillDoneRunning() {
|
||||||
|
QString scriptName = getFilename();
|
||||||
|
qDebug() << "ScriptEngine::waitTillDoneRunning() ------- BEGIN ------- script:" << scriptName;
|
||||||
|
qDebug() << " _isFinished:" << _isFinished;
|
||||||
|
qDebug() << " _isRunning:" << _isRunning;
|
||||||
|
qDebug() << " _isInitialized:" << _isInitialized;
|
||||||
|
qDebug() << " _evaluatesPending:" << _evaluatesPending;
|
||||||
|
|
||||||
|
if (_isRunning) {
|
||||||
|
qDebug() << "ScriptEngine::waitTillDoneRunning() SETTING _doneRunningThisScript = false ################################### line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
_doneRunningThisScript = false;
|
||||||
|
_isWaitingForDoneRunning = true;
|
||||||
|
|
||||||
|
// What can we do here???
|
||||||
|
// we will be calling this on the main Application thread, inside of stopAllScripts()
|
||||||
|
// we want the application thread to continue to process events, because the script will
|
||||||
|
// likely need to marshall messages across to the main thread.
|
||||||
|
while (!_doneRunningThisScript && _isRunning) {
|
||||||
|
|
||||||
|
// and run a QEventLoop???
|
||||||
|
QEventLoop loop;
|
||||||
|
QObject::connect(this, &ScriptEngine::doneRunning, &loop, &QEventLoop::quit);
|
||||||
|
qDebug() << "ScriptEngine::waitTillDoneRunning() STARTING loop.exec() script:" << scriptName;
|
||||||
|
qDebug() << " _doneRunningThisScript:" << _doneRunningThisScript;
|
||||||
|
qDebug() << " _isRunning:" << _isRunning;
|
||||||
|
qDebug() << " _isWaitingForDoneRunning:" << _isWaitingForDoneRunning;
|
||||||
|
qDebug() << " _isFinished:" << _isFinished;
|
||||||
|
qDebug() << " _isInitialized:" << _isInitialized;
|
||||||
|
qDebug() << " _evaluatesPending:" << _evaluatesPending;
|
||||||
|
loop.exec();
|
||||||
|
qDebug() << "ScriptEngine::waitTillDoneRunning() AFTER loop.exec() script:" << scriptName;
|
||||||
|
|
||||||
|
// process events
|
||||||
|
qDebug() << "ScriptEngine::waitTillDoneRunning() STARTING QCoreApplication::processEvents() script:" << scriptName;
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
qDebug() << "ScriptEngine::waitTillDoneRunning() AFTER QCoreApplication::processEvents() script:" << scriptName;
|
||||||
|
|
||||||
|
if (_doneRunningThisScript) {
|
||||||
|
qDebug() << "ScriptEngine::waitTillDoneRunning() _doneRunningThisScript after processEvents... breaking!!! script:" << scriptName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_isWaitingForDoneRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::waitTillDoneRunning() ------- DONE ------- script:" << scriptName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ScriptEngine::getFilename() const {
|
QString ScriptEngine::getFilename() const {
|
||||||
|
@ -377,12 +424,23 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::evaluate() {
|
void ScriptEngine::evaluate() {
|
||||||
|
if (_stoppingAllScripts) {
|
||||||
|
qDebug() << "ScriptEngine::evaluate() while shutting down is ignored...";
|
||||||
|
qDebug() << " parent script:" << getFilename() << "[" << this << "]";
|
||||||
|
return; // bail early
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::evaluate() -- BEGIN script:" << getFilename() << "[" << this << "]";
|
||||||
if (!_isInitialized) {
|
if (!_isInitialized) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::evaluate() -- about to call own evaluate(program) script:" << getFilename() << "[" << this << "]";
|
||||||
QScriptValue result = evaluate(_scriptContents);
|
QScriptValue result = evaluate(_scriptContents);
|
||||||
|
qDebug() << "ScriptEngine::evaluate() -- AFTER own evaluate(program) script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
|
// TODO: why do we check this twice? It seems like the call to clearExcpetions() in the lower level evaluate call
|
||||||
|
// will cause this code to never actually run...
|
||||||
if (hasUncaughtException()) {
|
if (hasUncaughtException()) {
|
||||||
int line = uncaughtExceptionLineNumber();
|
int line = uncaughtExceptionLineNumber();
|
||||||
qDebug() << "Uncaught exception at (" << _fileNameString << ") line" << line << ":" << result.toString();
|
qDebug() << "Uncaught exception at (" << _fileNameString << ") line" << line << ":" << result.toString();
|
||||||
|
@ -392,17 +450,30 @@ void ScriptEngine::evaluate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber) {
|
QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber) {
|
||||||
qDebug() << "ScriptEngine::evaluate() " << getFilename() << " line:" << __LINE__;
|
if (_stoppingAllScripts) {
|
||||||
_evaluatePending = true;
|
qDebug() << "ScriptEngine::evaluate(program) while shutting down is ignored...";
|
||||||
|
qDebug() << " parent script:" << getFilename() << "[" << this << "]";
|
||||||
|
return QScriptValue(); // bail early
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::evaluate(program) -- BEGIN script:" << getFilename() << "_evaluatesPending:" << _evaluatesPending << "[" << this << "]";
|
||||||
|
_evaluatesPending++;
|
||||||
|
qDebug() << "ScriptEngine::evaluate(program) -- after _evaluatesPending++ script:" << getFilename() << "_evaluatesPending:" << _evaluatesPending << "[" << this << "]";
|
||||||
|
qDebug() << "ScriptEngine::evaluate(program) -- BEFORE QScriptEngine::evaluate() script:" << getFilename() << "_evaluatesPending:" << _evaluatesPending << "[" << this << "]";
|
||||||
QScriptValue result = QScriptEngine::evaluate(program, fileName, lineNumber);
|
QScriptValue result = QScriptEngine::evaluate(program, fileName, lineNumber);
|
||||||
|
qDebug() << "ScriptEngine::evaluate(program) -- AFTER QScriptEngine::evaluate() script:" << getFilename() << "_evaluatesPending:" << _evaluatesPending << "[" << this << "]";
|
||||||
if (hasUncaughtException()) {
|
if (hasUncaughtException()) {
|
||||||
int line = uncaughtExceptionLineNumber();
|
int line = uncaughtExceptionLineNumber();
|
||||||
qDebug() << "Uncaught exception at (" << _fileNameString << " : " << fileName << ") line" << line << ": " << result.toString();
|
qDebug() << "Uncaught exception at (" << _fileNameString << " : " << fileName << ") line" << line << ": " << result.toString();
|
||||||
}
|
}
|
||||||
|
_evaluatesPending--;
|
||||||
|
qDebug() << "ScriptEngine::evaluate(program) -- after _evaluatesPending-- script:" << getFilename() << "_evaluatesPending:" << _evaluatesPending << "[" << this << "]";
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::evaluate(program) -- ABOUT TO emit evaluationFinished() script:" << getFilename() << "_evaluatesPending:" << _evaluatesPending << "[" << this << "]";
|
||||||
emit evaluationFinished(result, hasUncaughtException());
|
emit evaluationFinished(result, hasUncaughtException());
|
||||||
|
qDebug() << "ScriptEngine::evaluate(program) -- AFTER emit evaluationFinished() script:" << getFilename() << "_evaluatesPending:" << _evaluatesPending << "[" << this << "]";
|
||||||
clearExceptions();
|
clearExceptions();
|
||||||
_evaluatePending = false;
|
qDebug() << "ScriptEngine::evaluate(program) -- DONE script:" << getFilename() << "_evaluatesPending:" << _evaluatesPending << "[" << this << "]";
|
||||||
qDebug() << "ScriptEngine::evaluate() " << getFilename() << " line:" << __LINE__;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,49 +490,60 @@ void ScriptEngine::sendAvatarBillboardPacket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::run() {
|
void ScriptEngine::run() {
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " -------- BEGIN -----------";
|
// TODO: can we add a short circuit for _stoppingAllScripts here? What does it mean to not start running if
|
||||||
|
// we're in the process of stopping?
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
if (!_isInitialized) {
|
if (!_isInitialized) {
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
|
||||||
init();
|
init();
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
|
||||||
}
|
}
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
_isRunning = true;
|
_isRunning = true;
|
||||||
_isFinished = false;
|
_isFinished = false;
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
|
||||||
emit runningStateChanged();
|
emit runningStateChanged();
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
QScriptValue result = evaluate(_scriptContents);
|
QScriptValue result = evaluate(_scriptContents);
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
|
||||||
QElapsedTimer startTime;
|
QElapsedTimer startTime;
|
||||||
startTime.start();
|
startTime.start();
|
||||||
|
|
||||||
int thisFrame = 0;
|
int thisFrame = 0;
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
qint64 lastUpdate = usecTimestampNow();
|
qint64 lastUpdate = usecTimestampNow();
|
||||||
|
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
while (!_isFinished) {
|
while (!_isFinished) {
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
int usecToSleep = (thisFrame++ * SCRIPT_DATA_CALLBACK_USECS) - startTime.nsecsElapsed() / 1000; // nsec to usec
|
int usecToSleep = (thisFrame++ * SCRIPT_DATA_CALLBACK_USECS) - startTime.nsecsElapsed() / 1000; // nsec to usec
|
||||||
if (usecToSleep > 0) {
|
if (usecToSleep > 0) {
|
||||||
usleep(usecToSleep);
|
usleep(usecToSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isFinished) {
|
if (_isFinished) {
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
if (_isFinished) {
|
if (_isFinished) {
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,16 +671,38 @@ void ScriptEngine::run() {
|
||||||
emit update(deltaTime);
|
emit update(deltaTime);
|
||||||
}
|
}
|
||||||
lastUpdate = now;
|
lastUpdate = now;
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
}
|
}
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " line:" << __LINE__;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
stopAllTimers(); // make sure all our timers are stopped if the script is ending
|
stopAllTimers(); // make sure all our timers are stopped if the script is ending
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename();
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
emit scriptEnding();
|
emit scriptEnding();
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
// kill the avatar identity timer
|
// kill the avatar identity timer
|
||||||
delete _avatarIdentityTimer;
|
delete _avatarIdentityTimer;
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
if (_entityScriptingInterface.getEntityPacketSender()->serversExist()) {
|
if (_entityScriptingInterface.getEntityPacketSender()->serversExist()) {
|
||||||
// release the queue of edit entity messages.
|
// release the queue of edit entity messages.
|
||||||
_entityScriptingInterface.getEntityPacketSender()->releaseQueuedMessages();
|
_entityScriptingInterface.getEntityPacketSender()->releaseQueuedMessages();
|
||||||
|
@ -609,19 +713,44 @@ void ScriptEngine::run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
// If we were on a thread, then wait till it's done
|
// If we were on a thread, then wait till it's done
|
||||||
if (thread()) {
|
if (thread()) {
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
thread()->quit();
|
thread()->quit();
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::run() line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
emit finished(_fileNameString);
|
emit finished(_fileNameString);
|
||||||
|
|
||||||
_isRunning = false;
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
_isRunning = false;
|
||||||
emit runningStateChanged();
|
emit runningStateChanged();
|
||||||
|
|
||||||
|
qDebug() << "ABOUT TO emit doneRunning() script:" << getFilename() << "[" << this << "]";
|
||||||
emit doneRunning();
|
emit doneRunning();
|
||||||
qDebug() << "ScriptEngine::run() " << getFilename() << " -------- DONE -----------" << " line:" << __LINE__;
|
qDebug() << "AFTER emit doneRunning() script:" << getFilename() << "[" << this << "]";
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "ScriptEngine::run() SETTING _doneRunningThisScript = true ################################### line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
_doneRunningThisScript = true;
|
||||||
|
|
||||||
|
if (_isWaitingForDoneRunning) {
|
||||||
|
qDebug() << "ScriptEngine::run() ** _isWaitingForDoneRunning == true ** line:" << __LINE__ << " script:" << getFilename() << "[" << this << "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: This is private because it must be called on the same thread that created the timers, which is why
|
// NOTE: This is private because it must be called on the same thread that created the timers, which is why
|
||||||
|
@ -636,9 +765,10 @@ void ScriptEngine::stopAllTimers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::stop() {
|
void ScriptEngine::stop() {
|
||||||
qDebug() << "ScriptEngine::stop() " << getFilename() << "[" << ((void*)this) << "]";
|
qDebug() << "ScriptEngine::stop() -- START -- line:" << __LINE__ << " script:" << getFilename();
|
||||||
_isFinished = true;
|
_isFinished = true;
|
||||||
emit runningStateChanged();
|
emit runningStateChanged();
|
||||||
|
qDebug() << "ScriptEngine::stop() -- DONE -- line:" << __LINE__ << " script:" << getFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::timerFired() {
|
void ScriptEngine::timerFired() {
|
||||||
|
@ -674,10 +804,22 @@ QObject* ScriptEngine::setupTimerWithInterval(const QScriptValue& function, int
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) {
|
QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) {
|
||||||
|
if (_stoppingAllScripts) {
|
||||||
|
qDebug() << "Script.setInterval() while shutting down is ignored...";
|
||||||
|
qDebug() << " parent script:" << getFilename() << "[" << this << "]";
|
||||||
|
return NULL; // bail early
|
||||||
|
}
|
||||||
|
|
||||||
return setupTimerWithInterval(function, intervalMS, false);
|
return setupTimerWithInterval(function, intervalMS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject* ScriptEngine::setTimeout(const QScriptValue& function, int timeoutMS) {
|
QObject* ScriptEngine::setTimeout(const QScriptValue& function, int timeoutMS) {
|
||||||
|
if (_stoppingAllScripts) {
|
||||||
|
qDebug() << "Script.setTimeout() while shutting down is ignored...";
|
||||||
|
qDebug() << " parent script:" << getFilename() << "[" << this << "]";
|
||||||
|
return NULL; // bail early
|
||||||
|
}
|
||||||
|
|
||||||
return setupTimerWithInterval(function, timeoutMS, true);
|
return setupTimerWithInterval(function, timeoutMS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,6 +865,12 @@ void ScriptEngine::print(const QString& message) {
|
||||||
// If no callback is specified, the included files will be loaded synchronously and will block execution until
|
// If no callback is specified, the included files will be loaded synchronously and will block execution until
|
||||||
// all of the files have finished loading.
|
// all of the files have finished loading.
|
||||||
void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) {
|
void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) {
|
||||||
|
if (_stoppingAllScripts) {
|
||||||
|
qDebug() << "Script.include() while shutting down is ignored...";
|
||||||
|
qDebug() << " includeFiles:" << includeFiles;
|
||||||
|
qDebug() << " parent script:" << getFilename() << "[" << this << "]";
|
||||||
|
return; // bail early
|
||||||
|
}
|
||||||
QList<QUrl> urls;
|
QList<QUrl> urls;
|
||||||
for (QString file : includeFiles) {
|
for (QString file : includeFiles) {
|
||||||
urls.append(resolvePath(file));
|
urls.append(resolvePath(file));
|
||||||
|
@ -736,7 +884,9 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac
|
||||||
if (contents.isNull()) {
|
if (contents.isNull()) {
|
||||||
qDebug() << "Error loading file: " << url;
|
qDebug() << "Error loading file: " << url;
|
||||||
} else {
|
} else {
|
||||||
|
qDebug() << "ScriptEngine::include() BEFORE evaluate() line:" << __LINE__ << " parent script:" << getFilename() << "[" << this << "]" << " url:" << url << "_evaluatesPending:" << _evaluatesPending;
|
||||||
QScriptValue result = evaluate(contents, url.toString());
|
QScriptValue result = evaluate(contents, url.toString());
|
||||||
|
qDebug() << "ScriptEngine::include() AFTER evaluate() line:" << __LINE__ << " parent script:" << getFilename() << "[" << this << "]" << " url:" << url << "_evaluatesPending:" << _evaluatesPending;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,17 +912,31 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::include(const QString& includeFile, QScriptValue callback) {
|
void ScriptEngine::include(const QString& includeFile, QScriptValue callback) {
|
||||||
|
if (_stoppingAllScripts) {
|
||||||
|
qDebug() << "Script.include() while shutting down is ignored...";
|
||||||
|
qDebug() << " includeFile:" << includeFile;
|
||||||
|
qDebug() << " parent script:" << getFilename() << "[" << this << "]";
|
||||||
|
return; // bail early
|
||||||
|
}
|
||||||
|
|
||||||
QStringList urls;
|
QStringList urls;
|
||||||
urls.append(includeFile);
|
urls.append(includeFile);
|
||||||
include(urls, callback);
|
include(urls, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: The load() command is similar to the include() command except that it loads the script
|
||||||
|
// as a stand-alone script. To accomplish this, the ScriptEngine class just emits a signal which
|
||||||
|
// the Application or other context will connect to in order to know to actually load the script
|
||||||
void ScriptEngine::load(const QString& loadFile) {
|
void ScriptEngine::load(const QString& loadFile) {
|
||||||
qDebug() << "ScriptEngine::load() " << getFilename() << "[" << ((void*)this) << "]" << "line:" << __LINE__;
|
if (_stoppingAllScripts) {
|
||||||
|
qDebug() << "Script.load() while shutting down is ignored...";
|
||||||
|
qDebug() << " loadFile:" << loadFile;
|
||||||
|
qDebug() << " parent script:" << getFilename() << "[" << this << "]";
|
||||||
|
return; // bail early
|
||||||
|
}
|
||||||
|
|
||||||
QUrl url = resolvePath(loadFile);
|
QUrl url = resolvePath(loadFile);
|
||||||
qDebug() << "ScriptEngine::load() " << getFilename() << "[" << ((void*)this) << "]" << "line:" << __LINE__;
|
|
||||||
emit loadScript(url.toString(), false);
|
emit loadScript(url.toString(), false);
|
||||||
qDebug() << "ScriptEngine::load() " << getFilename() << "[" << ((void*)this) << "]" << "line:" << __LINE__;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::nodeKilled(SharedNodePointer node) {
|
void ScriptEngine::nodeKilled(SharedNodePointer node) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtCore/QWaitCondition>
|
||||||
#include <QtScript/QScriptEngine>
|
#include <QtScript/QScriptEngine>
|
||||||
|
|
||||||
#include <AnimationCache.h>
|
#include <AnimationCache.h>
|
||||||
|
@ -85,7 +86,7 @@ public:
|
||||||
|
|
||||||
bool isFinished() const { return _isFinished; }
|
bool isFinished() const { return _isFinished; }
|
||||||
bool isRunning() const { return _isRunning; }
|
bool isRunning() const { return _isRunning; }
|
||||||
bool evaluatePending() const { return _evaluatePending; }
|
bool evaluatePending() const { return _evaluatesPending > 0; }
|
||||||
|
|
||||||
void setUserLoaded(bool isUserLoaded) { _isUserLoaded = isUserLoaded; }
|
void setUserLoaded(bool isUserLoaded) { _isUserLoaded = isUserLoaded; }
|
||||||
bool isUserLoaded() const { return _isUserLoaded; }
|
bool isUserLoaded() const { return _isUserLoaded; }
|
||||||
|
@ -96,6 +97,8 @@ public:
|
||||||
|
|
||||||
static void stopAllScripts(QObject* application);
|
static void stopAllScripts(QObject* application);
|
||||||
|
|
||||||
|
void waitTillDoneRunning();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void loadURL(const QUrl& scriptURL);
|
void loadURL(const QUrl& scriptURL);
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -132,7 +135,8 @@ protected:
|
||||||
QString _parentURL;
|
QString _parentURL;
|
||||||
bool _isFinished;
|
bool _isFinished;
|
||||||
bool _isRunning;
|
bool _isRunning;
|
||||||
bool _evaluatePending = false;
|
int _evaluatesPending = 0;
|
||||||
|
bool _isWaitingForDoneRunning = false;
|
||||||
bool _isInitialized;
|
bool _isInitialized;
|
||||||
bool _isAvatar;
|
bool _isAvatar;
|
||||||
QTimer* _avatarIdentityTimer;
|
QTimer* _avatarIdentityTimer;
|
||||||
|
@ -171,6 +175,7 @@ private:
|
||||||
static QSet<ScriptEngine*> _allKnownScriptEngines;
|
static QSet<ScriptEngine*> _allKnownScriptEngines;
|
||||||
static QMutex _allScriptsMutex;
|
static QMutex _allScriptsMutex;
|
||||||
static bool _stoppingAllScripts;
|
static bool _stoppingAllScripts;
|
||||||
|
static bool _doneRunningThisScript;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ScriptEngine_h
|
#endif // hifi_ScriptEngine_h
|
||||||
|
|
Loading…
Reference in a new issue