forked from qt-creator/qt-creator
QmlDesigner: Add Effect Maker shader error propagation
In case of manual edit of shaders, this simple system detects common errors that might be found in a shader. Task-number: QDS-10499 Change-Id: I0c70ac85ef519880dcd98642c5927f037f113f94 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
#include "compositionnode.h"
|
||||
#include "uniform.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -152,4 +154,77 @@ const QString EffectMakerModel::getFSUniforms()
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// Detects common GLSL error messages and returns potential
|
||||
// additional error information related to them.
|
||||
QString EffectMakerModel::detectErrorMessage(const QString &errorMessage)
|
||||
{
|
||||
static QHash<QString, QString> nodeErrors {
|
||||
{ "'BLUR_HELPER_MAX_LEVEL' : undeclared identifier", "BlurHelper"},
|
||||
{ "'iSourceBlur1' : undeclared identifier", "BlurHelper"},
|
||||
{ "'hash23' : no matching overloaded function found", "NoiseHelper" },
|
||||
{ "'HASH_BOX_SIZE' : undeclared identifier", "NoiseHelper" },
|
||||
{ "'pseudo3dNoise' : no matching overloaded function found", "NoiseHelper" }
|
||||
};
|
||||
|
||||
QString missingNodeError = QStringLiteral("Are you missing a %1 node?\n");
|
||||
QHash<QString, QString>::const_iterator i = nodeErrors.constBegin();
|
||||
while (i != nodeErrors.constEnd()) {
|
||||
if (errorMessage.contains(i.key()))
|
||||
return missingNodeError.arg(i.value());
|
||||
++i;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Return first error message (if any)
|
||||
EffectError EffectMakerModel::effectError() const
|
||||
{
|
||||
for (const EffectError &e : std::as_const(m_effectErrors)) {
|
||||
if (!e.m_message.isEmpty())
|
||||
return e;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
// Set the effect error message with optional type and lineNumber.
|
||||
// Type comes from ErrorTypes, defaulting to common errors (-1).
|
||||
// Note that type must match with UI editor tab index.
|
||||
void EffectMakerModel::setEffectError(const QString &errorMessage, int type, int lineNumber)
|
||||
{
|
||||
EffectError error;
|
||||
error.m_type = type;
|
||||
if (type == 1 || type == 2) {
|
||||
// For shaders, get the line number from baker output.
|
||||
// Which is something like "ERROR: :15: message"
|
||||
int glslErrorLineNumber = -1;
|
||||
static QRegularExpression spaceReg("\\s+");
|
||||
QStringList errorStringList = errorMessage.split(spaceReg, Qt::SkipEmptyParts);
|
||||
if (errorStringList.size() >= 2) {
|
||||
QString lineString = errorStringList.at(1).trimmed();
|
||||
if (lineString.size() >= 3) {
|
||||
// String is ":[linenumber]:", get only the number.
|
||||
glslErrorLineNumber = lineString.sliced(1, lineString.size() - 2).toInt();
|
||||
}
|
||||
}
|
||||
error.m_line = glslErrorLineNumber;
|
||||
} else {
|
||||
// For QML (and others) use given linenumber
|
||||
error.m_line = lineNumber;
|
||||
}
|
||||
|
||||
QString additionalErrorInfo = detectErrorMessage(errorMessage);
|
||||
error.m_message = additionalErrorInfo + errorMessage;
|
||||
m_effectErrors.insert(type, error);
|
||||
Q_EMIT effectErrorChanged();
|
||||
}
|
||||
|
||||
void EffectMakerModel::resetEffectError(int type)
|
||||
{
|
||||
if (m_effectErrors.contains(type)) {
|
||||
m_effectErrors.remove(type);
|
||||
Q_EMIT effectErrorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -13,6 +13,17 @@ namespace QmlDesigner {
|
||||
class CompositionNode;
|
||||
class Uniform;
|
||||
|
||||
struct EffectError {
|
||||
Q_GADGET
|
||||
Q_PROPERTY(QString message MEMBER m_message)
|
||||
Q_PROPERTY(int line MEMBER m_line)
|
||||
Q_PROPERTY(int type MEMBER m_type)
|
||||
public:
|
||||
QString m_message;
|
||||
int m_line = -1;
|
||||
int m_type = -1;
|
||||
};
|
||||
|
||||
class EffectMakerModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -36,6 +47,7 @@ public:
|
||||
signals:
|
||||
void isEmptyChanged();
|
||||
void selectedIndexChanged(int idx);
|
||||
void effectErrorChanged();
|
||||
|
||||
private:
|
||||
enum Roles {
|
||||
@@ -51,11 +63,18 @@ private:
|
||||
const QString getVSUniforms();
|
||||
const QString getFSUniforms();
|
||||
|
||||
QString detectErrorMessage(const QString &errorMessage);
|
||||
EffectError effectError() const;
|
||||
void setEffectError(const QString &errorMessage, int type, int lineNumber);
|
||||
void resetEffectError(int type);
|
||||
|
||||
QList<CompositionNode *> m_nodes;
|
||||
|
||||
int m_selectedIndex = -1;
|
||||
bool m_isEmpty = true;
|
||||
|
||||
QMap<int, EffectError> m_effectErrors;
|
||||
|
||||
ShaderFeatures m_shaderFeatures;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user