summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp10
-rw-r--r--src/remoteobjects/qremoteobjectnode.cpp27
-rw-r--r--src/remoteobjects/qremoteobjectnode.h2
-rw-r--r--src/repparser/parser.g11
-rw-r--r--tests/auto/proxy/tst_proxy.cpp79
-rw-r--r--tests/auto/repparser/tst_parser.cpp11
6 files changed, 133 insertions, 7 deletions
diff --git a/src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp b/src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp
index 0b84975..27851c8 100644
--- a/src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp
+++ b/src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp
@@ -383,6 +383,16 @@ void QAbstractItemModelReplicaImplementation::handleModelResetDone(QRemoteObject
m_rootItem.columnCount = size.width();
m_headerData[0].resize(size.width());
m_headerData[1].resize(size.height());
+ {
+ QVector<CacheEntry> &headerEntries = m_headerData[0];
+ for (int i = 0; i < size.width(); ++i )
+ headerEntries[i].data.clear();
+ }
+ {
+ QVector<CacheEntry> &headerEntries = m_headerData[1];
+ for (int i = 0; i < size.height(); ++i )
+ headerEntries[i].data.clear();
+ }
if (m_initialAction == QtRemoteObjects::PrefetchData) {
auto entries = watcher->returnValue().value<MetaAndDataEntries>();
for (int i = 0; i < entries.data.size(); ++i)
diff --git a/src/remoteobjects/qremoteobjectnode.cpp b/src/remoteobjects/qremoteobjectnode.cpp
index c2fba06..3b87605 100644
--- a/src/remoteobjects/qremoteobjectnode.cpp
+++ b/src/remoteobjects/qremoteobjectnode.cpp
@@ -437,9 +437,10 @@ bool QRemoteObjectHostBase::proxy(const QUrl &registryUrl, const QUrl &hostUrl,
// myInternalHost is a node only visible on the device...
QRemoteObjectHost myInternalHost("local:MyHost");
- // Regular host node, listening on port 12123, so visible to other
- // devices
- QRemoteObjectHost proxyNode("tcp://localhost:12123");
+ // RegistryHost node, listening on port 12123, so visible to other
+ // devices. The node must be a RegistryHost, so the Sources on
+ // the "outside" network can be forwarded to the inner network.
+ QRemoteObjectRegistryHost proxyNode("tcp://localhost:12123");
// Enable proxying objects from nodes on the local machine's internal
// QtRO bus. Note the hostUrl parameter is now needed.
@@ -2414,7 +2415,11 @@ ProxyInfo::~ProxyInfo() {
bool ProxyInfo::setReverseProxy(QRemoteObjectHostBase::RemoteObjectNameFilter filter)
{
- const auto registry = proxyNode->registry();
+ if (qobject_cast<QRemoteObjectRegistryHost *>(parentNode) == nullptr) {
+ qWarning() << "Setting up reverseProxy() can only be done on a Registry node.";
+ return false;
+ }
+ const auto registry = parentNode->registry();
this->reverseFilter = filter;
connect(registry, &QRemoteObjectRegistry::remoteObjectAdded, this,
@@ -2439,12 +2444,17 @@ bool ProxyInfo::setReverseProxy(QRemoteObjectHostBase::RemoteObjectNameFilter fi
void ProxyInfo::proxyObject(const QRemoteObjectSourceLocation &entry, ProxyDirection direction)
{
const QString name = entry.first;
- Q_ASSERT(!proxiedReplicas.contains(name));
const QString typeName = entry.second.typeName;
if (direction == ProxyDirection::Forward) {
+ // If we are using the reverse proxy, this can be called when reverse proxy objects are added
+ // Don't try to proxy those back. We can detect this because the hosting node will be our proxyNode.
+ auto host = qobject_cast<QRemoteObjectHost *>(proxyNode);
+ if (host && entry.second.hostUrl == host->hostUrl())
+ return;
if (!proxyFilter(name, typeName))
return;
+ Q_ASSERT(!proxiedReplicas.contains(name));
qCDebug(QT_REMOTEOBJECT) << "Starting proxy for" << name << "from" << entry.second.hostUrl;
@@ -2460,8 +2470,15 @@ void ProxyInfo::proxyObject(const QRemoteObjectSourceLocation &entry, ProxyDirec
[rep, name, this]() { this->parentNode->enableRemoting(rep, name); });
}
} else {
+ // If we are using the reverse proxy, this can be called when proxy objects are added
+ // Don't try to proxy those back. We can detect this because the hosting node will be the parentNode.
+ // Since we know the parentNode has to be a RegistryNode for reverse proxy to work, we compare against
+ // the registryUrl().
+ if (entry.second.hostUrl == parentNode->registryUrl())
+ return;
if (!reverseFilter(name, typeName))
return;
+ Q_ASSERT(!proxiedReplicas.contains(name));
qCDebug(QT_REMOTEOBJECT) << "Starting reverse proxy for" << name << "from" << entry.second.hostUrl;
diff --git a/src/remoteobjects/qremoteobjectnode.h b/src/remoteobjects/qremoteobjectnode.h
index d69b369..ae63d61 100644
--- a/src/remoteobjects/qremoteobjectnode.h
+++ b/src/remoteobjects/qremoteobjectnode.h
@@ -189,6 +189,8 @@ public:
typedef std::function<bool(const QString &, const QString &)> RemoteObjectNameFilter;
bool proxy(const QUrl &registryUrl, const QUrl &hostUrl={},
RemoteObjectNameFilter filter=[](const QString &, const QString &) {return true; });
+ // ### Qt 6: Fix -> This should only be part of the QRemoteObjectRegistryHost type, since the
+ // reverse aspect requires the registry.
bool reverseProxy(RemoteObjectNameFilter filter=[](const QString &, const QString &) {return true; });
protected:
diff --git a/src/repparser/parser.g b/src/repparser/parser.g
index 2930de3..6208c37 100644
--- a/src/repparser/parser.g
+++ b/src/repparser/parser.g
@@ -512,12 +512,19 @@ bool RepParser::parseProperty(ASTClass &astClass, const QString &propertyDeclara
propertyName = input.left(equalSignIndex).trimmed();
input = input.mid(equalSignIndex + 1).trimmed();
+ const int lastQuoteIndex = input.lastIndexOf(QLatin1Char('"'));
+ if (lastQuoteIndex != -1) {
+ propertyDefaultValue = input.left(lastQuoteIndex + 1);
+ input = input.mid(lastQuoteIndex + 1);
+ }
const int whitespaceIndex = input.indexOf(whitespace);
if (whitespaceIndex == -1) { // no flag given
- propertyDefaultValue = input;
+ if (propertyDefaultValue.isEmpty())
+ propertyDefaultValue = input;
propertyModifier = ASTProperty::ReadPush;
} else { // flag given
- propertyDefaultValue = input.left(whitespaceIndex).trimmed();
+ if (propertyDefaultValue.isEmpty())
+ propertyDefaultValue = input.left(whitespaceIndex).trimmed();
const QString flag = input.mid(whitespaceIndex + 1).trimmed();
if (!parseModifierFlag(flag, propertyModifier, persisted))
diff --git a/tests/auto/proxy/tst_proxy.cpp b/tests/auto/proxy/tst_proxy.cpp
index 79e1adf..aa914bc 100644
--- a/tests/auto/proxy/tst_proxy.cpp
+++ b/tests/auto/proxy/tst_proxy.cpp
@@ -36,7 +36,10 @@
const QUrl localHostUrl = QUrl(QLatin1String("local:testHost"));
const QUrl tcpHostUrl = QUrl(QLatin1String("tcp://127.0.0.1:9989"));
+const QUrl proxyNodeUrl = QUrl(QLatin1String("tcp://127.0.0.1:12123"));
+const QUrl remoteNodeUrl = QUrl(QLatin1String("tcp://127.0.0.1:23234"));
const QUrl registryUrl = QUrl(QLatin1String("local:testRegistry"));
+const QUrl proxyHostUrl = QUrl(QLatin1String("local:fromProxy"));
#define SET_NODE_NAME(obj) (obj).setName(QLatin1String(#obj))
@@ -52,6 +55,8 @@ private Q_SLOTS:
void testProxy_data();
void testProxy();
+ void testForwardProxy();
+ void testReverseProxy();
// The following should fail to compile, verifying the SourceAPI templates work
// for subclasses
/*
@@ -349,6 +354,80 @@ void ProxyTest::testProxy()
replica.reset();
}
+void ProxyTest::testForwardProxy()
+{
+ // Setup Local Registry
+ QRemoteObjectRegistryHost registry(registryUrl);
+ SET_NODE_NAME(registry);
+
+ // Setup Local Host
+ QRemoteObjectHost host(localHostUrl, registryUrl);
+ SET_NODE_NAME(host);
+
+ // Setup Proxy
+ QRemoteObjectRegistryHost proxyNode(proxyNodeUrl);
+ SET_NODE_NAME(proxyNode);
+ proxyNode.proxy(registryUrl, proxyHostUrl);
+ // Include the reverseProxy to make sure we don't try to send back
+ // proxied objects.
+ proxyNode.reverseProxy();
+
+ // Setup Source
+ EngineSimpleSource engine;
+ engine.setRpm(1234);
+
+ // Setup Remote Node
+ QRemoteObjectHost remoteNode(remoteNodeUrl);
+ SET_NODE_NAME(remoteNode);
+ remoteNode.connectToNode(proxyNodeUrl);
+
+ // Add source
+ host.enableRemoting(&engine);
+
+ // Setup Replica
+ const QScopedPointer<EngineReplica> replica(remoteNode.acquire<EngineReplica>());
+ QVERIFY(replica->waitForSource(1000));
+
+ // Compare Replica to Source
+ QCOMPARE(replica->rpm(), engine.rpm());
+}
+
+void ProxyTest::testReverseProxy()
+{
+ // Setup Local Registry
+ QRemoteObjectRegistryHost registry(registryUrl);
+ SET_NODE_NAME(registry);
+
+ // Setup Local Host
+ QRemoteObjectHost host(localHostUrl, registryUrl);
+ SET_NODE_NAME(host);
+
+ // Setup Proxy
+ // QRemoteObjectRegistryHost proxyNode(proxyNodeUrl);
+ QRemoteObjectRegistryHost proxyNode(proxyNodeUrl);
+ SET_NODE_NAME(proxyNode);
+ proxyNode.proxy(registryUrl, proxyHostUrl);
+ proxyNode.reverseProxy();
+
+ // Setup Source
+ EngineSimpleSource engine;
+ engine.setRpm(1234);
+
+ // Setup Remote Node
+ QRemoteObjectHost remoteNode(remoteNodeUrl, proxyNodeUrl);
+ SET_NODE_NAME(remoteNode);
+
+ // Add source
+ remoteNode.enableRemoting(&engine);
+
+ // Setup Replica
+ const QScopedPointer<EngineReplica> replica(host.acquire<EngineReplica>());
+ QVERIFY(replica->waitForSource(1000));
+
+ //Compare Replica to Source
+ QCOMPARE(replica->rpm(), engine.rpm());
+}
+
void ProxyTest::testTopLevelModel()
{
QRemoteObjectRegistryHost registry(registryUrl);
diff --git a/tests/auto/repparser/tst_parser.cpp b/tests/auto/repparser/tst_parser.cpp
index b749a15..a212059 100644
--- a/tests/auto/repparser/tst_parser.cpp
+++ b/tests/auto/repparser/tst_parser.cpp
@@ -128,6 +128,17 @@ void tst_Parser::testProperties_data()
QTest::newRow("non-int default value") << "PROP(double foo=1.1 CONSTANT)" << "double" << "foo" << "1.1" << ASTProperty::Constant << false;
QTest::newRow("tab") << "PROP(double\tfoo)" << "double" << "foo" << "" << ASTProperty::ReadPush << false;
QTest::newRow("two tabs") << "PROP(double\t\tfoo)" << "double" << "foo" << "" << ASTProperty::ReadPush << false;
+ QTest::newRow("stringWithValue") << "PROP(QString foo=\"Hello World\")" << "QString" << "foo"
+ << QString("\"Hello World\"") << ASTProperty::ReadPush << false;
+ QTest::newRow("stringWithValueWhitespaces") << "PROP(QString foo = \"Hello World\")"
+ << "QString" << "foo" << QString("\"Hello World\"")
+ << ASTProperty::ReadPush << false;
+ QTest::newRow("readonlyStringWithValueWhitespaces") << "PROP(QString foo = \"Hello World\" READONLY )"
+ << "QString" << "foo" << "\"Hello World\""
+ << ASTProperty::ReadOnly << false;
+ QTest::newRow("readonlyStringWithValue") << "PROP(QString foo=\"Hello World\" READONLY)"
+ << "QString" << "foo" << "\"Hello World\""
+ << ASTProperty::ReadOnly << false;
}
void tst_Parser::testProperties()