diff options
author | Rainer Keller <Rainer.Keller@qt.io> | 2018-08-10 10:29:26 +0200 |
---|---|---|
committer | Rainer Keller <Rainer.Keller@qt.io> | 2018-08-28 06:48:47 +0000 |
commit | cb0f4838fd65ce21df6d1b995d620ee99a5f78e9 (patch) | |
tree | d7c62ffb4fc5c87a9f59be807679f99bf39c185c /src | |
parent | 7455da9968a21b19abc4719a06da209993ee8b30 (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.pro | 8 | ||||
-rw-r--r-- | src/imports/opcua/opcuaattributecache.cpp | 86 | ||||
-rw-r--r-- | src/imports/opcua/opcuaattributecache.h | 62 | ||||
-rw-r--r-- | src/imports/opcua/opcuaattributevalue.cpp | 88 | ||||
-rw-r--r-- | src/imports/opcua/opcuaattributevalue.h | 62 | ||||
-rw-r--r-- | src/imports/opcua/opcuanode.cpp | 3 | ||||
-rw-r--r-- | src/imports/opcua/opcuanode.h | 2 | ||||
-rw-r--r-- | src/imports/opcua/opcuavaluenode.cpp | 40 | ||||
-rw-r--r-- | src/imports/opcua/opcuavaluenode.h | 5 |
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 |