// stop all scripts scriptManager->stop(); scriptManager->waitTillDoneRunning(); } if (restart) { qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading"; QTimer::singleShot(RELOAD_ALL_SCRIPTS_TIMEOUT, this, [&] { _isReloading = false; }); emit scriptsReloading(); } });} bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { bool stoppedScript = false; { QUrl scriptURL = normalizeScriptURL(QUrl(rawScriptURL)); if (!scriptURL.isValid()) { scriptURL = normalizeScriptURL(QUrl::fromLocalFile(rawScriptURL)); } QReadLocker lock(&_scriptManagersHashLock); if (_scriptManagersHash.contains(scriptURL)) { ScriptManagerPointer scriptManager = _scriptManagersHash.value(scriptURL); if (restart) { bool isUserLoaded = scriptManager->isUserLoaded(); ScriptManager::Type type = scriptManager->getType(); auto scriptCache = DependencyManager::get<ScriptCache>(); scriptCache->deleteScript(scriptURL); if (!scriptManager->isStopping()) { connect(scriptManager.get(), &ScriptManager::finished, this, [this, isUserLoaded, type](QString scriptName, ScriptManagerPointer manager) { reloadScript(scriptName, isUserLoaded)->setType(type); }); } } scriptManager->stop(); stoppedScript = true; } } return stoppedScript;} void ScriptEngines::reloadLocalFiles() { _scriptsModel.reloadLocalFiles();} void ScriptEngines::reloadAllScripts() { qCDebug(scriptengine) << "reloadAllScripts -- clearing caches"; DependencyManager::get<ScriptCache>()->clearCache(); qCDebug(scriptengine) << "reloadAllScripts -- stopping all scripts"; stopAllScripts(true);} ScriptManagerPointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor, bool activateMainWindow, bool reload, bool quitWhenFinished) { if (thread() != QThread::currentThread()) { ScriptManagerPointer result { nullptr }; BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(ScriptManagerPointer, result), Q_ARG(QUrl, scriptFilename), Q_ARG(bool, isUserLoaded), Q_ARG(bool, loadScriptFromEditor), Q_ARG(bool, activateMainWindow), Q_ARG(bool, reload), Q_ARG(bool, quitWhenFinished)); return result; } QUrl scriptUrl; if (!scriptFilename.isValid() || (scriptFilename.scheme() != "http" && scriptFilename.scheme() != "https" && scriptFilename.scheme() != "atp" && scriptFilename.scheme() != "file" && scriptFilename.scheme() != "about")) { // deal with a "url" like c:/something scriptUrl = normalizeScriptURL(QUrl::fromLocalFile(scriptFilename.toString())); } else { scriptUrl = normalizeScriptURL(scriptFilename); } scriptUrl = QUrl(FileUtils::selectFile(scriptUrl.toString())); auto scriptManager = getScriptEngine(scriptUrl); if (scriptManager && !scriptManager->isStopping()) { return scriptManager; } scriptManager = scriptManagerFactory(_context, NO_SCRIPT, "about:" + scriptFilename.fileName()); scriptManager->setUserLoaded(isUserLoaded); scriptManager->setQuitWhenFinished(quitWhenFinished); if (scriptFilename.isEmpty() || !scriptUrl.isValid()) { launchScriptEngine(scriptManager); } else { // connect to the appropriate signals of this script engine connect(scriptManager.get(), &ScriptManager::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded); connect(scriptManager.get(), &ScriptManager::errorLoadingScript, this, &ScriptEngines::onScriptEngineError); // Shutdown Interface when script finishes, if requested if (quitWhenFinished) { connect(scriptManager.get(), &ScriptManager::finished, this, &ScriptEngines::quitWhenFinished); } // get the script engine object to load the script at the designated script URL scriptManager->loadURL(scriptUrl, reload); } return scriptManager;} ScriptManagerPointer ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { ScriptManagerPointer result; { QReadLocker lock(&_scriptManagersHashLock); const QUrl scriptURL = normalizeScriptURL(rawScriptURL); auto it = _scriptManagersHash.find(scriptURL); if (it != _scriptManagersHash.end()) { result = it.value(); } } return result;} // FIXME - change to new version of ScriptCache loading notificationvoid ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { UserActivityLogger::getInstance().loadedScript(rawScriptURL); ScriptManagerPointer scriptEngine = qobject_cast<ScriptManager*>(sender())->shared_from_this(); Q_ASSERT(scriptEngine != nullptr); launchScriptEngine(scriptEngine); { QWriteLocker lock(&_scriptManagersHashLock); QUrl url = QUrl(rawScriptURL); QUrl normalized = normalizeScriptURL(url); _scriptManagersHash.insert(normalized, scriptEngine); } // Update settings with new script saveScripts(); emit scriptCountChanged();} void ScriptEngines::quitWhenFinished() { qApp->quit();} int ScriptEngines::runScriptInitializers(ScriptManagerPointer scriptManager) { auto nativeCount = DependencyManager::get<ScriptInitializers>()->runScriptInitializers(scriptManager->engine().get()); return nativeCount + ScriptInitializerMixin<ScriptManagerPointer>::runScriptInitializers(scriptManager);} void ScriptEngines::launchScriptEngine(ScriptManagerPointer scriptManager) { connect(scriptManager.get(), &ScriptManager::finished, this, &ScriptEngines::onScriptFinished, Qt::DirectConnection); connect(scriptManager.get(), &ScriptManager::loadScript, [this](const QString& scriptName, bool userLoaded) { loadScript(scriptName, userLoaded); }); connect(scriptManager.get(), &ScriptManager::reloadScript, [this](const QString& scriptName, bool userLoaded) { loadScript(scriptName, userLoaded, false, false, true); }); // register our application services and set it off on its own thread runScriptInitializers(scriptManager); scriptManager->runInThread();} void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptManagerPointer manager) { bool removed = false; { QWriteLocker lock(&_scriptManagersHashLock); const QUrl scriptURL = normalizeScriptURL(QUrl(rawScriptURL)); for (auto it = _scriptManagersHash.find(scriptURL); it != _scriptManagersHash.end(); ++it) { if (it.value() == manager) { _scriptManagersHash.erase(it); removed = true; break; } } } // Could this cause deadlocks when script engine invokes a blocking method on main thread? manager->waitTillDoneRunning(); removeScriptEngine(manager); if (removed && !_isReloading) { // Update settings with removed script saveScripts(); emit scriptCountChanged(); }} // FIXME - change to new version of ScriptCache loading notificationvoid ScriptEngines::onScriptEngineError(const QString& scriptFilename) { qCDebug(scriptengine) << "Application::loadScript(), script failed to load..."; emit scriptLoadError(scriptFilename, "");} QString ScriptEngines::getDefaultScriptsLocation() const { return PathUtils::defaultScriptsLocation().toString();}Lines 501–703 of 703. Previous lines
// stop all scripts scriptManager->stop(); scriptManager->waitTillDoneRunning(); } if (restart) { qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading"; QTimer::singleShot(RELOAD_ALL_SCRIPTS_TIMEOUT, this, [&] { _isReloading = false; }); emit scriptsReloading(); } }); } bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { bool stoppedScript = false; { QUrl scriptURL = normalizeScriptURL(QUrl(rawScriptURL)); if (!scriptURL.isValid()) { scriptURL = normalizeScriptURL(QUrl::fromLocalFile(rawScriptURL)); } QReadLocker lock(&_scriptManagersHashLock); if (_scriptManagersHash.contains(scriptURL)) { ScriptManagerPointer scriptManager = _scriptManagersHash.value(scriptURL); if (restart) { bool isUserLoaded = scriptManager->isUserLoaded(); ScriptManager::Type type = scriptManager->getType(); auto scriptCache = DependencyManager::get<ScriptCache>(); scriptCache->deleteScript(scriptURL); if (!scriptManager->isStopping()) { connect(scriptManager.get(), &ScriptManager::finished, this, [this, isUserLoaded, type](QString scriptName, ScriptManagerPointer manager) { reloadScript(scriptName, isUserLoaded)->setType(type); }); } } scriptManager->stop(); stoppedScript = true; } } return stoppedScript; } void ScriptEngines::reloadLocalFiles() { _scriptsModel.reloadLocalFiles(); } void ScriptEngines::reloadAllScripts() { qCDebug(scriptengine) << "reloadAllScripts -- clearing caches"; DependencyManager::get<ScriptCache>()->clearCache(); qCDebug(scriptengine) << "reloadAllScripts -- stopping all scripts"; stopAllScripts(true); } ScriptManagerPointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor, bool activateMainWindow, bool reload, bool quitWhenFinished) { if (thread() != QThread::currentThread()) { ScriptManagerPointer result { nullptr }; BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(ScriptManagerPointer, result), Q_ARG(QUrl, scriptFilename), Q_ARG(bool, isUserLoaded), Q_ARG(bool, loadScriptFromEditor), Q_ARG(bool, activateMainWindow), Q_ARG(bool, reload), Q_ARG(bool, quitWhenFinished)); return result; } QUrl scriptUrl; if (!scriptFilename.isValid() || (scriptFilename.scheme() != "http" && scriptFilename.scheme() != "https" && scriptFilename.scheme() != "atp" && scriptFilename.scheme() != "file" && scriptFilename.scheme() != "about")) { // deal with a "url" like c:/something scriptUrl = normalizeScriptURL(QUrl::fromLocalFile(scriptFilename.toString())); } else { scriptUrl = normalizeScriptURL(scriptFilename); } scriptUrl = QUrl(FileUtils::selectFile(scriptUrl.toString())); auto scriptManager = getScriptEngine(scriptUrl); if (scriptManager && !scriptManager->isStopping()) { return scriptManager; } scriptManager = scriptManagerFactory(_context, NO_SCRIPT, "about:" + scriptFilename.fileName()); scriptManager->setUserLoaded(isUserLoaded); scriptManager->setQuitWhenFinished(quitWhenFinished); if (scriptFilename.isEmpty() || !scriptUrl.isValid()) { launchScriptEngine(scriptManager); } else { // connect to the appropriate signals of this script engine connect(scriptManager.get(), &ScriptManager::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded); connect(scriptManager.get(), &ScriptManager::errorLoadingScript, this, &ScriptEngines::onScriptEngineError); // Shutdown Interface when script finishes, if requested if (quitWhenFinished) { connect(scriptManager.get(), &ScriptManager::finished, this, &ScriptEngines::quitWhenFinished); } // get the script engine object to load the script at the designated script URL scriptManager->loadURL(scriptUrl, reload); } return scriptManager; } ScriptManagerPointer ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { ScriptManagerPointer result; { QReadLocker lock(&_scriptManagersHashLock); const QUrl scriptURL = normalizeScriptURL(rawScriptURL); auto it = _scriptManagersHash.find(scriptURL); if (it != _scriptManagersHash.end()) { result = it.value(); } } return result; } // FIXME - change to new version of ScriptCache loading notification void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { UserActivityLogger::getInstance().loadedScript(rawScriptURL); ScriptManagerPointer scriptEngine = qobject_cast<ScriptManager*>(sender())->shared_from_this(); Q_ASSERT(scriptEngine != nullptr); launchScriptEngine(scriptEngine); { QWriteLocker lock(&_scriptManagersHashLock); QUrl url = QUrl(rawScriptURL); QUrl normalized = normalizeScriptURL(url); _scriptManagersHash.insert(normalized, scriptEngine); } // Update settings with new script saveScripts(); emit scriptCountChanged(); } void ScriptEngines::quitWhenFinished() { qApp->quit(); } int ScriptEngines::runScriptInitializers(ScriptManagerPointer scriptManager) { auto nativeCount = DependencyManager::get<ScriptInitializers>()->runScriptInitializers(scriptManager->engine().get()); return nativeCount + ScriptInitializerMixin<ScriptManagerPointer>::runScriptInitializers(scriptManager); } void ScriptEngines::launchScriptEngine(ScriptManagerPointer scriptManager) { connect(scriptManager.get(), &ScriptManager::finished, this, &ScriptEngines::onScriptFinished, Qt::DirectConnection); connect(scriptManager.get(), &ScriptManager::loadScript, [this](const QString& scriptName, bool userLoaded) { loadScript(scriptName, userLoaded); }); connect(scriptManager.get(), &ScriptManager::reloadScript, [this](const QString& scriptName, bool userLoaded) { loadScript(scriptName, userLoaded, false, false, true); }); // register our application services and set it off on its own thread runScriptInitializers(scriptManager); scriptManager->runInThread(); } void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptManagerPointer manager) { bool removed = false; { QWriteLocker lock(&_scriptManagersHashLock); const QUrl scriptURL = normalizeScriptURL(QUrl(rawScriptURL)); for (auto it = _scriptManagersHash.find(scriptURL); it != _scriptManagersHash.end(); ++it) { if (it.value() == manager) { _scriptManagersHash.erase(it); removed = true; break; } } } // Could this cause deadlocks when script engine invokes a blocking method on main thread? manager->waitTillDoneRunning(); removeScriptEngine(manager); if (removed && !_isReloading) { // Update settings with removed script saveScripts(); emit scriptCountChanged(); } } // FIXME - change to new version of ScriptCache loading notification void ScriptEngines::onScriptEngineError(const QString& scriptFilename) { qCDebug(scriptengine) << "Application::loadScript(), script failed to load..."; emit scriptLoadError(scriptFilename, ""); } QString ScriptEngines::getDefaultScriptsLocation() const { return PathUtils::defaultScriptsLocation().toString(); }