summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRainer Keller <Rainer.Keller@qt.io>2018-08-10 10:29:26 +0200
committerRainer Keller <Rainer.Keller@qt.io>2018-08-28 06:48:47 +0000
commitcb0f4838fd65ce21df6d1b995d620ee99a5f78e9 (patch)
treed7c62ffb4fc5c87a9f59be807679f99bf39c185c /src
parent7455da9968a21b19abc4719a06da209993ee8b30 (diff)
qml: Introduce node attribute cache
The QOpcUaNode attributeUpdated signal is emitted even when the actual value has not changed. Change-Id: Ib8e232d03903e7442244eccf4f20b607e8c40d39 Reviewed-by: Frank Meerkoetter <frank.meerkoetter@basyskom.com>
Diffstat (limited to 'src')
-rw-r--r--src/imports/opcua/opcua.pro8
-rw-r--r--src/imports/opcua/opcuaattributecache.cpp86
-rw-r--r--src/imports/opcua/opcuaattributecache.h62
-rw-r--r--src/imports/opcua/opcuaattributevalue.cpp88
-rw-r--r--src/imports/opcua/opcuaattributevalue.h62
-rw-r--r--src/imports/opcua/opcuanode.cpp3
-rw-r--r--src/imports/opcua/opcuanode.h2
-rw-r--r--src/imports/opcua/opcuavaluenode.cpp40
-rw-r--r--src/imports/opcua/opcuavaluenode.h5
9 files changed, 312 insertions, 44 deletions
diff --git a/src/imports/opcua/opcua.pro b/src/imports/opcua/opcua.pro
index 93429b1..cfc94a4 100644
--- a/src/imports/opcua/opcua.pro
+++ b/src/imports/opcua/opcua.pro
@@ -11,7 +11,9 @@ SOURCES += \
opcuarelativenodeid.cpp \
opcuanodeidtype.cpp \
universalnode.cpp \
- opcuapathresolver.cpp
+ opcuapathresolver.cpp \
+ opcuaattributevalue.cpp \
+ opcuaattributecache.cpp
HEADERS += \
opcua_plugin.h \
@@ -24,7 +26,9 @@ HEADERS += \
opcuarelativenodeid.h \
opcuanodeidtype.h \
universalnode.h \
- opcuapathresolver.h
+ opcuapathresolver.h \
+ opcuaattributecache.h \
+ opcuaattributevalue.h
load(qml_plugin)
diff --git a/src/imports/opcua/opcuaattributecache.cpp b/src/imports/opcua/opcuaattributecache.cpp
new file mode 100644
index 0000000..b57acc8
--- /dev/null
+++ b/src/imports/opcua/opcuaattributecache.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcuaattributecache.h"
+#include "opcuaattributevalue.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class OpcUaAttributeCache
+ \inqmlmodule QtOpcUa
+ \brief Flexible attribute value cache providing signals.
+ \internal
+
+ This class is just for internal use in the declarative backend and not exposed to users.
+
+ It caches node attribute values and provides accesss. Main purpose is to
+ let \l OpcUaAttributeValue provide separate value change signals for each attribute.
+
+ \sa OpcUaAttributeValue
+*/
+
+OpcUaAttributeCache::OpcUaAttributeCache(QObject *parent) : QObject(parent)
+{
+}
+
+void OpcUaAttributeCache::setAttributeValue(QOpcUa::NodeAttribute attr, const QVariant &value)
+{
+ attribute(attr)->setValue(value);
+}
+
+void OpcUaAttributeCache::invalidate()
+{
+ // Reset all values in the cache to invalid.
+ // Do not clear() the cache because there are still objects with
+ // connections waiting for notifications
+ for (auto i = m_attributeCache.constBegin(); i != m_attributeCache.constEnd(); ++i)
+ i.value()->invalidate();
+}
+
+OpcUaAttributeValue *OpcUaAttributeCache::attribute(QOpcUa::NodeAttribute attr)
+{
+ if (!m_attributeCache.contains(attr))
+ m_attributeCache.insert(attr, new OpcUaAttributeValue(this));
+ return m_attributeCache.value(attr);
+}
+
+const QVariant &OpcUaAttributeCache::attributeValue(QOpcUa::NodeAttribute attr)
+{
+ return attribute(attr)->value();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuaattributecache.h b/src/imports/opcua/opcuaattributecache.h
new file mode 100644
index 0000000..f9a761b
--- /dev/null
+++ b/src/imports/opcua/opcuaattributecache.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+
+#include "qopcuatype.h"
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class OpcUaAttributeValue;
+
+class OpcUaAttributeCache : public QObject
+{
+ Q_OBJECT
+public:
+ explicit OpcUaAttributeCache(QObject *parent = nullptr);
+ OpcUaAttributeValue *attribute(QOpcUa::NodeAttribute attribute);
+ const QVariant &attributeValue(QOpcUa::NodeAttribute);
+
+public slots:
+ void setAttributeValue(QOpcUa::NodeAttribute attribute, const QVariant &value);
+ void invalidate();
+
+private:
+ QHash<QOpcUa::NodeAttribute, OpcUaAttributeValue *> m_attributeCache;
+};
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuaattributevalue.cpp b/src/imports/opcua/opcuaattributevalue.cpp
new file mode 100644
index 0000000..493d7d0
--- /dev/null
+++ b/src/imports/opcua/opcuaattributevalue.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcuaattributevalue.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class OpcUaAttributeValue
+ \inqmlmodule QtOpcUa
+ \brief Stores an attribute value and provides a changed signal.
+ \internal
+
+ This class is just for internal use in the declarative backend and not exposed to users.
+
+ When setting the value it will emit a changed signal if the value has changed.
+
+ \sa OpcUaAttributeCache
+*/
+
+OpcUaAttributeValue::OpcUaAttributeValue(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+bool OpcUaAttributeValue::operator ==(const OpcUaAttributeValue &rhs)
+{
+ return m_value == rhs.m_value;
+}
+
+void OpcUaAttributeValue::setValue(const QVariant &value)
+{
+ if (value != m_value) {
+ m_value = value;
+ emit changed(m_value);
+ }
+}
+
+void OpcUaAttributeValue::invalidate()
+{
+ setValue(QVariant());
+}
+
+const QVariant &OpcUaAttributeValue::value() const
+{
+ return m_value;
+}
+
+OpcUaAttributeValue::operator QVariant() const
+{
+ return value();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuaattributevalue.h b/src/imports/opcua/opcuaattributevalue.h
new file mode 100644
index 0000000..a3c073c
--- /dev/null
+++ b/src/imports/opcua/opcuaattributevalue.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QObject>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class OpcUaAttributeValue : public QObject
+{
+ Q_OBJECT
+public:
+ explicit OpcUaAttributeValue(QObject *parent);
+ bool operator ==(const OpcUaAttributeValue &rhs);
+ void setValue(const QVariant &value);
+ void invalidate();
+ const QVariant &value() const;
+ operator QVariant() const;
+
+signals:
+ void changed(QVariant value);
+
+private:
+ QVariant m_value;
+};
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuanode.cpp b/src/imports/opcua/opcuanode.cpp
index b9d9025..fdb2188 100644
--- a/src/imports/opcua/opcuanode.cpp
+++ b/src/imports/opcua/opcuanode.cpp
@@ -41,6 +41,7 @@
#include "opcuarelativenodepath.h"
#include "opcuarelativenodeid.h"
#include "opcuapathresolver.h"
+#include "opcuaattributevalue.h"
#include <QOpcUaNode>
#include <QOpcUaClient>
#include <QLoggingCategory>
@@ -192,6 +193,8 @@ void OpcUaNode::setupNode(const QString &absoluteNodePath)
qCWarning(QT_OPCUA_PLUGINS_QML) << "Invalid node:" << m_absoluteNodePath;
return;
}
+
+ connect(m_node, &QOpcUaNode::attributeUpdated, &m_attributeCache, &OpcUaAttributeCache::setAttributeValue);
}
void OpcUaNode::updateNode()
diff --git a/src/imports/opcua/opcuanode.h b/src/imports/opcua/opcuanode.h
index 821fac3..4466967 100644
--- a/src/imports/opcua/opcuanode.h
+++ b/src/imports/opcua/opcuanode.h
@@ -39,6 +39,7 @@
#include <QObject>
#include <qopcuatype.h>
#include "universalnode.h"
+#include "opcuaattributecache.h"
QT_BEGIN_NAMESPACE
@@ -85,6 +86,7 @@ protected:
QString m_absoluteNodePath; // not exposed
bool m_readyToUse = false;
UniversalNode m_resolvedNode;
+ OpcUaAttributeCache m_attributeCache;
};
QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuavaluenode.cpp b/src/imports/opcua/opcuavaluenode.cpp
index 83f9c13..98198b0 100644
--- a/src/imports/opcua/opcuavaluenode.cpp
+++ b/src/imports/opcua/opcuavaluenode.cpp
@@ -37,6 +37,7 @@
#include "opcuavaluenode.h"
#include "opcuaconnection.h"
#include "opcuanodeid.h"
+#include "opcuaattributevalue.h"
#include <QLoggingCategory>
QT_BEGIN_NAMESPACE
@@ -77,11 +78,11 @@ Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA_PLUGINS_QML)
OpcUaValueNode::OpcUaValueNode(QObject *parent):
OpcUaNode(parent)
{
+ connect(m_attributeCache.attribute(QOpcUa::NodeAttribute::Value), &OpcUaAttributeValue::changed, this, &OpcUaValueNode::valueChanged);
}
OpcUaValueNode::~OpcUaValueNode()
{
-
}
void OpcUaValueNode::setValue(const QVariant &value)
@@ -95,8 +96,7 @@ void OpcUaValueNode::setupNode(const QString &absolutePath)
if (!m_node)
return;
- connect(m_node, &QOpcUaNode::attributeRead, this, &OpcUaValueNode::handleAttributeUpdate);
- connect(m_node, &QOpcUaNode::dataChangeOccurred, this, &OpcUaValueNode::handleDataChangeOccurred);
+ connect(m_node, &QOpcUaNode::attributeRead, this, [this](){setReadyToUse(true);});
if (!m_node->readAttributes(QOpcUa::NodeAttribute::Value
| QOpcUa::NodeAttribute::NodeClass
@@ -111,40 +111,6 @@ void OpcUaValueNode::setupNode(const QString &absolutePath)
qCWarning(QT_OPCUA_PLUGINS_QML) << "Failed monitoring" << m_node->nodeId();
}
-void OpcUaValueNode::handleAttributeUpdate(QOpcUa::NodeAttributes attrs)
-{
- /*
- if (attr & QOpcUa::NodeAttribute::NodeClass)
- mNodeClass = mOpcNode->attribute(QOpcUa::NodeAttribute::NodeClass).value<QOpcUa::NodeClass>();
- if (attr & QOpcUa::NodeAttribute::BrowseName)
- mNodeBrowseName = mOpcNode->attribute(QOpcUa::NodeAttribute::BrowseName).value<QOpcUa::QQualifiedName>().name();
- if (attr & QOpcUa::NodeAttribute::DisplayName)
- mNodeDisplayName = mOpcNode->attribute(QOpcUa::NodeAttribute::DisplayName).value<QOpcUa::QLocalizedText>().text();
- if (attr & QOpcUa::NodeAttribute::NodeId)
- mNodeDisplayName = mOpcNode->attribute(QOpcUa::NodeAttribute::NodeId).toString();
- */
-
- if (attrs & QOpcUa::NodeAttribute::Value) {
- const auto value = m_node->attribute(QOpcUa::NodeAttribute::Value);
- if (value != m_cachedValue) {
- m_cachedValue = value;
- emit valueChanged(value);
- }
- }
-
- setReadyToUse();
-}
-
-void OpcUaValueNode::handleDataChangeOccurred(QOpcUa::NodeAttribute attr, QVariant value)
-{
- if (attr == QOpcUa::NodeAttribute::Value) {
- if (value != m_cachedValue) {
- m_cachedValue = value;
- emit valueChanged(value);
- }
- }
-}
-
QVariant OpcUaValueNode::value() const
{
if (!m_node)
diff --git a/src/imports/opcua/opcuavaluenode.h b/src/imports/opcua/opcuavaluenode.h
index 1d892a9..cab3474 100644
--- a/src/imports/opcua/opcuavaluenode.h
+++ b/src/imports/opcua/opcuavaluenode.h
@@ -59,11 +59,6 @@ signals:
private slots:
void setupNode(const QString &absolutePath) override;
- void handleAttributeUpdate(QOpcUa::NodeAttributes attrs);
- void handleDataChangeOccurred(QOpcUa::NodeAttribute attr, QVariant value);
-
- private:
- QVariant m_cachedValue;
};
QT_END_NAMESPACE