Procházet zdrojové kódy

Add a QML method with the return value as a parameter

Giulio Girardi před 4 roky
rodič
revize
3a0982a354

+ 1 - 0
src/generator/clientdeclarationprinter.cpp

@@ -88,6 +88,7 @@ void ClientDeclarationPrinter::printClientMethodsDeclaration()
             mPrinter->Print(parameters, Templates::ClientMethodDeclarationAsync2Template);
             if (GeneratorOptions::instance().hasQml()) {
                 mPrinter->Print(parameters, Templates::ClientMethodDeclarationQmlTemplate);
+                mPrinter->Print(parameters, Templates::ClientMethodDeclarationQml2Template);
             }
         }
         mPrinter->Print("\n");

+ 1 - 0
src/generator/clientdefinitionprinter.cpp

@@ -59,6 +59,7 @@ void ClientDefinitionPrinter::printMethods()
             mPrinter->Print(parameters, Templates::ClientMethodDefinitionAsync2Template);
             if (GeneratorOptions::instance().hasQml()) {
                 mPrinter->Print(parameters, Templates::ClientMethodDefinitionQmlTemplate);
+                mPrinter->Print(parameters, Templates::ClientMethodDefinitionQml2Template);
             }
         }
     }

+ 28 - 0
src/generator/templates.cpp

@@ -292,6 +292,7 @@ const char *Templates::ClientMethodDeclarationSyncTemplate = "QtProtobuf::QGrpcS
 const char *Templates::ClientMethodDeclarationAsyncTemplate = "QtProtobuf::QGrpcAsyncReplyShared $method_name$(const $param_type$ &$param_name$);\n";
 const char *Templates::ClientMethodDeclarationAsync2Template = "Q_INVOKABLE void $method_name$(const $param_type$ &$param_name$, const QObject *context, const std::function<void(QtProtobuf::QGrpcAsyncReplyShared)> &callback);\n";
 const char *Templates::ClientMethodDeclarationQmlTemplate = "Q_INVOKABLE void $method_name$($param_type$ *$param_name$, const QJSValue &callback, const QJSValue &errorCallback);\n";
+const char *Templates::ClientMethodDeclarationQml2Template = "Q_INVOKABLE void $method_name$($param_type$ *$param_name$, $return_type$ *$return_name$, const QJSValue &errorCallback);\n";
 
 const char *Templates::ServerMethodDeclarationTemplate = "Q_INVOKABLE virtual $return_type$ $method_name$(const $param_type$ &$param_name$) = 0;\n";
 
@@ -339,6 +340,33 @@ const char *Templates::ClientMethodDefinitionQmlTemplate = "\nvoid $classname$::
                                                            "        QJSValue(errorCallback).call(QJSValueList{jsEngine->toScriptValue(status)});\n"
                                                            "    });\n"
                                                            "}\n";
+const char *Templates::ClientMethodDefinitionQml2Template = "\nvoid $classname$::$method_name$($param_type$ *$param_name$, $return_type$ *$return_name$, const QJSValue &errorCallback)\n"
+                                                            "{\n"
+                                                            "    if ($return_name$ == nullptr) {\n"
+                                                            "        qProtoWarning() << \"Invalid argument provided for method $classname$::$method_name$, argument of type '$return_type$ *' expected\";\n"
+                                                            "        return;\n"
+                                                            "    }\n\n"
+                                                            "    QPointer<$return_type$> safeReturn($return_name$);\n\n"
+                                                            "    if ($param_name$ == nullptr) {\n"
+                                                            "        qProtoWarning() << \"Invalid argument provided for method $classname$::$method_name$, argument of type '$param_type$ *' expected\";\n"
+                                                            "        return;\n"
+                                                            "    }\n\n"
+                                                            "    QJSEngine *jsEngine = qjsEngine(this);\n"
+                                                            "    if (jsEngine == nullptr) {\n"
+                                                            "        qProtoWarning() << \"Unable to call $classname$::$method_name$, it's only callable from JS engine context\";\n"
+                                                            "        return;\n"
+                                                            "    }\n\n"
+                                                            "    QtProtobuf::QGrpcAsyncReplyShared reply = call(\"$method_name$\", *$param_name$);\n"
+                                                            "    reply->subscribe(jsEngine, [this, reply, jsEngine, safeReturn]() {\n"
+                                                            "        if (safeReturn.isNull()) {\n"
+                                                            "            qProtoWarning() << \"Return value is destroyed. Ignore call result\";\n"
+                                                            "            return;\n"
+                                                            "        }\n"
+                                                            "        *safeReturn = $return_type$(reply->read<$return_type$>());\n"
+                                                            "    }, [errorCallback, jsEngine](const QGrpcStatus &status) {\n"
+                                                            "        QJSValue(errorCallback).call(QJSValueList{jsEngine->toScriptValue(status)});\n"
+                                                            "    });\n"
+                                                            "}\n";
 const char *Templates::RegisterSerializersTemplate = "qRegisterProtobufType<$classname$>();\n";
 const char *Templates::RegisterEnumSerializersTemplate = "qRegisterProtobufEnumType<$full_type$>();\n";
 const char *Templates::RegistrarTemplate = "static QtProtobuf::ProtoTypeRegistrar<$classname$> ProtoTypeRegistrar$classname$(qRegisterProtobufType<$classname$>);\n";

+ 2 - 0
src/generator/templates.h

@@ -185,6 +185,7 @@ public:
     static const char *ClientMethodDeclarationAsyncTemplate;
     static const char *ClientMethodDeclarationAsync2Template;
     static const char *ClientMethodDeclarationQmlTemplate;
+    static const char *ClientMethodDeclarationQml2Template;
 
     static const char *ServerMethodDeclarationTemplate;
 
@@ -192,6 +193,7 @@ public:
     static const char *ClientMethodDefinitionAsyncTemplate;
     static const char *ClientMethodDefinitionAsync2Template;
     static const char *ClientMethodDefinitionQmlTemplate;
+    static const char *ClientMethodDefinitionQml2Template;
 
     //Streaming
     static const char *ClientMethodSignalDeclarationTemplate;

+ 13 - 0
tests/test_grpc_qml/qml/tst_grpc.qml

@@ -206,4 +206,17 @@ TestCase {
         compare(subscriptionLoader.item.updateCount, 1, "Subscription failed, update was not called right amount times")
         subscriptionLoader.active = false;
     }
+
+    SimpleStringMessage {
+        id: returnStringMsg
+    }
+
+    function test_returnValueAsParameter() {
+        var errorCalled = false;
+        TestServiceClient.testMethod(stringMsg, returnStringMsg, function(status) {
+            errorCalled = true
+        })
+        wait(300)
+        compare(returnStringMsg.testFieldString == stringMsg.testFieldString && !errorCalled, true, "testMethod was not called proper way")
+    }
 }