add return value with async result

This commit is contained in:
王劲鹏 2021-05-25 10:45:45 +08:00 committed by osborn
parent 37f8898eac
commit da73ee5347
13 changed files with 95 additions and 94 deletions

View File

@ -14,11 +14,15 @@ DoricNativeDriver::invokeContextEntityMethod(QString contextId, QString method,
std::shared_ptr<DoricAsyncResult> std::shared_ptr<DoricAsyncResult>
DoricNativeDriver::invokeDoricMethod(QString method, QVariantList args) { DoricNativeDriver::invokeDoricMethod(QString method, QVariantList args) {
std::shared_ptr<DoricAsyncResult> asyncResult =
std::make_shared<DoricAsyncResult>();
DoricAsyncCall::ensureRunInThreadPool( DoricAsyncCall::ensureRunInThreadPool(
&jsEngine.mJSThreadPool, &jsEngine.mJSThreadPool, [this, method, args, asyncResult] {
[this, method, args] { this->jsEngine.invokeDoricMethod(method, args); }); QString result = this->jsEngine.invokeDoricMethod(method, args);
asyncResult->setResult(result);
});
return std::make_shared<DoricAsyncResult>(); return asyncResult;
} }
std::shared_ptr<DoricAsyncResult> std::shared_ptr<DoricAsyncResult>
@ -26,10 +30,11 @@ DoricNativeDriver::asyncCall(std::function<void()> lambda,
DoricThreadMode mode) { DoricThreadMode mode) {
switch (mode) { switch (mode) {
case UI: case UI:
DoricAsyncCall::ensureRunInMain(lambda); return DoricAsyncCall::ensureRunInMain(lambda);
break; break;
case JS: case JS:
DoricAsyncCall::ensureRunInThreadPool(&jsEngine.mJSThreadPool, lambda); return DoricAsyncCall::ensureRunInThreadPool(&jsEngine.mJSThreadPool,
lambda);
break; break;
} }
return NULL; return NULL;
@ -38,21 +43,31 @@ DoricNativeDriver::asyncCall(std::function<void()> lambda,
std::shared_ptr<DoricAsyncResult> std::shared_ptr<DoricAsyncResult>
DoricNativeDriver::createContext(QString contextId, QString script, DoricNativeDriver::createContext(QString contextId, QString script,
QString source) { QString source) {
std::shared_ptr<DoricAsyncResult> asyncResult =
std::make_shared<DoricAsyncResult>();
DoricAsyncCall::ensureRunInThreadPool( DoricAsyncCall::ensureRunInThreadPool(
&jsEngine.mJSThreadPool, [this, contextId, script, source] { &jsEngine.mJSThreadPool, [this, contextId, script, source, asyncResult] {
this->jsEngine.prepareContext(contextId, script, source); QString result =
this->jsEngine.prepareContext(contextId, script, source);
asyncResult->setResult(result);
}); });
return std::make_shared<DoricAsyncResult>(); return asyncResult;
} }
std::shared_ptr<DoricAsyncResult> std::shared_ptr<DoricAsyncResult>
DoricNativeDriver::destroyContext(QString contextId) { DoricNativeDriver::destroyContext(QString contextId) {
DoricAsyncCall::ensureRunInThreadPool( std::shared_ptr<DoricAsyncResult> asyncResult =
&jsEngine.mJSThreadPool, std::make_shared<DoricAsyncResult>();
[this, contextId] { this->jsEngine.destroyContext(contextId); });
return std::make_shared<DoricAsyncResult>(); DoricAsyncCall::ensureRunInThreadPool(
&jsEngine.mJSThreadPool, [this, contextId, asyncResult] {
QString result = this->jsEngine.destroyContext(contextId);
asyncResult->setResult(result);
});
return asyncResult;
} }
DoricRegistry *DoricNativeDriver::getRegistry() { DoricRegistry *DoricNativeDriver::getRegistry() {

View File

@ -5,21 +5,43 @@
#include <QThreadPool> #include <QThreadPool>
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#include "DoricAsyncResult.h"
class DoricAsyncCall { class DoricAsyncCall {
public: public:
static void ensureRunInThreadPool(QThreadPool *threadPool, template <typename Function>
std::function<void()> lambda) { static std::shared_ptr<DoricAsyncResult>
QFuture<std::function<void()>::result_type> future = ensureRunInThreadPool(QThreadPool *threadPool, Function &&function) {
QtConcurrent::run(threadPool, lambda); std::shared_ptr<DoricAsyncResult> asyncResult =
std::make_shared<DoricAsyncResult>();
Function lambda = std::forward<Function>(function);
QtConcurrent::run(threadPool, [lambda, asyncResult]() {
lambda();
// asyncResult->setResult(result);
});
return asyncResult;
} }
template <typename Function> template <typename Function>
static void ensureRunInMain(Function &&function, static std::shared_ptr<DoricAsyncResult>
QThread *thread = qApp->thread()) { ensureRunInMain(Function &&function, QThread *thread = qApp->thread()) {
std::shared_ptr<DoricAsyncResult> asyncResult =
std::make_shared<DoricAsyncResult>();
auto *obj = QAbstractEventDispatcher::instance(thread); auto *obj = QAbstractEventDispatcher::instance(thread);
Q_ASSERT(obj); Q_ASSERT(obj);
QMetaObject::invokeMethod(obj, std::forward<Function>(function));
Function lambda = std::forward<Function>(function);
QMetaObject::invokeMethod(obj, [lambda, asyncResult]() {
lambda();
// asyncResult->setResult(result);
});
return asyncResult;
} }
}; };

View File

@ -2,37 +2,12 @@
DoricAsyncResult::DoricAsyncResult() {} DoricAsyncResult::DoricAsyncResult() {}
DoricAsyncResult::DoricAsyncResult(QJSValue result) { this->result = result; } void DoricAsyncResult::setResult(QString result) { this->result = result; }
void DoricAsyncResult::setResult(QJSValue result) { void DoricAsyncResult::setError(QString exception) { this->result = exception; }
this->result = result;
if (this->callback != NULL) {
this->callback->onResult(result);
this->callback->onFinish();
}
}
void DoricAsyncResult::setError(QJSValue exception) { bool DoricAsyncResult::hasResult() { return !(result == EMPTY); }
this->result = exception;
if (this->callback != NULL) {
this->callback->onResult(result);
this->callback->onFinish();
}
}
bool DoricAsyncResult::hasResult() { return !result.equals(EMPTY); }
QJSValue DoricAsyncResult::getResult() { return this->result; } 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; } DoricSettableFuture *DoricAsyncResult::synchronous() { return NULL; }

View File

@ -5,31 +5,29 @@
#include "DoricExport.h" #include "DoricExport.h"
#include "DoricCallback.h"
#include "DoricSettableFuture.h" #include "DoricSettableFuture.h"
static QJSValue EMPTY(QJSValue::NullValue); static QString EMPTY("");
class DORIC_EXPORT DoricAsyncResult { class DORIC_EXPORT DoricAsyncResult {
private: private:
QJSValue result = EMPTY; QString result = EMPTY;
DoricCallback *callback;
public: public:
std::function<void()> resultCallback;
std::function<void()> exceptionCallback;
std::function<void()> finishCallback;
DoricAsyncResult(); DoricAsyncResult();
DoricAsyncResult(QJSValue result); void setResult(QString result);
void setResult(QJSValue result); void setError(QString exception);
void setError(QJSValue exception);
bool hasResult(); bool hasResult();
QJSValue getResult(); QJSValue getResult();
void setCallback(DoricCallback *callback);
DoricSettableFuture *synchronous(); DoricSettableFuture *synchronous();
}; };

View File

@ -1,15 +0,0 @@
#ifndef CALLBACK_H
#define CALLBACK_H
#include <QJSValue>
class DoricCallback {
public:
virtual void onResult(QJSValue result) = 0;
virtual void onError(QJSValue error) = 0;
virtual void onFinish() = 0;
};
#endif // CALLBACK_H

View File

@ -101,7 +101,6 @@ HEADERS += \
DoricRegistry.h \ DoricRegistry.h \
async/DoricAsyncCall.h \ async/DoricAsyncCall.h \
async/DoricAsyncResult.h \ async/DoricAsyncResult.h \
async/DoricCallback.h \
async/DoricSettableFuture.h \ async/DoricSettableFuture.h \
engine/DoricBridgeExtension.h \ engine/DoricBridgeExtension.h \
engine/DoricInterfaceJSE.h \ engine/DoricInterfaceJSE.h \

View File

@ -13,8 +13,8 @@ public:
virtual void injectGlobalJSFunction(QString name, QObject *function, virtual void injectGlobalJSFunction(QString name, QObject *function,
QString property) = 0; QString property) = 0;
virtual void invokeObject(QString objectName, QString functionName, virtual QString invokeObject(QString objectName, QString functionName,
QVariantList arguments) = 0; QVariantList arguments) = 0;
}; };
#endif // INTERFACE_JSE_H #endif // INTERFACE_JSE_H

View File

@ -96,18 +96,20 @@ DoricJSEngine::DoricJSEngine(QObject *parent) : QObject(parent) {
} }
} }
void DoricJSEngine::prepareContext(QString contextId, QString script, QString DoricJSEngine::prepareContext(QString contextId, QString script,
QString source) { QString source) {
mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source); return mJSE->loadJS(packageContextScript(contextId, script),
"Context://" + source);
} }
void DoricJSEngine::destroyContext(QString contextId) { QString DoricJSEngine::destroyContext(QString contextId) {
QString script = QString script =
QString(DoricConstant::TEMPLATE_CONTEXT_DESTROY).replace("%s", contextId); 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); return mJSE->invokeObject(DoricConstant::GLOBAL_DORIC, method, arguments);
} }

View File

@ -26,11 +26,11 @@ public:
~DoricJSEngine(); ~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(); DoricRegistry *getRegistry();
}; };

View File

@ -56,11 +56,13 @@ void DoricNativeJSE::injectGlobalJSFunction(QString name, QObject *function,
} }
} }
void DoricNativeJSE::invokeObject(QString objectName, QString functionName, QString DoricNativeJSE::invokeObject(QString objectName, QString functionName,
QVariantList arguments) { QVariantList arguments) {
if (mType == JSEType::V8) { if (mType == JSEType::V8) {
v8Executor->invokeObject(objectName, functionName, arguments); return v8Executor->invokeObject(objectName, functionName, arguments);
} else if (mType == JSEType::Native) { } else if (mType == JSEType::Native) {
nativeExecutor->invokeObject(objectName, functionName, arguments); return nativeExecutor->invokeObject(objectName, functionName, arguments)
.toString();
} }
return QString();
} }

View File

@ -26,8 +26,8 @@ public:
void injectGlobalJSFunction(QString name, QObject *function, void injectGlobalJSFunction(QString name, QObject *function,
QString property) override; QString property) override;
void invokeObject(QString objectName, QString functionName, QString invokeObject(QString objectName, QString functionName,
QVariantList arguments) override; QVariantList arguments) override;
}; };
#endif // NATIVE_JSE_H #endif // NATIVE_JSE_H

View File

@ -72,8 +72,8 @@ void V8Executor::injectGlobalJSFunction(QString name, QObject *function,
injectFunctions(nullptr, name.toUtf8().constData(), true); injectFunctions(nullptr, name.toUtf8().constData(), true);
} }
void V8Executor::invokeObject(QString objectName, QString functionName, QString V8Executor::invokeObject(QString objectName, QString functionName,
QVariantList arguments) { QVariantList arguments) {
std::string exception; std::string exception;
v8::HandleScope handleScope(m_isolate); v8::HandleScope handleScope(m_isolate);
int valueSize = arguments.size(); int valueSize = arguments.size();
@ -86,6 +86,9 @@ void V8Executor::invokeObject(QString objectName, QString functionName,
functionName.toUtf8().constData(), functionName.toUtf8().constData(),
valueSize, js_values, &exception); valueSize, js_values, &exception);
delete[] js_values; delete[] js_values;
std::string result = JS2String(value);
return QString::fromUtf8(result.c_str());
} }
// private segment // private segment

View File

@ -45,8 +45,8 @@ public:
void injectGlobalJSFunction(QString name, QObject *function, void injectGlobalJSFunction(QString name, QObject *function,
QString property); QString property);
void invokeObject(QString objectName, QString functionName, QString invokeObject(QString objectName, QString functionName,
QVariantList arguments); QVariantList arguments);
}; };
#endif // V8EXECUTOR_H #endif // V8EXECUTOR_H