summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJanne Kangas <janne.kangas@qt.io>2019-05-14 11:02:30 +0300
committerJanne Kangas <janne.kangas@qt.io>2019-06-05 10:55:03 +0300
commitf5819c8149ecef193619cbd33589a5652fd79ee6 (patch)
treec74f04765c40034b2683999e27b1c61dcadb3de3
parent0cc10ec7d2c15f8c7ce531bee23ad9ca7e0557cc (diff)
Implement datainput metadata getter
Implement metadata for both C++ and QML APIs. As a basic rule, defer to viewer app as metadata source whenever possible. For QML side separated by asynchronous command queue, fetch metadata at UIA load and store it locally in datainput and/or presentation items. Task-id: QT3DS-3579 Change-Id: Ife323f427da301ee8e6bfe9a9dccfe599ee2e5dd Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r--src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.cpp52
-rw-r--r--src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.h3
-rw-r--r--src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput_p.h6
-rw-r--r--src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.cpp86
-rw-r--r--src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.h2
-rw-r--r--src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation_p.h2
-rw-r--r--src/Runtime/ogl-runtime/src/api/studio3dqml/q3dsrenderer.cpp2
-rw-r--r--src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.cpp9
-rw-r--r--src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.h1
-rw-r--r--src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.cpp30
-rw-r--r--src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.h4
-rw-r--r--src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.cpp8
-rw-r--r--src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.h1
13 files changed, 198 insertions, 8 deletions
diff --git a/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.cpp b/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.cpp
index 2e6281e6..a15f9fb7 100644
--- a/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.cpp
+++ b/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.cpp
@@ -257,8 +257,56 @@ bool Q3DSDataInput::isValid() const
}
/*!
- \brief Q3DSDataInput::setValue Set value of the data input.
- \param value New value to be set.
+ Returns the metadata defined for this datainput with metadata \a key.
+
+ Metadata is user-defined key-value table that can be used, for example, to better describe the
+ usage of, or to indicate the external data source that should be bound to this datainput.
+ Metadata has no impact on presentation rendering.
+
+ \note Datainput metadata is read-only.
+ */
+/*!
+ \qmlmethod string DataInput::metadata
+ Returns the metadata defined for this datainput with metadata \a key.
+
+ Metadata is user-defined key-value table that can be used, for example, to better describe the
+ usage of, or to indicate the external data source that should be bound to this datainput.
+ Metadata has no impact on presentation rendering.
+
+ \note Datainput metadata is read-only.
+ */
+QString Q3DSDataInput::metadata(const QString &key) const
+{
+ if (!d_ptr->m_presentation)
+ return {};
+
+ auto metadata = d_ptr->m_presentation->d_ptr->dataInputMetadata(name());
+
+ return metadata[key];
+}
+
+/*!
+ Returns the metadata keys defined for this datainput.
+
+ \sa metadata
+ */
+/*!
+ \qmlmethod var DataInput::metadataKeys
+ Returns the metadata keys defined for this datainput.
+
+ \note Datainput metadata is read-only.
+ \sa metadata
+ */
+QStringList Q3DSDataInput::metadataKeys() const
+{
+ if (!d_ptr->m_presentation)
+ return {};
+
+ return d_ptr->m_presentation->d_ptr->dataInputMetadata(name()).keys();
+}
+
+/*!
+ \brief Q3DSDataInput::setValue Set a new \a value for this data input.
\note For performance reasons do not call setValue unnecessarily.
*/
void Q3DSDataInput::setValue(const QVariant &value)
diff --git a/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.h b/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.h
index 4504e5d2..3617dcd1 100644
--- a/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.h
+++ b/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput.h
@@ -68,6 +68,9 @@ public:
float max() const;
bool isValid() const;
+ Q_INVOKABLE QString metadata(const QString &key) const;
+ Q_INVOKABLE QStringList metadataKeys() const;
+
public Q_SLOTS:
void setName(const QString &name);
void setValue(const QVariant &value);
diff --git a/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput_p.h b/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput_p.h
index 6107add9..19b06f9d 100644
--- a/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput_p.h
+++ b/src/Runtime/ogl-runtime/src/api/studio3d/q3dsdatainput_p.h
@@ -74,6 +74,12 @@ protected:
float m_max = 0;
float m_min = 0;
+ // Note: Qt3d Runtime allows metadata to be both read and set, therefore requiring
+ // internal representation of both keys and values to be QVariant as per API convention.
+ // OpenGL Runtime, in contrast, only allows metadata to be read. As metadata now can only
+ // come from UIA file where it is stored as string, we use QStrings in API as well.
+ QHash<QString, QString> m_metadata;
+
friend class Q3DSPresentationPrivate;
friend class Q3DSRenderer;
};
diff --git a/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.cpp b/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.cpp
index f6de2fd8..59bd91a4 100644
--- a/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.cpp
+++ b/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.cpp
@@ -305,6 +305,7 @@ Q3DSDataOutput *Q3DSPresentation::registeredDataOutput(const QString &name) cons
QVector<Q3DSDataInput *> Q3DSPresentation::dataInputs() const
{
QVector<Q3DSDataInput *> ret;
+ // Just return local datainput list
const auto datainputs = d_ptr->m_dataInputs;
for (const auto &it : datainputs)
ret.append(it);
@@ -313,7 +314,7 @@ QVector<Q3DSDataInput *> Q3DSPresentation::dataInputs() const
}
/*!
- \qmlmethod variant Presentation::getDataInputs
+ \qmlmethod var Presentation::getDataInputs
Returns a list of datainputs defined for this presentation. Use setDataInputValue()
interface to set a datainput value using datainput name, or call Q3DSDataInput::setValue
directly for a specific datainput.
@@ -341,6 +342,46 @@ QVariantList Q3DSPresentation::getDataInputs() const
}
/*!
+ Returns a list of datainputs defined for this presentation that have the specified
+ \a metadataKey.
+
+ \sa setDataInputValue
+ \sa Q3DSDataInput
+ */
+
+/*!
+ \qmlmethod var Presentation::getDataInputs
+ Returns a list of datainputs defined for this presentation that have the specified
+ \a metadataKey.
+
+ \sa DataInput
+ */
+QVariantList Q3DSPresentation::getDataInputs(const QString &metadataKey) const
+{
+ QVariantList ret;
+ const auto datainputs = dataInputs(metadataKey);
+
+ for (const auto &it : datainputs)
+ ret.append(QVariant::fromValue(it));
+
+ return ret;
+}
+
+/*!
+ Returns a list of datainputs defined for this presentation that have the specified
+ \a metadataKey.
+
+ \sa setDataInputValue
+ \sa Q3DSDataInput
+ */
+QVector<Q3DSDataInput *> Q3DSPresentation::dataInputs(const QString &metadataKey) const
+{
+ // Defer to presentation item as we want to read metadata from viewer app whenever
+ // possible.
+ return d_ptr->dataInputs(metadataKey);
+}
+
+/*!
Returns a list of dataoutputs defined for this presentation. Use Qt's connect() method
to connect slots to the valueChanged() signal in the required \l{DataOutput}s to get notified
when the value tracked by the DataOutput is changed.
@@ -358,7 +399,7 @@ QVector<Q3DSDataOutput *> Q3DSPresentation::dataOutputs() const
}
/*!
- \qmlmethod variant Presentation::getDataOutputs
+ \qmlmethod var Presentation::getDataOutputs
Returns a list of dataoutputs defined for this presentation. Connect slots to the
\c{valueChanged()} signal in the required \l{DataOutput}s to get notified
@@ -1327,17 +1368,19 @@ void Q3DSPresentationPrivate::requestResponseHandler(CommandType commandType, vo
// Check and append to QML-side list if the (UIA) presentation has additional datainputs
// that are not explicitly defined in QML code.
auto receivedDI = response->at(i).value<Q3DSDataInput *>();
- // For QML behind async command queue, we cache min/max values in addition
+ // For QML behind async command queue, we cache min/max and metadata values in addition
// to name, in order to be able to return values initially set in UIA file (in QML
// getters).
if (!m_dataInputs.contains(receivedDI->name())) {
auto newDI = new Q3DSDataInput(receivedDI->name(), nullptr);
newDI->d_ptr->m_min = receivedDI->d_ptr->m_min;
newDI->d_ptr->m_max = receivedDI->d_ptr->m_max;
+ newDI->d_ptr->m_metadata = receivedDI->d_ptr->m_metadata;
registerDataInput(newDI);
} else {
m_dataInputs[receivedDI->name()]->d_ptr->m_min = receivedDI->d_ptr->m_min;
m_dataInputs[receivedDI->name()]->d_ptr->m_max = receivedDI->d_ptr->m_max;
+ m_dataInputs[receivedDI->name()]->d_ptr->m_metadata = receivedDI->d_ptr->m_metadata;
}
}
delete response;
@@ -1504,6 +1547,43 @@ float Q3DSPresentationPrivate::dataInputMax(const QString &name) const
return m_viewerApp->dataInputMax(name);
}
+QHash<QString, QString> Q3DSPresentationPrivate::dataInputMetadata(const QString &name) const
+{
+ // For QML instance separated from runtime engine by command queue,
+ // return locally cached value (initialised at presentation load).
+ if (!m_viewerApp) {
+ if (m_dataInputs.contains(name))
+ return m_dataInputs[name]->d_ptr->m_metadata;
+ else
+ return {};
+ }
+ return m_viewerApp->dataInputMetadata(name);
+}
+
+QVector<Q3DSDataInput *> Q3DSPresentationPrivate::dataInputs(const QString &key) const
+{
+ QVector<Q3DSDataInput *> ret;
+ // For QML instance separated from runtime engine by command queue,
+ // return locally cached value (initialised at presentation load).
+ if (!m_viewerApp) {
+ for (const auto &it : m_dataInputs) {
+ if (it->metadataKeys().contains(key))
+ ret.append(it);
+ }
+ } else {
+ // Otherwise, defer to viewer app.
+ const auto &diList = m_viewerApp->dataInputs();
+ // We fetch the metadata(s) from the source (viewer app) but
+ // return the corresponding datainput object(s) held by presentation item.
+ for (const auto &it : diList) {
+ if (m_viewerApp->dataInputMetadata(it).contains(key))
+ ret.append(m_dataInputs[it]);
+ }
+ }
+
+ return ret;
+}
+
void Q3DSPresentationPrivate::registerDataOutput(Q3DSDataOutput *dataOutput)
{
Q_ASSERT(!dataOutput->name().isEmpty());
diff --git a/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.h b/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.h
index 436e6844..4566443d 100644
--- a/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.h
+++ b/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation.h
@@ -76,6 +76,8 @@ public:
Q_INVOKABLE QVariantList getDataInputs() const;
QVector<Q3DSDataInput *> dataInputs() const;
+ Q_INVOKABLE QVariantList getDataInputs(const QString &metadataKey) const;
+ QVector<Q3DSDataInput *> dataInputs(const QString &metadataKey) const;
Q_INVOKABLE QVariantList getDataOutputs() const;
QVector<Q3DSDataOutput *> dataOutputs() const;
diff --git a/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation_p.h b/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation_p.h
index 7b4877d9..c30eb82d 100644
--- a/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation_p.h
+++ b/src/Runtime/ogl-runtime/src/api/studio3d/q3dspresentation_p.h
@@ -86,6 +86,8 @@ public:
bool isValidDataInput(const Q3DSDataInput *dataInput) const;
float dataInputMin(const QString &name) const;
float dataInputMax(const QString &name) const;
+ QHash<QString, QString> dataInputMetadata(const QString &name) const;
+ QVector<Q3DSDataInput *> dataInputs(const QString &key) const;
bool isValidDataOutput(const Q3DSDataOutput *dataOutput) const;
ViewerQmlStreamProxy *streamProxy();
diff --git a/src/Runtime/ogl-runtime/src/api/studio3dqml/q3dsrenderer.cpp b/src/Runtime/ogl-runtime/src/api/studio3dqml/q3dsrenderer.cpp
index bbfee502..4bd8ed0a 100644
--- a/src/Runtime/ogl-runtime/src/api/studio3dqml/q3dsrenderer.cpp
+++ b/src/Runtime/ogl-runtime/src/api/studio3dqml/q3dsrenderer.cpp
@@ -421,7 +421,7 @@ void Q3DSRenderer::processCommands()
Q3DSDataInput *newIt = new Q3DSDataInput(it, nullptr);
newIt->d_ptr->m_max = m_runtime->dataInputMax(it);
newIt->d_ptr->m_min = m_runtime->dataInputMin(it);
-
+ newIt->d_ptr->m_metadata = m_runtime->dataInputMetadata(it);
requestData->append(QVariant::fromValue(newIt));
}
}
diff --git a/src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.cpp b/src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.cpp
index fc6c3cac..5b79234c 100644
--- a/src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.cpp
+++ b/src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.cpp
@@ -212,6 +212,7 @@ public:
QList<QString> dataOutputs() const override;
float dataInputMax(const QString &name) const override;
float dataInputMin(const QString &name) const override;
+ QHash<QString, QString> dataInputMetadata(const QString &name) const override;
void createElements(const QString &parentElementPath, const QString &slideName,
const QVector<QHash<QString, QVariant>> &properties) override;
@@ -637,6 +638,14 @@ float CRuntimeView::dataInputMin(const QString &name) const
return 0;
}
+QHash<QString, QString> CRuntimeView::dataInputMetadata(const QString &name) const
+{
+ if (m_Application)
+ return m_Application->dataInputMetadata(name);
+
+ return {};
+}
+
void CRuntimeView::createElements(const QString &parentElementPath, const QString &slideName,
const QVector<QHash<QString, QVariant>> &properties)
{
diff --git a/src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.h b/src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.h
index 9ade9c7f..6d0e45cb 100644
--- a/src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.h
+++ b/src/Runtime/ogl-runtime/src/engine/Qt3DSRuntimeView.h
@@ -200,6 +200,7 @@ public:
virtual QList<QString> dataOutputs() const = 0;
virtual float dataInputMax(const QString &name) const = 0;
virtual float dataInputMin(const QString &name) const = 0;
+ virtual QHash<QString, QString> dataInputMetadata(const QString &name) const = 0;
virtual void createElements(const QString &parentElementPath, const QString &slideName,
const QVector<QHash<QString, QVariant>> &properties) = 0;
virtual void deleteElements(const QStringList &elementPaths) = 0;
diff --git a/src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.cpp b/src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.cpp
index 8be219c1..baa94ddd 100644
--- a/src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.cpp
+++ b/src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.cpp
@@ -1314,6 +1314,7 @@ struct SApp : public IApplication
const char8_t *name = "";
const char8_t *type = "";
const char8_t *evaluator = "";
+ const char8_t *metadataStr = "";
diDef.value = QVariant::Invalid;
inReader.UnregisteredAtt("name", name);
inReader.UnregisteredAtt("type", type);
@@ -1342,6 +1343,27 @@ struct SApp : public IApplication
diDef.evaluator = QString::fromUtf8(evaluator);
}
+ inReader.UnregisteredAtt("metadata", metadataStr);
+ QString metaData = QString(metadataStr);
+ if (!metaData.isEmpty()) {
+ auto metadataList = metaData.split(QLatin1Char('$'));
+
+ if (metadataList.size() & 1) {
+ qWarning("Malformed datainput metadata for datainput %s, cannot"
+ "parse key - value pairs. Stop parsing metadata.",
+ qUtf8Printable(name));
+ } else {
+ for (int i = 0; i < metadataList.size(); i += 2) {
+ if (metadataList[i].isEmpty()) {
+ qWarning("Malformed datainput metadata for datainput %s "
+ "- metadata key empty. Stop parsing metadata.",
+ qUtf8Printable(name));
+ break;
+ }
+ diDef.metadata.insert(metadataList[i], metadataList[i+1]);
+ }
+ }
+ }
m_dataInputDefs.insert(QString::fromUtf8(name), diDef);
// #TODO Remove below once QT3DS-3510 task has been completed.
// By default data inputs should not have data outputs, but this is needed
@@ -1439,6 +1461,11 @@ struct SApp : public IApplication
return m_dataInputDefs[name].min;
}
+ QHash<QString, QString> dataInputMetadata(const QString &name) const override
+ {
+ return m_dataInputDefs[name].metadata;
+ }
+
struct SAppXMLErrorHandler : public qt3ds::foundation::CXmlErrorHandler
{
NVFoundationBase &m_Foundation;
@@ -2117,6 +2144,9 @@ QDebug operator<<(QDebug debug, const DataInputValueRole &value)
return debug;
}
+// TODO: optionally print out also metadata, but note that it is not
+// relevant for any runtime or editor -side code debugging (strictly user-side
+// information).
QDebug operator<<(QDebug debug, const DataInputDef &value)
{
QDebugStateSaver saver(debug);
diff --git a/src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.h b/src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.h
index 39cd3c4b..f38b1821 100644
--- a/src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.h
+++ b/src/Runtime/ogl-runtime/src/runtime/Qt3DSApplication.h
@@ -123,7 +123,7 @@ struct DataInputDef
QVariant value; // most recently set value
// evaluator datainputs that need to re-evaluate when this datainput changes value
QVector<QString> dependents;
-
+ QHash<QString, QString> metadata;
};
struct DataOutputDef
@@ -186,8 +186,8 @@ public:
virtual QList<QString> dataOutputs() const = 0;
virtual float dataInputMax(const QString &name) const = 0;
-
virtual float dataInputMin(const QString &name) const = 0;
+ virtual QHash<QString, QString> dataInputMetadata(const QString &name) const = 0;
virtual void setPresentationId(const QString &id) = 0;
diff --git a/src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.cpp b/src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.cpp
index 094f140f..4c7be294 100644
--- a/src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.cpp
+++ b/src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.cpp
@@ -910,6 +910,14 @@ float Q3DSViewerApp::dataInputMin(const QString &name) const
return m_Impl.m_view->dataInputMin(name);
}
+QHash<QString, QString> Q3DSViewerApp::dataInputMetadata(const QString &name) const
+{
+ if (!m_Impl.m_view)
+ return {};
+
+ return m_Impl.m_view->dataInputMetadata(name);
+}
+
void Q3DSViewerApp::createElements(const QString &parentElementPath, const QString &slideName,
const QVector<QHash<QString, QVariant>> &properties)
{
diff --git a/src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.h b/src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.h
index 975e3b12..7a9299f2 100644
--- a/src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.h
+++ b/src/Runtime/ogl-runtime/src/viewer/Qt3DSViewerApp.h
@@ -461,6 +461,7 @@ public:
float dataInputMax(const QString &name) const;
float dataInputMin(const QString &name) const;
+ QHash<QString, QString> dataInputMetadata(const QString &name) const;
void createElements(const QString &parentElementPath, const QString &slideName,
const QVector<QHash<QString, QVariant>> &properties);