complete invoke method on v8
This commit is contained in:
parent
dada2e4e0d
commit
7458d0f4c0
@ -15,7 +15,7 @@ void DoricNativeDriver::invokeContextEntityMethod(QString contextId,
|
||||
void DoricNativeDriver::invokeDoricMethod(QString method, QVariantList args) {
|
||||
return DoricAsyncCall::ensureRunInThreadPool(
|
||||
&jsEngine.mJSThreadPool, [this, method, args] {
|
||||
this->jsEngine.invokeDoricMethod(method, args).toString();
|
||||
this->jsEngine.invokeDoricMethod(method, args);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMetaObject>
|
||||
|
||||
#include "../DoricContextManager.h"
|
||||
@ -8,7 +10,9 @@ DoricBridgeExtension::DoricBridgeExtension(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void DoricBridgeExtension::callNative(QString contextId, QString module,
|
||||
QString methodName, QString callbackId,
|
||||
QJSValue jsValue) {
|
||||
QString argument) {
|
||||
QJsonDocument document = QJsonDocument::fromJson(argument.toUtf8());
|
||||
QJsonObject jsValue = document.object();
|
||||
DoricContext *context =
|
||||
DoricContextManager::getInstance()->getContext(contextId);
|
||||
bool classRegistered =
|
||||
@ -17,10 +21,10 @@ void DoricBridgeExtension::callNative(QString contextId, QString module,
|
||||
QObject *plugin = context->obtainPlugin(module);
|
||||
QMetaObject::invokeMethod(plugin, methodName.toUtf8(), Qt::DirectConnection,
|
||||
QGenericReturnArgument(),
|
||||
Q_ARG(QJSValue, jsValue),
|
||||
Q_ARG(QJsonObject, jsValue),
|
||||
Q_ARG(QString, callbackId));
|
||||
}
|
||||
qDebug() << "contextId: " + contextId << "module: " + module
|
||||
<< "methodName: " + methodName << "callbackId: " + callbackId
|
||||
<< "jsValue: " + jsValue.toString();
|
||||
<< "jsValue: " + argument;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public:
|
||||
|
||||
Q_INVOKABLE void callNative(QString contextId, QString module,
|
||||
QString methodName, QString callbackId,
|
||||
QJSValue jsValue);
|
||||
QString argument);
|
||||
};
|
||||
|
||||
#endif // BRIDGEEXTENSION_H
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef INTERFACE_JSE_H
|
||||
#define INTERFACE_JSE_H
|
||||
|
||||
#include <QJSValue>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
@ -14,7 +13,7 @@ public:
|
||||
virtual void injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property) = 0;
|
||||
|
||||
virtual QJSValue invokeObject(QString objectName, QString functionName,
|
||||
virtual void invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) = 0;
|
||||
};
|
||||
|
||||
|
@ -98,7 +98,7 @@ void DoricJSEngine::prepareContext(QString contextId, QString script,
|
||||
mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source);
|
||||
}
|
||||
|
||||
QJSValue DoricJSEngine::invokeDoricMethod(QString method,
|
||||
void DoricJSEngine::invokeDoricMethod(QString method,
|
||||
QVariantList arguments) {
|
||||
return mJSE->invokeObject(DoricConstant::GLOBAL_DORIC, method, arguments);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
~DoricJSEngine();
|
||||
|
||||
void prepareContext(QString contextId, QString script, QString source);
|
||||
QJSValue invokeDoricMethod(QString method, QVariantList arguments);
|
||||
void invokeDoricMethod(QString method, QVariantList arguments);
|
||||
DoricRegistry *getRegistry();
|
||||
};
|
||||
|
||||
|
@ -56,11 +56,11 @@ void DoricNativeJSE::injectGlobalJSFunction(QString name, QObject *function,
|
||||
}
|
||||
}
|
||||
|
||||
QJSValue DoricNativeJSE::invokeObject(QString objectName, QString functionName,
|
||||
void DoricNativeJSE::invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) {
|
||||
if (mType == JSEType::V8) {
|
||||
return QJSValue::UndefinedValue;
|
||||
v8Executor->invokeObject(objectName, functionName, arguments);
|
||||
} else if (mType == JSEType::Native) {
|
||||
return nativeExecutor->invokeObject(objectName, functionName, arguments);
|
||||
nativeExecutor->invokeObject(objectName, functionName, arguments);
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
void injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property) override;
|
||||
|
||||
QJSValue invokeObject(QString objectName, QString functionName,
|
||||
void invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) override;
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "JSValueHelper.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
std::string JS2String(v8::Local<v8::Value> object) {
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
@ -55,3 +58,27 @@ v8::Local<v8::Value> String2JS(std::string string) {
|
||||
|
||||
return handleScope.Escape(ret);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Variant2JS(QVariant variant) {
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
v8::EscapableHandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Value> jsValue;
|
||||
if (variant.type() == QVariant::String) {
|
||||
jsValue = NewV8String(variant.toString().toUtf8().constData());
|
||||
} else if (variant.type() == QVariant::Map) {
|
||||
QMap<QString, QVariant> map = variant.toMap();
|
||||
|
||||
QJsonObject jsonObject;
|
||||
foreach (QString key, map.keys()) {
|
||||
QVariant value = map.value(key);
|
||||
jsonObject.insert(key, QJsonValue::fromVariant(value));
|
||||
}
|
||||
QJsonDocument doc(jsonObject);
|
||||
QString strJson(doc.toJson(QJsonDocument::Compact));
|
||||
jsValue = String2JS(strJson.toUtf8().constData());
|
||||
} else if (variant.type() == QVariant::StringList) {
|
||||
qDebug() << "";
|
||||
}
|
||||
return handle_scope.Escape(jsValue);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef JSVALUEHELPER_H
|
||||
#define JSVALUEHELPER_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <string>
|
||||
|
||||
#include "v8/v8.h"
|
||||
@ -18,4 +19,6 @@ bool JS2Bool(v8::Local<v8::Value> value);
|
||||
|
||||
v8::Local<v8::Value> String2JS(std::string string);
|
||||
|
||||
v8::Local<v8::Value> Variant2JS(QVariant variant);
|
||||
|
||||
#endif // JSVALUEHELPER_H
|
||||
|
@ -72,6 +72,22 @@ void V8Executor::injectGlobalJSFunction(QString name, QObject *function,
|
||||
injectFunctions(nullptr, name.toUtf8().constData(), true);
|
||||
}
|
||||
|
||||
void V8Executor::invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) {
|
||||
std::string exception;
|
||||
v8::HandleScope handleScope(m_isolate);
|
||||
int valueSize = arguments.size();
|
||||
|
||||
auto js_values = new v8::Local<v8::Value>[valueSize];
|
||||
for (uint32_t i = 0; i < valueSize; i++) {
|
||||
js_values[i] = Variant2JS(arguments.at(i));
|
||||
}
|
||||
v8::Local<v8::Value> value = invokeMethod(objectName.toUtf8().constData(),
|
||||
functionName.toUtf8().constData(),
|
||||
valueSize, js_values, &exception);
|
||||
delete[] js_values;
|
||||
}
|
||||
|
||||
// private segment
|
||||
void V8Executor::injectObject(const char *string, v8::Local<v8::Value> local) {
|
||||
v8::Isolate *isolate = m_isolate;
|
||||
@ -214,11 +230,11 @@ static void InjectedFunction(const v8::FunctionCallbackInfo<v8::Value> &args) {
|
||||
QMetaObject::invokeMethod(
|
||||
pair.first, pair.second.toUtf8().constData(), Qt::DirectConnection,
|
||||
QGenericReturnArgument(),
|
||||
Q_ARG(QString, QString::fromStdString(argString0)),
|
||||
Q_ARG(QString, QString::fromStdString(argString1)),
|
||||
Q_ARG(QString, QString::fromStdString(argString2)),
|
||||
Q_ARG(QString, QString::fromStdString(argString3)),
|
||||
Q_ARG(QString, QString::fromStdString(argString4)));
|
||||
Q_ARG(QString, QString::fromUtf8(argString0.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString1.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString2.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString3.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString4.c_str())));
|
||||
}
|
||||
|
||||
// begin check to perform micro task checkpoint
|
||||
@ -281,3 +297,52 @@ void V8Executor::injectFunctions(const char *objectName,
|
||||
v8::Maybe<bool> result = object->Set(context, name, function);
|
||||
result.ToChecked();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> V8Executor::invokeMethod(const char *objectName,
|
||||
const char *functionName,
|
||||
int argc,
|
||||
v8::Local<v8::Value> argv[],
|
||||
std::string *exception_str) {
|
||||
v8::Isolate *isolate = m_isolate;
|
||||
v8::EscapableHandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
v8::Local<v8::Object> object = context->Global();
|
||||
v8::Local<v8::Value> result = Undefined(isolate);
|
||||
|
||||
if (objectName) {
|
||||
object = object->Get(context, NewV8String(objectName))
|
||||
.ToLocalChecked()
|
||||
->ToObject(context)
|
||||
.ToLocalChecked();
|
||||
}
|
||||
if (object.IsEmpty()) {
|
||||
*exception_str = std::string("Cannot find Object:") +
|
||||
std::string(objectName ? objectName : "global");
|
||||
return handle_scope.Escape(result);
|
||||
}
|
||||
v8::Local<v8::Value> target_value =
|
||||
object->Get(context, NewV8String(functionName)).ToLocalChecked();
|
||||
if (!target_value->IsFunction()) {
|
||||
*exception_str =
|
||||
std::string("In ") + std::string(objectName ? objectName : "global") +
|
||||
std::string("cannot find target function ") + std::string(functionName);
|
||||
return handle_scope.Escape(result);
|
||||
}
|
||||
v8::TryCatch try_catch(isolate);
|
||||
try_catch.SetVerbose(true);
|
||||
v8::Local<v8::Function> target_function =
|
||||
v8::Local<v8::Function>::Cast(target_value);
|
||||
result = target_function->Call(context, object, argc, argv).ToLocalChecked();
|
||||
v8::Local<v8::Value> exception = try_catch.Exception();
|
||||
if (!exception.IsEmpty()) {
|
||||
if (exception->IsObject()) {
|
||||
v8::Local<v8::Object> exc = v8::Local<v8::Object>::Cast(exception);
|
||||
v8::Local<v8::Value> stack =
|
||||
exc->Get(context, NewV8String("stack")).FromMaybe(exception);
|
||||
*exception_str = JS2String(stack);
|
||||
} else {
|
||||
*exception_str = JS2String(exception);
|
||||
}
|
||||
}
|
||||
return handle_scope.Escape(result);
|
||||
}
|
||||
|
@ -28,6 +28,11 @@ private:
|
||||
void injectFunctions(const char *objectName, const char *functionName,
|
||||
bool hashKey);
|
||||
|
||||
v8::Local<v8::Value> invokeMethod(const char *objectName,
|
||||
const char *functionName, int argc,
|
||||
v8::Local<v8::Value> argv[],
|
||||
std::string *exception_str);
|
||||
|
||||
public:
|
||||
V8Executor();
|
||||
|
||||
@ -39,6 +44,9 @@ public:
|
||||
|
||||
void injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property);
|
||||
|
||||
void invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments);
|
||||
};
|
||||
|
||||
#endif // V8EXECUTOR_H
|
||||
|
Reference in New Issue
Block a user