1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QQMLGRPCFUNCTIONALHANDLERS_H
5#define QQMLGRPCFUNCTIONALHANDLERS_H
6
7#include <QtGrpcQuick/qtgrpcquickexports.h>
8
9#include <QtGrpc/qgrpccallreply.h>
10#include <QtGrpc/qgrpcstream.h>
11
12#include <QtQml/qqmlengine.h>
13
14#include <QtCore/qobject.h>
15#include <QtCore/qtconfigmacros.h>
16
17QT_BEGIN_NAMESPACE
18
19namespace QtGrpcQuickFunctional {
20
21Q_ALWAYS_INLINE void validateEngineAndOperation(QJSEngine *jsEngine, QGrpcOperation *operation)
22{
23 Q_ASSERT(jsEngine != nullptr);
24 Q_ASSERT(operation != nullptr);
25}
26
27template <typename Ret>
28std::optional<QJSValue> readMessageToJSValue(QJSEngine *jsEngine, QGrpcOperation *operation)
29{
30 QtGrpcQuickFunctional::validateEngineAndOperation(jsEngine, operation);
31
32 if (std::optional<Ret> result = operation->read<Ret>())
33 return jsEngine->toScriptValue(*result);
34 return std::nullopt;
35}
36
37Q_GRPCQUICK_EXPORT
38void handleReceivedMessageImpl(QJSEngine *jsEngine, std::optional<QJSValue> message,
39 const QJSValue &successCallback, const QJSValue &errorCallback);
40
41template <typename Ret>
42void handleReceivedMessage(QJSEngine *jsEngine, QGrpcOperation *operation,
43 const QJSValue &successCallback, const QJSValue &errorCallback)
44{
45 auto message = QtGrpcQuickFunctional::readMessageToJSValue<Ret>(jsEngine, operation);
46 QtGrpcQuickFunctional::handleReceivedMessageImpl(jsEngine, message: std::move(message), successCallback,
47 errorCallback);
48}
49
50Q_GRPCQUICK_EXPORT
51bool checkReceivedStatus(QJSEngine *jsEngine, const QGrpcStatus &status,
52 const QJSValue &errorCallback);
53
54Q_GRPCQUICK_EXPORT
55void connectMultipleReceiveOperationFinished(QJSEngine *jsEngine,
56 std::unique_ptr<QGrpcOperation> &&operation,
57 const QJSValue &successCallback,
58 const QJSValue &errorCallback);
59
60namespace Private {
61using HandleReceivedMessageImpl = void (*)(QJSEngine *jsEngine, QGrpcOperation *operation,
62 const QJSValue &successCallback,
63 const QJSValue &errorCallback);
64Q_GRPCQUICK_EXPORT
65void connectSingleReceiveOperationFinishedImpl(QJSEngine *jsEngine,
66 HandleReceivedMessageImpl impl,
67 std::unique_ptr<QGrpcOperation> &&operation,
68 const QJSValue &successCallback,
69 const QJSValue &errorCallback);
70Q_GRPCQUICK_EXPORT
71void makeServerStreamConnectionsImpl(QJSEngine *jsEngine,
72 HandleReceivedMessageImpl impl,
73 std::unique_ptr<QGrpcServerStream> &&stream,
74 const QJSValue &messageCallback,
75 const QJSValue &finishCallback,
76 const QJSValue &errorCallback);
77} // namespace Private
78
79template <typename Ret>
80void connectSingleReceiveOperationFinished(QJSEngine *jsEngine,
81 std::unique_ptr<QGrpcOperation> &&operation,
82 const QJSValue &successCallback,
83 const QJSValue &errorCallback)
84{
85 Private::connectSingleReceiveOperationFinishedImpl(jsEngine, impl: handleReceivedMessage<Ret>,
86 operation: std::move(operation), successCallback,
87 errorCallback);
88}
89
90template <typename Ret>
91void makeCallConnections(QJSEngine *jsEngine, std::unique_ptr<QGrpcCallReply> &&reply,
92 const QJSValue &finishCallback, const QJSValue &errorCallback)
93{
94 QtGrpcQuickFunctional::connectSingleReceiveOperationFinished<Ret>(jsEngine, std::move(reply),
95 finishCallback,
96 errorCallback);
97}
98
99template <typename Ret>
100void makeServerStreamConnections(QJSEngine *jsEngine, std::unique_ptr<QGrpcServerStream> &&stream,
101 const QJSValue &messageCallback, const QJSValue &finishCallback,
102 const QJSValue &errorCallback)
103{
104 Private::makeServerStreamConnectionsImpl(jsEngine, impl: &handleReceivedMessage<Ret>,
105 stream: std::move(stream), messageCallback, finishCallback,
106 errorCallback);
107}
108
109template <typename Ret>
110void makeClientStreamConnections(QJSEngine *jsEngine, std::unique_ptr<QGrpcClientStream> &&stream,
111 const QJSValue &finishCallback, const QJSValue &errorCallback)
112{
113 QtGrpcQuickFunctional::connectSingleReceiveOperationFinished<Ret>(jsEngine, std::move(stream),
114 finishCallback,
115 errorCallback);
116}
117
118template <typename Ret>
119void makeBidiStreamConnections(QJSEngine *jsEngine, std::unique_ptr<QGrpcBidiStream> &&stream,
120 const QJSValue &messageCallback, const QJSValue &finishCallback,
121 const QJSValue &errorCallback)
122{
123 QObject::connect(stream.get(), &QGrpcBidiStream::messageReceived, jsEngine,
124 [streamPtr = stream.get(), messageCallback, jsEngine, errorCallback] {
125 QtGrpcQuickFunctional::handleReceivedMessage<Ret>(jsEngine, streamPtr,
126 messageCallback,
127 errorCallback);
128 });
129 QtGrpcQuickFunctional::connectMultipleReceiveOperationFinished(jsEngine, operation: std::move(stream),
130 successCallback: finishCallback, errorCallback);
131}
132
133} // namespace QtGrpcQuickFunctional
134
135QT_END_NAMESPACE
136
137#endif // QQMLGRPCFUNCTIONALHANDLERS_H
138

source code of qtgrpc/src/grpcquick/qqmlgrpcfunctionalhandlers.h