aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Holland <dominik.holland@pelagicore.com>2018-11-28 14:14:23 +0100
committerRobert Griebl <robert.griebl@pelagicore.com>2018-11-29 12:58:56 +0000
commit1ec7e3a9c84b4f15a7ea5dc74c870919183bc7c8 (patch)
treefbe25287299e195d5743101b723753e92e8c4137
parent529ead91c4ffbe868d7d607666ea649af7bd3467 (diff)
Add support for overriding the simulation/data-file at runtime
The QIviSimulationEngine can now take an extra identifier in the constructor which is used to identify override settings for this simulation engine. Using the following environment variable schema it is possible to set and override which the simulation engine will use instead of the compiled in simulation/data-file. QTIVI_SIMULATION_OVERRIDE=<identifier>=<QML-file> QTIVI_SIMULATION_DATA_OVERRIDE=<identifier>=<JSON-file> Change-Id: Id2a921d8b74c619ea9662d413f0a7296de949b91 Fixes: AUTOSUITE-703 Reviewed-by: Robert Griebl <robert.griebl@pelagicore.com>
-rw-r--r--src/ivicore/qivisimulationengine.cpp92
-rw-r--r--src/ivicore/qivisimulationengine.h4
-rw-r--r--src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl2
3 files changed, 91 insertions, 7 deletions
diff --git a/src/ivicore/qivisimulationengine.cpp b/src/ivicore/qivisimulationengine.cpp
index 12bc04b..b83e387 100644
--- a/src/ivicore/qivisimulationengine.cpp
+++ b/src/ivicore/qivisimulationengine.cpp
@@ -48,9 +48,71 @@
#include <QDebug>
#include <QQmlContext>
#include <QLoggingCategory>
+#include <QRegularExpression>
QT_BEGIN_NAMESPACE
+namespace qtivi_helper {
+ static const QString qrcUrlLiteral = QStringLiteral("qrc:");
+ static const QString qrcLiteral = QStringLiteral("qrc");
+ static const QString resourceLiteral = QStringLiteral(":/");
+
+ QUrl toQmlUrl(const QString &path) {
+ if (path.startsWith(qrcUrlLiteral))
+ return path;
+ else if (path.startsWith(resourceLiteral))
+ return QString(path).prepend(qrcLiteral);
+ return path;
+ }
+
+ class QIviSimulationOverrideParser {
+ public:
+ static QIviSimulationOverrideParser* instance() {
+ static QIviSimulationOverrideParser* s_parser = new QIviSimulationOverrideParser();
+ return s_parser;
+ }
+
+ QHash<QString, QString> simulationOverrides;
+ QHash<QString, QString> simulationDataOverrides;
+
+ private:
+ QIviSimulationOverrideParser() {
+ parseEnv(qgetenv("QTIVI_SIMULATION_OVERRIDE"), simulationOverrides);
+ parseEnv(qgetenv("QTIVI_SIMULATION_DATA_OVERRIDE"), simulationDataOverrides);
+ }
+
+ void parseEnv(const QByteArray &rulesSrc, QHash<QString, QString> &hash) {
+ const QString content = QString::fromLocal8Bit(rulesSrc);
+ const auto lines = content.splitRef(QLatin1Char(';'));
+ for (auto line : lines) {
+ // Remove whitespace at start and end of line:
+ line = line.trimmed();
+
+ int equalPos = line.indexOf(QLatin1Char('='));
+ if (equalPos != -1) {
+ if (line.lastIndexOf(QLatin1Char('=')) == equalPos) {
+ const auto key = line.left(equalPos).trimmed();
+ const auto valueStr = line.mid(equalPos + 1).trimmed();
+
+ auto fixedStr = valueStr;
+ if (fixedStr.startsWith(qrcUrlLiteral))
+ fixedStr = fixedStr.mid(3);
+
+ if (QFile::exists(fixedStr.toString()))
+ hash.insert(key.toString(), valueStr.toString());
+ else
+ qCWarning(qLcIviSimulationEngine, "Ignoring malformed override: File does not exist: '%s'", fixedStr.toUtf8().constData());
+ } else {
+ qCWarning(qLcIviSimulationEngine, "Ignoring malformed override: '%s'", line.toUtf8().constData());
+ }
+ }
+ }
+ }
+ };
+}
+
+using namespace qtivi_helper;
+
/*!
\class QIviSimulationEngine
\inmodule QtIviCore
@@ -221,19 +283,31 @@ QT_BEGIN_NAMESPACE
*/
QIviSimulationEngine::QIviSimulationEngine(QObject *parent)
+ : QIviSimulationEngine(QString(), parent)
+{
+}
+
+QIviSimulationEngine::QIviSimulationEngine(const QString &identifier, QObject *parent)
: QQmlApplicationEngine (parent)
, m_globalObject(new QIviSimulationGlobalObject)
+ , m_identifier(identifier)
{
rootContext()->setContextProperty(QStringLiteral("IviSimulator"), m_globalObject);
}
void QIviSimulationEngine::loadSimulationData(const QString &dataFile)
{
- qCDebug(qLcIviSimulationEngine) << "loading SimulationData" << dataFile;
+ QString filePath = dataFile;
+ if (!m_identifier.isEmpty() && QIviSimulationOverrideParser::instance()->simulationDataOverrides.contains(m_identifier)) {
+ filePath = QIviSimulationOverrideParser::instance()->simulationDataOverrides.value(m_identifier);
+ qCWarning(qLcIviSimulationEngine, "Detected matching simulation data override: %s=%s", qPrintable(m_identifier), qPrintable(filePath));
+ }
- QFile file(dataFile);
+ qCDebug(qLcIviSimulationEngine, "loading SimulationData for engine %s: %s", qPrintable(m_identifier), qPrintable(filePath));
+
+ QFile file(filePath);
if (!file.open(QFile::ReadOnly)) {
- qCCritical(qLcIviSimulationEngine, "Cannot open the simulation data file %s: %s", qPrintable(dataFile), qPrintable(file.errorString()));
+ qCCritical(qLcIviSimulationEngine, "Cannot open the simulation data file %s: %s", qPrintable(filePath), qPrintable(file.errorString()));
return;
}
@@ -241,7 +315,7 @@ void QIviSimulationEngine::loadSimulationData(const QString &dataFile)
QByteArray data = file.readAll();
QJsonDocument document = QJsonDocument::fromJson(data, &pe);
if (pe.error != QJsonParseError::NoError) {
- qCCritical(qLcIviSimulationEngine, "Error parsing the simulation data in %s: %s", qPrintable(dataFile), qPrintable(pe.errorString()));
+ qCCritical(qLcIviSimulationEngine, "Error parsing the simulation data in %s: %s", qPrintable(filePath), qPrintable(pe.errorString()));
qCCritical(qLcIviSimulationEngine, "Error context:\n %s", data.mid(qMax(pe.offset - 20, 0), 40).data());
}
m_globalObject->setSimulationData(document.toVariant());
@@ -255,7 +329,15 @@ void QIviSimulationEngine::loadSimulationData(const QString &dataFile)
*/
void QIviSimulationEngine::loadSimulation(const QUrl &file)
{
- load(file);
+ QUrl filePath = file.toLocalFile();
+ if (!m_identifier.isEmpty() && QIviSimulationOverrideParser::instance()->simulationOverrides.contains(m_identifier)) {
+ filePath = toQmlUrl(QIviSimulationOverrideParser::instance()->simulationOverrides.value(m_identifier));
+ qCWarning(qLcIviSimulationEngine, "Detected matching simulation override: %s=%s", qPrintable(m_identifier), qPrintable(filePath.toString()));
+ }
+
+ qCDebug(qLcIviSimulationEngine, "loading simulation for engine %s: %s", qPrintable(m_identifier), qPrintable(filePath.toString()));
+
+ load(filePath);
}
/*!
diff --git a/src/ivicore/qivisimulationengine.h b/src/ivicore/qivisimulationengine.h
index a79d269..f0cea30 100644
--- a/src/ivicore/qivisimulationengine.h
+++ b/src/ivicore/qivisimulationengine.h
@@ -55,7 +55,8 @@ class Q_QTIVICORE_EXPORT QIviSimulationEngine : public QQmlApplicationEngine
{
Q_OBJECT
public:
- QIviSimulationEngine(QObject *parent = nullptr);
+ explicit QIviSimulationEngine(QObject *parent = nullptr);
+ explicit QIviSimulationEngine(const QString &identifier, QObject *parent = nullptr);
template <typename T> void registerSimulationInstance(T* instance, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
@@ -69,6 +70,7 @@ public:
private:
QIviSimulationGlobalObject *m_globalObject;
+ QString m_identifier;
};
QT_END_NAMESPACE
diff --git a/src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl b/src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl
index 39b67ae..446e07e 100644
--- a/src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl
+++ b/src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl
@@ -63,7 +63,7 @@ extern {{class}}::InterfaceBuilder {{module.tags.config.interfaceBuilder}};
/*! \internal */
{{class}}::{{class}}(QObject *parent)
: QObject(parent)
- , m_simulationEngine(new QIviSimulationEngine(this))
+ , m_simulationEngine(new QIviSimulationEngine("{{module.name|lower}}", this))
{
{% if module.tags.config.interfaceBuilder %}
m_interfaces = {{module.tags.config.interfaceBuilder}}(this);