From da73ee53475006c8d2f7c7e0aeb710fee2881f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8A=B2=E9=B9=8F?= Date: Tue, 25 May 2021 10:45:45 +0800 Subject: [PATCH] add return value with async result --- doric-Qt/example/doric/DoricNativeDriver.cpp | 39 +++++++++++++------ doric-Qt/example/doric/async/DoricAsyncCall.h | 36 +++++++++++++---- .../example/doric/async/DoricAsyncResult.cpp | 31 ++------------- .../example/doric/async/DoricAsyncResult.h | 18 ++++----- doric-Qt/example/doric/async/DoricCallback.h | 15 ------- doric-Qt/example/doric/doric.pro | 1 - .../example/doric/engine/DoricInterfaceJSE.h | 4 +- .../example/doric/engine/DoricJSEngine.cpp | 14 ++++--- doric-Qt/example/doric/engine/DoricJSEngine.h | 6 +-- .../example/doric/engine/DoricNativeJSE.cpp | 10 +++-- .../example/doric/engine/DoricNativeJSE.h | 4 +- .../example/doric/engine/v8/V8Executor.cpp | 7 +++- doric-Qt/example/doric/engine/v8/V8Executor.h | 4 +- 13 files changed, 95 insertions(+), 94 deletions(-) delete mode 100644 doric-Qt/example/doric/async/DoricCallback.h diff --git a/doric-Qt/example/doric/DoricNativeDriver.cpp b/doric-Qt/example/doric/DoricNativeDriver.cpp index a231660a..61ed5e3d 100644 --- a/doric-Qt/example/doric/DoricNativeDriver.cpp +++ b/doric-Qt/example/doric/DoricNativeDriver.cpp @@ -14,11 +14,15 @@ DoricNativeDriver::invokeContextEntityMethod(QString contextId, QString method, std::shared_ptr DoricNativeDriver::invokeDoricMethod(QString method, QVariantList args) { + std::shared_ptr asyncResult = + std::make_shared(); DoricAsyncCall::ensureRunInThreadPool( - &jsEngine.mJSThreadPool, - [this, method, args] { this->jsEngine.invokeDoricMethod(method, args); }); + &jsEngine.mJSThreadPool, [this, method, args, asyncResult] { + QString result = this->jsEngine.invokeDoricMethod(method, args); + asyncResult->setResult(result); + }); - return std::make_shared(); + return asyncResult; } std::shared_ptr @@ -26,10 +30,11 @@ DoricNativeDriver::asyncCall(std::function lambda, DoricThreadMode mode) { switch (mode) { case UI: - DoricAsyncCall::ensureRunInMain(lambda); + return DoricAsyncCall::ensureRunInMain(lambda); break; case JS: - DoricAsyncCall::ensureRunInThreadPool(&jsEngine.mJSThreadPool, lambda); + return DoricAsyncCall::ensureRunInThreadPool(&jsEngine.mJSThreadPool, + lambda); break; } return NULL; @@ -38,21 +43,31 @@ DoricNativeDriver::asyncCall(std::function lambda, std::shared_ptr DoricNativeDriver::createContext(QString contextId, QString script, QString source) { + std::shared_ptr asyncResult = + std::make_shared(); + DoricAsyncCall::ensureRunInThreadPool( - &jsEngine.mJSThreadPool, [this, contextId, script, source] { - this->jsEngine.prepareContext(contextId, script, source); + &jsEngine.mJSThreadPool, [this, contextId, script, source, asyncResult] { + QString result = + this->jsEngine.prepareContext(contextId, script, source); + asyncResult->setResult(result); }); - return std::make_shared(); + return asyncResult; } std::shared_ptr DoricNativeDriver::destroyContext(QString contextId) { - DoricAsyncCall::ensureRunInThreadPool( - &jsEngine.mJSThreadPool, - [this, contextId] { this->jsEngine.destroyContext(contextId); }); + std::shared_ptr asyncResult = + std::make_shared(); - return std::make_shared(); + DoricAsyncCall::ensureRunInThreadPool( + &jsEngine.mJSThreadPool, [this, contextId, asyncResult] { + QString result = this->jsEngine.destroyContext(contextId); + asyncResult->setResult(result); + }); + + return asyncResult; } DoricRegistry *DoricNativeDriver::getRegistry() { diff --git a/doric-Qt/example/doric/async/DoricAsyncCall.h b/doric-Qt/example/doric/async/DoricAsyncCall.h index cfa62dca..fae4d394 100644 --- a/doric-Qt/example/doric/async/DoricAsyncCall.h +++ b/doric-Qt/example/doric/async/DoricAsyncCall.h @@ -5,21 +5,43 @@ #include #include +#include "DoricAsyncResult.h" + class DoricAsyncCall { public: - static void ensureRunInThreadPool(QThreadPool *threadPool, - std::function lambda) { - QFuture::result_type> future = - QtConcurrent::run(threadPool, lambda); + template + static std::shared_ptr + ensureRunInThreadPool(QThreadPool *threadPool, Function &&function) { + std::shared_ptr asyncResult = + std::make_shared(); + + Function lambda = std::forward(function); + + QtConcurrent::run(threadPool, [lambda, asyncResult]() { + lambda(); + // asyncResult->setResult(result); + }); + + return asyncResult; } template - static void ensureRunInMain(Function &&function, - QThread *thread = qApp->thread()) { + static std::shared_ptr + ensureRunInMain(Function &&function, QThread *thread = qApp->thread()) { + std::shared_ptr asyncResult = + std::make_shared(); + auto *obj = QAbstractEventDispatcher::instance(thread); Q_ASSERT(obj); - QMetaObject::invokeMethod(obj, std::forward(function)); + + Function lambda = std::forward(function); + QMetaObject::invokeMethod(obj, [lambda, asyncResult]() { + lambda(); + // asyncResult->setResult(result); + }); + + return asyncResult; } }; diff --git a/doric-Qt/example/doric/async/DoricAsyncResult.cpp b/doric-Qt/example/doric/async/DoricAsyncResult.cpp index 3bc37885..32fca82a 100644 --- a/doric-Qt/example/doric/async/DoricAsyncResult.cpp +++ b/doric-Qt/example/doric/async/DoricAsyncResult.cpp @@ -2,37 +2,12 @@ DoricAsyncResult::DoricAsyncResult() {} -DoricAsyncResult::DoricAsyncResult(QJSValue result) { this->result = result; } +void DoricAsyncResult::setResult(QString result) { this->result = result; } -void DoricAsyncResult::setResult(QJSValue result) { - this->result = result; - if (this->callback != NULL) { - this->callback->onResult(result); - this->callback->onFinish(); - } -} +void DoricAsyncResult::setError(QString exception) { this->result = exception; } -void DoricAsyncResult::setError(QJSValue exception) { - this->result = exception; - if (this->callback != NULL) { - this->callback->onResult(result); - this->callback->onFinish(); - } -} - -bool DoricAsyncResult::hasResult() { return !result.equals(EMPTY); } +bool DoricAsyncResult::hasResult() { return !(result == EMPTY); } QJSValue DoricAsyncResult::getResult() { return this->result; } -void DoricAsyncResult::setCallback(DoricCallback *callback) { - this->callback = callback; - if (this->result.isError()) { - this->callback->onError(result); - this->callback->onFinish(); - } else if (!result.equals(EMPTY)) { - this->callback->onResult(result); - this->callback->onFinish(); - } -} - DoricSettableFuture *DoricAsyncResult::synchronous() { return NULL; } diff --git a/doric-Qt/example/doric/async/DoricAsyncResult.h b/doric-Qt/example/doric/async/DoricAsyncResult.h index 02843094..a9f1adba 100644 --- a/doric-Qt/example/doric/async/DoricAsyncResult.h +++ b/doric-Qt/example/doric/async/DoricAsyncResult.h @@ -5,31 +5,29 @@ #include "DoricExport.h" -#include "DoricCallback.h" #include "DoricSettableFuture.h" -static QJSValue EMPTY(QJSValue::NullValue); +static QString EMPTY(""); class DORIC_EXPORT DoricAsyncResult { private: - QJSValue result = EMPTY; - DoricCallback *callback; + QString result = EMPTY; public: + std::function resultCallback; + std::function exceptionCallback; + std::function finishCallback; + DoricAsyncResult(); - DoricAsyncResult(QJSValue result); + void setResult(QString result); - void setResult(QJSValue result); - - void setError(QJSValue exception); + void setError(QString exception); bool hasResult(); QJSValue getResult(); - void setCallback(DoricCallback *callback); - DoricSettableFuture *synchronous(); }; diff --git a/doric-Qt/example/doric/async/DoricCallback.h b/doric-Qt/example/doric/async/DoricCallback.h deleted file mode 100644 index 3938fc6c..00000000 --- a/doric-Qt/example/doric/async/DoricCallback.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef CALLBACK_H -#define CALLBACK_H - -#include - -class DoricCallback { -public: - virtual void onResult(QJSValue result) = 0; - - virtual void onError(QJSValue error) = 0; - - virtual void onFinish() = 0; -}; - -#endif // CALLBACK_H diff --git a/doric-Qt/example/doric/doric.pro b/doric-Qt/example/doric/doric.pro index db164ef7..2044dde3 100644 --- a/doric-Qt/example/doric/doric.pro +++ b/doric-Qt/example/doric/doric.pro @@ -101,7 +101,6 @@ HEADERS += \ DoricRegistry.h \ async/DoricAsyncCall.h \ async/DoricAsyncResult.h \ - async/DoricCallback.h \ async/DoricSettableFuture.h \ engine/DoricBridgeExtension.h \ engine/DoricInterfaceJSE.h \ diff --git a/doric-Qt/example/doric/engine/DoricInterfaceJSE.h b/doric-Qt/example/doric/engine/DoricInterfaceJSE.h index 905b657a..454e1fc4 100644 --- a/doric-Qt/example/doric/engine/DoricInterfaceJSE.h +++ b/doric-Qt/example/doric/engine/DoricInterfaceJSE.h @@ -13,8 +13,8 @@ public: virtual void injectGlobalJSFunction(QString name, QObject *function, QString property) = 0; - virtual void invokeObject(QString objectName, QString functionName, - QVariantList arguments) = 0; + virtual QString invokeObject(QString objectName, QString functionName, + QVariantList arguments) = 0; }; #endif // INTERFACE_JSE_H diff --git a/doric-Qt/example/doric/engine/DoricJSEngine.cpp b/doric-Qt/example/doric/engine/DoricJSEngine.cpp index a81e914c..2b562321 100644 --- a/doric-Qt/example/doric/engine/DoricJSEngine.cpp +++ b/doric-Qt/example/doric/engine/DoricJSEngine.cpp @@ -96,18 +96,20 @@ DoricJSEngine::DoricJSEngine(QObject *parent) : QObject(parent) { } } -void DoricJSEngine::prepareContext(QString contextId, QString script, - QString source) { - mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source); +QString DoricJSEngine::prepareContext(QString contextId, QString script, + QString source) { + return mJSE->loadJS(packageContextScript(contextId, script), + "Context://" + source); } -void DoricJSEngine::destroyContext(QString contextId) { +QString DoricJSEngine::destroyContext(QString contextId) { QString script = QString(DoricConstant::TEMPLATE_CONTEXT_DESTROY).replace("%s", contextId); - mJSE->loadJS(script, "_Context://" + contextId); + return mJSE->loadJS(script, "_Context://" + contextId); } -void DoricJSEngine::invokeDoricMethod(QString method, QVariantList arguments) { +QString DoricJSEngine::invokeDoricMethod(QString method, + QVariantList arguments) { return mJSE->invokeObject(DoricConstant::GLOBAL_DORIC, method, arguments); } diff --git a/doric-Qt/example/doric/engine/DoricJSEngine.h b/doric-Qt/example/doric/engine/DoricJSEngine.h index 9fb10e23..a67fc7f0 100644 --- a/doric-Qt/example/doric/engine/DoricJSEngine.h +++ b/doric-Qt/example/doric/engine/DoricJSEngine.h @@ -26,11 +26,11 @@ public: ~DoricJSEngine(); - void prepareContext(QString contextId, QString script, QString source); + QString prepareContext(QString contextId, QString script, QString source); - void destroyContext(QString contextId); + QString destroyContext(QString contextId); - void invokeDoricMethod(QString method, QVariantList arguments); + QString invokeDoricMethod(QString method, QVariantList arguments); DoricRegistry *getRegistry(); }; diff --git a/doric-Qt/example/doric/engine/DoricNativeJSE.cpp b/doric-Qt/example/doric/engine/DoricNativeJSE.cpp index 1a59c85b..6af2db7e 100644 --- a/doric-Qt/example/doric/engine/DoricNativeJSE.cpp +++ b/doric-Qt/example/doric/engine/DoricNativeJSE.cpp @@ -56,11 +56,13 @@ void DoricNativeJSE::injectGlobalJSFunction(QString name, QObject *function, } } -void DoricNativeJSE::invokeObject(QString objectName, QString functionName, - QVariantList arguments) { +QString DoricNativeJSE::invokeObject(QString objectName, QString functionName, + QVariantList arguments) { if (mType == JSEType::V8) { - v8Executor->invokeObject(objectName, functionName, arguments); + return v8Executor->invokeObject(objectName, functionName, arguments); } else if (mType == JSEType::Native) { - nativeExecutor->invokeObject(objectName, functionName, arguments); + return nativeExecutor->invokeObject(objectName, functionName, arguments) + .toString(); } + return QString(); } diff --git a/doric-Qt/example/doric/engine/DoricNativeJSE.h b/doric-Qt/example/doric/engine/DoricNativeJSE.h index 0324a6e2..8193343d 100644 --- a/doric-Qt/example/doric/engine/DoricNativeJSE.h +++ b/doric-Qt/example/doric/engine/DoricNativeJSE.h @@ -26,8 +26,8 @@ public: void injectGlobalJSFunction(QString name, QObject *function, QString property) override; - void invokeObject(QString objectName, QString functionName, - QVariantList arguments) override; + QString invokeObject(QString objectName, QString functionName, + QVariantList arguments) override; }; #endif // NATIVE_JSE_H diff --git a/doric-Qt/example/doric/engine/v8/V8Executor.cpp b/doric-Qt/example/doric/engine/v8/V8Executor.cpp index 046a4a83..8ae3c471 100644 --- a/doric-Qt/example/doric/engine/v8/V8Executor.cpp +++ b/doric-Qt/example/doric/engine/v8/V8Executor.cpp @@ -72,8 +72,8 @@ void V8Executor::injectGlobalJSFunction(QString name, QObject *function, injectFunctions(nullptr, name.toUtf8().constData(), true); } -void V8Executor::invokeObject(QString objectName, QString functionName, - QVariantList arguments) { +QString V8Executor::invokeObject(QString objectName, QString functionName, + QVariantList arguments) { std::string exception; v8::HandleScope handleScope(m_isolate); int valueSize = arguments.size(); @@ -86,6 +86,9 @@ void V8Executor::invokeObject(QString objectName, QString functionName, functionName.toUtf8().constData(), valueSize, js_values, &exception); delete[] js_values; + + std::string result = JS2String(value); + return QString::fromUtf8(result.c_str()); } // private segment diff --git a/doric-Qt/example/doric/engine/v8/V8Executor.h b/doric-Qt/example/doric/engine/v8/V8Executor.h index 0037bab0..b5f3be2d 100644 --- a/doric-Qt/example/doric/engine/v8/V8Executor.h +++ b/doric-Qt/example/doric/engine/v8/V8Executor.h @@ -45,8 +45,8 @@ public: void injectGlobalJSFunction(QString name, QObject *function, QString property); - void invokeObject(QString objectName, QString functionName, - QVariantList arguments); + QString invokeObject(QString objectName, QString functionName, + QVariantList arguments); }; #endif // V8EXECUTOR_H