1// Copyright (C) 2023 basysKom GmbH, opensource@basyskom.com
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qopcuainternaldatatypenode_p.h"
5#include "qopcuagenericstructhandler_p.h"
6
7QT_BEGIN_NAMESPACE
8
9QOpcUaInternalDataTypeNode::QOpcUaInternalDataTypeNode(QOpcUaClient *client)
10 : m_client(client)
11{
12}
13
14bool QOpcUaInternalDataTypeNode::initialize(const QString &nodeId)
15{
16 if (!m_client)
17 return false;
18
19 m_nodeId = nodeId;
20
21 m_node.reset(other: m_client->node(nodeId));
22
23 if (!m_node)
24 return false;
25
26 QObject::connect(sender: m_node.get(), signal: &QOpcUaNode::browseFinished, context: this,
27 slot: [this](const QList<QOpcUaReferenceDescription> &results, QOpcUa::UaStatusCode result) {
28 Q_UNUSED(result);
29
30 for (const auto &entry : results) {
31 auto child = new QOpcUaInternalDataTypeNode(m_client);
32 const auto success = child->initialize(nodeId: entry.targetNodeId().nodeId());
33
34 if (!success) {
35 child->deleteLater();
36 handleFinished(success: false);
37 qCWarning(lcGenericStructHandler) << "Failed to init child" << entry.browseName().name();
38 return;
39 }
40
41 m_children.push_back(x: std::unique_ptr<QOpcUaInternalDataTypeNode>(child));
42
43 QObject::connect(sender: child, signal: &QOpcUaInternalDataTypeNode::initializeFinished, context: this, slot: &QOpcUaInternalDataTypeNode::handleFinished);
44 }
45
46 const auto success = m_node->readAttributes(attributes: QOpcUa::NodeAttribute::IsAbstract |
47 QOpcUa::NodeAttribute::DataTypeDefinition |
48 QOpcUa::NodeAttribute::BrowseName);
49
50 if (!success) {
51 qCWarning(lcGenericStructHandler) << "Failed to read attributes for" << m_node->nodeId();
52 handleFinished(success: false);
53 }
54 });
55
56 QObject::connect(sender: m_node.get(), signal: &QOpcUaNode::attributeRead, context: this, slot: [this]() {
57 m_isAbstract = m_node->attribute(attribute: QOpcUa::NodeAttribute::IsAbstract).toBool();
58 m_definition = m_node->attribute(attribute: QOpcUa::NodeAttribute::DataTypeDefinition);
59 m_name = m_node->attribute(attribute: QOpcUa::NodeAttribute::BrowseName).value<QOpcUaQualifiedName>().name();
60 handleFinished(success: true);
61 });
62
63 const auto success = m_node->browseChildren(referenceType: QOpcUa::ReferenceTypeId::HasSubtype, nodeClassMask: QOpcUa::NodeClass::DataType);
64 if (!success) {
65 qCWarning(lcGenericStructHandler) << "Failed to start browse for" << m_node->nodeId();
66 handleFinished(success: false);
67 }
68
69 return success;
70}
71
72QVariant QOpcUaInternalDataTypeNode::definition() const
73{
74 return m_definition;
75}
76
77bool QOpcUaInternalDataTypeNode::isAbstract() const
78{
79 return m_isAbstract;
80}
81
82QString QOpcUaInternalDataTypeNode::name() const
83{
84 return m_name;
85}
86
87QString QOpcUaInternalDataTypeNode::nodeId() const
88{
89 return m_nodeId;
90}
91
92const std::vector<std::unique_ptr<QOpcUaInternalDataTypeNode> > &QOpcUaInternalDataTypeNode::children() const
93{
94 return m_children;
95}
96
97void QOpcUaInternalDataTypeNode::handleFinished(bool success)
98{
99 if (m_hasError)
100 return;
101
102 m_finishedCount++;
103 m_hasError = !success;
104
105 if (m_finishedCount == m_children.size() + 1 || m_hasError)
106 emit initializeFinished(success: !m_hasError);
107}
108
109QT_END_NAMESPACE
110

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtopcua/src/opcua/client/qopcuainternaldatatypenode.cpp