forked from qt-creator/qt-creator
QmlDesigner: Remove QmlJS usage from 3D related content
Removed unnecessary QmlJS usage from 3D importer, lights baking, and bundle importer. Also simplified bundle importer significantly and added usage of new addQuick3DImportAndView3D() function to 3D importer instead of just adding QtQuick3D import. Fixes: QDS-14922 Change-Id: I5c8a4073a146ebe3fbbc89705acffa16cb466ea6 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -12,7 +12,9 @@
|
||||
#include <rewritingexception.h>
|
||||
|
||||
#include <modelutils.h>
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
#endif
|
||||
#include <utils/async.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
@@ -52,15 +54,19 @@ QString BundleImporter::importComponent(const QString &bundleDir,
|
||||
if (!bundleImportPath.exists() && !bundleImportPath.createDir())
|
||||
return QStringLiteral("Failed to create bundle import folder: '%1'").arg(bundleImportPath.toUrlishString());
|
||||
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
bool doScan = false;
|
||||
bool doReset = false;
|
||||
#endif
|
||||
FilePath qmldirPath = bundleImportPath.pathAppended("qmldir");
|
||||
QString qmldirContent = QString::fromUtf8(qmldirPath.fileContents().value_or(QByteArray()));
|
||||
if (qmldirContent.isEmpty()) {
|
||||
qmldirContent.append("module ");
|
||||
qmldirContent.append(module);
|
||||
qmldirContent.append('\n');
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
doScan = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
FilePath qmlSourceFile = bundleImportPath.pathAppended(qmlFile);
|
||||
@@ -75,7 +81,9 @@ QString BundleImporter::importComponent(const QString &bundleDir,
|
||||
qmldirContent.append(qmlFile);
|
||||
qmldirContent.append('\n');
|
||||
qmldirPath.writeFileContents(qmldirContent.toUtf8());
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
doReset = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
QStringList allFiles;
|
||||
@@ -118,15 +126,15 @@ QString BundleImporter::importComponent(const QString &bundleDir,
|
||||
ImportData data;
|
||||
data.isImport = true;
|
||||
data.type = type;
|
||||
Import import = Import::createLibraryImport(module, "1.0");
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
model->changeImports({import}, {});
|
||||
#else
|
||||
if (doScan)
|
||||
data.pathToScan = bundleImportPath;
|
||||
else
|
||||
data.fullReset = doReset;
|
||||
|
||||
Import import = Import::createLibraryImport(module, "1.0");
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
model->changeImports({import}, {});
|
||||
#else
|
||||
if (!model->hasImport(import)) {
|
||||
if (model->possibleImports().contains(import)) {
|
||||
try {
|
||||
@@ -151,6 +159,51 @@ QString BundleImporter::importComponent(const QString &bundleDir,
|
||||
|
||||
void BundleImporter::handleImportTimer()
|
||||
{
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
auto handleFailure = [this] {
|
||||
m_importTimer.stop();
|
||||
m_importTimerCount = 0;
|
||||
|
||||
// Emit dummy finished signals for all pending types
|
||||
const QList<TypeName> pendingTypes = m_pendingImports.keys();
|
||||
for (const TypeName &pendingType : pendingTypes) {
|
||||
ImportData data = m_pendingImports.take(pendingType);
|
||||
if (data.isImport)
|
||||
emit importFinished({}, m_bundleId);
|
||||
else
|
||||
emit unimportFinished({}, m_bundleId);
|
||||
}
|
||||
m_bundleId.clear();
|
||||
};
|
||||
|
||||
auto doc = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
Model *model = doc ? doc->currentModel() : nullptr;
|
||||
if (!model || ++m_importTimerCount > 100) {
|
||||
handleFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
const QList<TypeName> keys = m_pendingImports.keys();
|
||||
for (const TypeName &type : keys) {
|
||||
ImportData &data = m_pendingImports[type];
|
||||
// Verify that code model has the new type fully available (or removed for unimport)
|
||||
NodeMetaInfo metaInfo = model->metaInfo(type);
|
||||
const bool typeComplete = metaInfo.isValid() && !metaInfo.prototypes().empty();
|
||||
if (data.isImport == typeComplete) {
|
||||
m_pendingImports.remove(type);
|
||||
if (data.isImport)
|
||||
emit importFinished(type, m_bundleId);
|
||||
else
|
||||
emit unimportFinished(metaInfo, m_bundleId);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pendingImports.isEmpty()) {
|
||||
m_bundleId.clear();
|
||||
m_importTimer.stop();
|
||||
m_importTimerCount = 0;
|
||||
}
|
||||
#else
|
||||
auto handleFailure = [this] {
|
||||
m_importTimer.stop();
|
||||
m_importTimerCount = 0;
|
||||
@@ -277,11 +330,7 @@ void BundleImporter::handleImportTimer()
|
||||
if (data.isImport == typeComplete) {
|
||||
m_pendingImports.remove(type);
|
||||
if (data.isImport)
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
emit importFinished(type, m_bundleId);
|
||||
#else
|
||||
emit importFinished(metaInfo, m_bundleId);
|
||||
#endif
|
||||
else
|
||||
emit unimportFinished(metaInfo, m_bundleId);
|
||||
}
|
||||
@@ -296,6 +345,7 @@ void BundleImporter::handleImportTimer()
|
||||
m_importTimerCount = 0;
|
||||
disconnect(m_libInfoConnection);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QVariantHash BundleImporter::loadAssetRefMap(const FilePath &bundlePath)
|
||||
@@ -411,7 +461,9 @@ QString BundleImporter::unimportComponent(const TypeName &type, const QString &q
|
||||
ImportData data;
|
||||
data.isImport = false;
|
||||
data.type = type;
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
data.fullReset = true;
|
||||
#endif
|
||||
m_pendingImports.insert(type, data);
|
||||
|
||||
m_importTimerCount = 0;
|
||||
|
@@ -7,7 +7,9 @@
|
||||
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
#include <QFuture>
|
||||
#endif
|
||||
#include <QTimer>
|
||||
#include <QVariantHash>
|
||||
|
||||
@@ -48,6 +50,13 @@ private:
|
||||
QTimer m_importTimer;
|
||||
int m_importTimerCount = 0;
|
||||
QString m_bundleId;
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
struct ImportData
|
||||
{
|
||||
bool isImport = true; // false = unimport
|
||||
TypeName type;
|
||||
};
|
||||
#else
|
||||
struct ImportData
|
||||
{
|
||||
enum State {
|
||||
@@ -66,8 +75,10 @@ private:
|
||||
State state = Starting;
|
||||
};
|
||||
|
||||
QHash<TypeName, ImportData> m_pendingImports;
|
||||
QMetaObject::Connection m_libInfoConnection;
|
||||
#endif
|
||||
|
||||
QHash<TypeName, ImportData> m_pendingImports;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -369,18 +369,20 @@ ModelNode createMaterial(AbstractView *view, const NodeMetaInfo &metaInfo)
|
||||
}
|
||||
#endif
|
||||
|
||||
void addQuick3DImportAndView3D(AbstractView *view)
|
||||
bool addQuick3DImportAndView3D(AbstractView *view, bool suppressWarningDialog)
|
||||
{
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
if (!view || !view->model() || !document || document->inFileComponentModelActive()) {
|
||||
if (!suppressWarningDialog) {
|
||||
Core::AsynchronousMessageBox::warning(Tr::tr("Failed to Add Import"),
|
||||
Tr::tr("Could not add QtQuick3D import to the document."));
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString importName{"QtQuick3D"};
|
||||
if (view->model()->hasImport(importName))
|
||||
return;
|
||||
return true;
|
||||
|
||||
view->executeInTransaction(__FUNCTION__, [&] {
|
||||
Import import = Import::createLibraryImport(importName);
|
||||
@@ -417,6 +419,7 @@ void addQuick3DImportAndView3D(AbstractView *view)
|
||||
if (!models.isEmpty())
|
||||
assignMaterialTo3dModel(view, models.at(0));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// Assigns given material to a 3D model.
|
||||
|
@@ -60,7 +60,7 @@ ModelNode createMaterial(AbstractView *view);
|
||||
void renameMaterial(const ModelNode &material, const QString &newName);
|
||||
void duplicateMaterial(AbstractView *view, const ModelNode &material);
|
||||
|
||||
void addQuick3DImportAndView3D(AbstractView *view);
|
||||
bool addQuick3DImportAndView3D(AbstractView *view, bool suppressWarningDialog = false);
|
||||
void assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode,
|
||||
const ModelNode &materialNode = {});
|
||||
|
||||
|
@@ -22,7 +22,9 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
#endif
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
@@ -283,11 +285,12 @@ void BakeLights::exposeModelsAndLights(const QString &nodeId)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
QmlJS::Document::Ptr doc = rewriter.document();
|
||||
modelManager->updateDocument(doc);
|
||||
|
||||
m_view->model()->rewriterView()->forceAmend();
|
||||
#endif
|
||||
|
||||
compModel->setRewriterView({});
|
||||
|
||||
|
@@ -16,8 +16,11 @@
|
||||
#include "viewmanager.h"
|
||||
|
||||
#include <modelutils.h>
|
||||
#include <utils3d.h>
|
||||
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
#endif
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/async.h>
|
||||
@@ -241,7 +244,6 @@ void Import3dImporter::reset()
|
||||
m_importFiles.clear();
|
||||
m_puppetProcess.reset();
|
||||
m_parseData.clear();
|
||||
m_requiredImports.clear();
|
||||
m_currentImportId = 0;
|
||||
m_puppetQueue.clear();
|
||||
m_importIdToAssetNameMap.clear();
|
||||
@@ -449,12 +451,6 @@ void Import3dImporter::postParseQuick3DAsset(ParseData &pd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add quick3D import unless it is already added
|
||||
if (impVersionMajor > 0 && (m_requiredImports.isEmpty()
|
||||
|| m_requiredImports.first() != "QtQuick3D")) {
|
||||
m_requiredImports.prepend("QtQuick3D");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -698,6 +694,11 @@ void Import3dImporter::finalizeQuick3DImport()
|
||||
addInfo(progressTitle);
|
||||
notifyProgress(0, progressTitle);
|
||||
|
||||
QTimer *timer = new QTimer(parent());
|
||||
static int counter;
|
||||
counter = 0;
|
||||
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
auto modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
QFuture<void> result;
|
||||
if (modelManager) {
|
||||
@@ -711,49 +712,17 @@ void Import3dImporter::finalizeQuick3DImport()
|
||||
true,
|
||||
true);
|
||||
}
|
||||
|
||||
// First we have to wait a while to ensure qmljs detects new files and updates its
|
||||
// internal model. Then we force amend on rewriter to trigger qmljs snapshot update.
|
||||
QTimer *timer = new QTimer(parent());
|
||||
static int counter;
|
||||
counter = 0;
|
||||
|
||||
timer->callOnTimeout([this, timer, progressTitle, model, result]() {
|
||||
if (!isCancelled()) {
|
||||
notifyProgress(++counter * 2, progressTitle);
|
||||
if (counter < 49) {
|
||||
if (counter == 1) {
|
||||
if (!Utils3D::addQuick3DImportAndView3D(model->rewriterView(), true))
|
||||
addError(tr("Failed to insert QtQuick3D import to the qml document."));
|
||||
} else if (counter < 50) {
|
||||
if (result.isCanceled() || result.isFinished())
|
||||
counter = 48; // skip to next step
|
||||
} else if (counter == 49) {
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
QmlDesignerPlugin::instance()->documentManager().resetPossibleImports();
|
||||
model->rewriterView()->forceAmend();
|
||||
try {
|
||||
RewriterTransaction transaction = model->rewriterView()->beginRewriterTransaction(
|
||||
QByteArrayLiteral("Import3dImporter::finalizeQuick3DImport"));
|
||||
bool success = ModelUtils::addImportsWithCheck(m_requiredImports, model);
|
||||
if (!success)
|
||||
addError(tr("Failed to insert import statement into qml document."));
|
||||
transaction.commit();
|
||||
#else
|
||||
const Imports &imports = model->imports();
|
||||
Imports importsToAdd;
|
||||
for (const QString &importName : std::as_const(m_requiredImports)) {
|
||||
auto hasName = [&](const auto &import) {
|
||||
return import.url() == importName || import.file() == importName;
|
||||
};
|
||||
if (!Utils::anyOf(imports, hasName)) {
|
||||
Import import = Import::createLibraryImport(importName);
|
||||
importsToAdd.push_back(import);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
model->changeImports(std::move(importsToAdd), {});
|
||||
#endif
|
||||
} catch (const RewritingException &e) {
|
||||
addError(tr("Failed to update imports: %1").arg(e.description()));
|
||||
}
|
||||
counter = 49; // skip to next step
|
||||
} else if (counter >= 50) {
|
||||
for (const ParseData &pd : std::as_const(m_parseData)) {
|
||||
if (!pd.overwrittenImports.isEmpty()) {
|
||||
@@ -766,6 +735,27 @@ void Import3dImporter::finalizeQuick3DImport()
|
||||
notifyFinished();
|
||||
model->rewriterView()->emitCustomNotification("asset_import_finished");
|
||||
}
|
||||
#else
|
||||
counter = 0;
|
||||
timer->callOnTimeout([this, timer, progressTitle, model]() {
|
||||
if (!isCancelled()) {
|
||||
notifyProgress(++counter * 50, progressTitle);
|
||||
if (counter == 1) {
|
||||
if (!Utils3D::addQuick3DImportAndView3D(model->rewriterView(), true))
|
||||
addError(tr("Failed to insert QtQuick3D import to the qml document."));
|
||||
} else if (counter > 1) {
|
||||
for (const ParseData &pd : std::as_const(m_parseData)) {
|
||||
if (!pd.overwrittenImports.isEmpty()) {
|
||||
model->rewriterView()->resetPuppet();
|
||||
model->rewriterView()->emitCustomNotification("asset_import_update");
|
||||
break;
|
||||
}
|
||||
}
|
||||
timer->stop();
|
||||
notifyFinished();
|
||||
model->rewriterView()->emitCustomNotification("asset_import_finished");
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
timer->stop();
|
||||
}
|
||||
|
@@ -126,7 +126,6 @@ private:
|
||||
QHash<int, QString> m_importIdToAssetNameMap;
|
||||
QHash<QString, ParseData> m_parseData; // Key: asset name
|
||||
QString m_progressTitle;
|
||||
QStringList m_requiredImports;
|
||||
QList<int> m_puppetQueue;
|
||||
};
|
||||
} // QmlDesigner
|
||||
|
Reference in New Issue
Block a user