1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtGrpcQuick/qqmlabstractgrpcchannel.h>
5
6#include <QtGrpcQuick/private/qqmlgrpchttp2channel_p.h>
7#include <QtGrpcQuick/private/qqmlabstractgrpcchannel_p.h>
8
9#include <QtGrpc/qgrpchttp2channel.h>
10
11#include <QtCore/qdebug.h>
12
13QT_BEGIN_NAMESPACE
14
15namespace {
16#if QT_CONFIG(ssl)
17constexpr size_t QQmlGrpcChannelOptionsPropertiesCount = 4;
18#else
19constexpr size_t QQmlGrpcChannelOptionsPropertiesCount = 3;
20#endif
21}
22
23class QQmlGrpcHttp2ChannelPrivate : public QQmlAbstractGrpcChannelPrivate
24{
25public:
26 QQmlGrpcChannelOptions *options = nullptr;
27 QUrl hostUri;
28 std::shared_ptr<QAbstractGrpcChannel> channel;
29 std::array<QMetaObject::Connection, QQmlGrpcChannelOptionsPropertiesCount> optionsConnections;
30};
31
32QQmlGrpcHttp2Channel::QQmlGrpcHttp2Channel(QObject *parent)
33 : QQmlAbstractGrpcChannel(*(new QQmlGrpcHttp2ChannelPrivate), parent)
34{
35}
36
37QQmlGrpcHttp2Channel::~QQmlGrpcHttp2Channel() = default;
38
39std::shared_ptr<QAbstractGrpcChannel> QQmlGrpcHttp2Channel::channel() const
40{
41 Q_D(const QQmlGrpcHttp2Channel);
42 return d->channel;
43}
44
45void QQmlGrpcHttp2Channel::setOptions(QQmlGrpcChannelOptions *options)
46{
47 Q_D(QQmlGrpcHttp2Channel);
48 if (d->options == options)
49 return;
50
51 for (auto &connection : d->optionsConnections) {
52 if (connection) {
53 disconnect(connection);
54 connection = {};
55 }
56 }
57
58 d->options = options;
59 if (d->options) {
60 auto updateChannelOptions = [this]() {
61 Q_D(QQmlGrpcHttp2Channel);
62 if (d->channel) {
63 d->channel->setChannelOptions(d->options != nullptr ? d->options->options()
64 : QGrpcChannelOptions{});
65 }
66 emit optionsChanged();
67 };
68
69 d->optionsConnections[0] = connect(sender: d->options,
70 signal: &QQmlGrpcChannelOptions::deadlineTimeoutChanged, context: this,
71 slot&: updateChannelOptions);
72 d->optionsConnections[1] = connect(sender: d->options, signal: &QQmlGrpcChannelOptions::metadataChanged,
73 context: this, slot&: updateChannelOptions);
74 d->optionsConnections[2] = connect(sender: d->options,
75 signal: &QQmlGrpcChannelOptions::serializationFormatChanged,
76 context: this, slot&: updateChannelOptions);
77#if QT_CONFIG(ssl)
78 d->optionsConnections[3] = connect(sender: d->options,
79 signal: &QQmlGrpcChannelOptions::sslConfigurationChanged, context: this,
80 slot&: updateChannelOptions);
81#endif
82 updateChannelOptions();
83 }
84}
85
86void QQmlGrpcHttp2Channel::updateChannel()
87{
88 Q_D(QQmlGrpcHttp2Channel);
89 if (d->hostUri.isEmpty())
90 return;
91
92 if (!d->hostUri.isValid()) {
93 qWarning() << "Unable to initialize the channel. The host URI is not valid.";
94 return;
95 }
96
97 if (d->channel)
98 d->channel.reset();
99
100 if (d->hostUri.isValid()) {
101 d->channel = d->options
102 ? std::make_shared<QGrpcHttp2Channel>(args&: d->hostUri, args: d->options->options())
103 : std::make_shared<QGrpcHttp2Channel>(args&: d->hostUri);
104 }
105 emit channelUpdated();
106}
107
108void QQmlGrpcHttp2Channel::setHostUri(const QUrl &hostUri)
109{
110 Q_D(QQmlGrpcHttp2Channel);
111 if (hostUri == d->hostUri)
112 return;
113
114 if (d->channel) {
115 qWarning() << "Changing the host URI is not supported.";
116 return;
117 }
118
119 d->hostUri = hostUri;
120
121 emit hostUriChanged();
122 updateChannel();
123}
124
125QQmlGrpcChannelOptions *QQmlGrpcHttp2Channel::options() const noexcept
126{
127 Q_D(const QQmlGrpcHttp2Channel);
128 return d->options;
129}
130
131QUrl QQmlGrpcHttp2Channel::hostUri() const noexcept
132{
133 Q_D(const QQmlGrpcHttp2Channel);
134 return d->hostUri;
135}
136
137QT_END_NAMESPACE
138
139#include "moc_qqmlgrpchttp2channel_p.cpp"
140

source code of qtgrpc/src/grpcquick/qqmlgrpchttp2channel.cpp