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) {
|
void DoricNativeDriver::invokeDoricMethod(QString method, QVariantList args) {
|
||||||
return DoricAsyncCall::ensureRunInThreadPool(
|
return DoricAsyncCall::ensureRunInThreadPool(
|
||||||
&jsEngine.mJSThreadPool, [this, method, args] {
|
&jsEngine.mJSThreadPool, [this, method, args] {
|
||||||
this->jsEngine.invokeDoricMethod(method, args).toString();
|
this->jsEngine.invokeDoricMethod(method, args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QMetaObject>
|
#include <QMetaObject>
|
||||||
|
|
||||||
#include "../DoricContextManager.h"
|
#include "../DoricContextManager.h"
|
||||||
@ -8,7 +10,9 @@ DoricBridgeExtension::DoricBridgeExtension(QObject *parent) : QObject(parent) {}
|
|||||||
|
|
||||||
void DoricBridgeExtension::callNative(QString contextId, QString module,
|
void DoricBridgeExtension::callNative(QString contextId, QString module,
|
||||||
QString methodName, QString callbackId,
|
QString methodName, QString callbackId,
|
||||||
QJSValue jsValue) {
|
QString argument) {
|
||||||
|
QJsonDocument document = QJsonDocument::fromJson(argument.toUtf8());
|
||||||
|
QJsonObject jsValue = document.object();
|
||||||
DoricContext *context =
|
DoricContext *context =
|
||||||
DoricContextManager::getInstance()->getContext(contextId);
|
DoricContextManager::getInstance()->getContext(contextId);
|
||||||
bool classRegistered =
|
bool classRegistered =
|
||||||
@ -17,10 +21,10 @@ void DoricBridgeExtension::callNative(QString contextId, QString module,
|
|||||||
QObject *plugin = context->obtainPlugin(module);
|
QObject *plugin = context->obtainPlugin(module);
|
||||||
QMetaObject::invokeMethod(plugin, methodName.toUtf8(), Qt::DirectConnection,
|
QMetaObject::invokeMethod(plugin, methodName.toUtf8(), Qt::DirectConnection,
|
||||||
QGenericReturnArgument(),
|
QGenericReturnArgument(),
|
||||||
Q_ARG(QJSValue, jsValue),
|
Q_ARG(QJsonObject, jsValue),
|
||||||
Q_ARG(QString, callbackId));
|
Q_ARG(QString, callbackId));
|
||||||
}
|
}
|
||||||
qDebug() << "contextId: " + contextId << "module: " + module
|
qDebug() << "contextId: " + contextId << "module: " + module
|
||||||
<< "methodName: " + methodName << "callbackId: " + callbackId
|
<< "methodName: " + methodName << "callbackId: " + callbackId
|
||||||
<< "jsValue: " + jsValue.toString();
|
<< "jsValue: " + argument;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ public:
|
|||||||
|
|
||||||
Q_INVOKABLE void callNative(QString contextId, QString module,
|
Q_INVOKABLE void callNative(QString contextId, QString module,
|
||||||
QString methodName, QString callbackId,
|
QString methodName, QString callbackId,
|
||||||
QJSValue jsValue);
|
QString argument);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BRIDGEEXTENSION_H
|
#endif // BRIDGEEXTENSION_H
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#ifndef INTERFACE_JSE_H
|
#ifndef INTERFACE_JSE_H
|
||||||
#define INTERFACE_JSE_H
|
#define INTERFACE_JSE_H
|
||||||
|
|
||||||
#include <QJSValue>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ public:
|
|||||||
virtual void injectGlobalJSFunction(QString name, QObject *function,
|
virtual void injectGlobalJSFunction(QString name, QObject *function,
|
||||||
QString property) = 0;
|
QString property) = 0;
|
||||||
|
|
||||||
virtual QJSValue invokeObject(QString objectName, QString functionName,
|
virtual void invokeObject(QString objectName, QString functionName,
|
||||||
QVariantList arguments) = 0;
|
QVariantList arguments) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void DoricJSEngine::prepareContext(QString contextId, QString script,
|
|||||||
mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source);
|
mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJSValue DoricJSEngine::invokeDoricMethod(QString method,
|
void DoricJSEngine::invokeDoricMethod(QString method,
|
||||||
QVariantList arguments) {
|
QVariantList arguments) {
|
||||||
return mJSE->invokeObject(DoricConstant::GLOBAL_DORIC, method, arguments);
|
return mJSE->invokeObject(DoricConstant::GLOBAL_DORIC, method, arguments);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
~DoricJSEngine();
|
~DoricJSEngine();
|
||||||
|
|
||||||
void prepareContext(QString contextId, QString script, QString source);
|
void prepareContext(QString contextId, QString script, QString source);
|
||||||
QJSValue invokeDoricMethod(QString method, QVariantList arguments);
|
void invokeDoricMethod(QString method, QVariantList arguments);
|
||||||
DoricRegistry *getRegistry();
|
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) {
|
QVariantList arguments) {
|
||||||
if (mType == JSEType::V8) {
|
if (mType == JSEType::V8) {
|
||||||
return QJSValue::UndefinedValue;
|
v8Executor->invokeObject(objectName, functionName, arguments);
|
||||||
} else if (mType == JSEType::Native) {
|
} 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,
|
void injectGlobalJSFunction(QString name, QObject *function,
|
||||||
QString property) override;
|
QString property) override;
|
||||||
|
|
||||||
QJSValue invokeObject(QString objectName, QString functionName,
|
void invokeObject(QString objectName, QString functionName,
|
||||||
QVariantList arguments) override;
|
QVariantList arguments) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#include "JSValueHelper.h"
|
#include "JSValueHelper.h"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
std::string JS2String(v8::Local<v8::Value> object) {
|
std::string JS2String(v8::Local<v8::Value> object) {
|
||||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||||
v8::HandleScope handleScope(isolate);
|
v8::HandleScope handleScope(isolate);
|
||||||
@ -55,3 +58,27 @@ v8::Local<v8::Value> String2JS(std::string string) {
|
|||||||
|
|
||||||
return handleScope.Escape(ret);
|
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
|
#ifndef JSVALUEHELPER_H
|
||||||
#define JSVALUEHELPER_H
|
#define JSVALUEHELPER_H
|
||||||
|
|
||||||
|
#include <QVariant>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "v8/v8.h"
|
#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> String2JS(std::string string);
|
||||||
|
|
||||||
|
v8::Local<v8::Value> Variant2JS(QVariant variant);
|
||||||
|
|
||||||
#endif // JSVALUEHELPER_H
|
#endif // JSVALUEHELPER_H
|
||||||
|
@ -72,6 +72,22 @@ 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,
|
||||||
|
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
|
// private segment
|
||||||
void V8Executor::injectObject(const char *string, v8::Local<v8::Value> local) {
|
void V8Executor::injectObject(const char *string, v8::Local<v8::Value> local) {
|
||||||
v8::Isolate *isolate = m_isolate;
|
v8::Isolate *isolate = m_isolate;
|
||||||
@ -214,11 +230,11 @@ static void InjectedFunction(const v8::FunctionCallbackInfo<v8::Value> &args) {
|
|||||||
QMetaObject::invokeMethod(
|
QMetaObject::invokeMethod(
|
||||||
pair.first, pair.second.toUtf8().constData(), Qt::DirectConnection,
|
pair.first, pair.second.toUtf8().constData(), Qt::DirectConnection,
|
||||||
QGenericReturnArgument(),
|
QGenericReturnArgument(),
|
||||||
Q_ARG(QString, QString::fromStdString(argString0)),
|
Q_ARG(QString, QString::fromUtf8(argString0.c_str())),
|
||||||
Q_ARG(QString, QString::fromStdString(argString1)),
|
Q_ARG(QString, QString::fromUtf8(argString1.c_str())),
|
||||||
Q_ARG(QString, QString::fromStdString(argString2)),
|
Q_ARG(QString, QString::fromUtf8(argString2.c_str())),
|
||||||
Q_ARG(QString, QString::fromStdString(argString3)),
|
Q_ARG(QString, QString::fromUtf8(argString3.c_str())),
|
||||||
Q_ARG(QString, QString::fromStdString(argString4)));
|
Q_ARG(QString, QString::fromUtf8(argString4.c_str())));
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin check to perform micro task checkpoint
|
// 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);
|
v8::Maybe<bool> result = object->Set(context, name, function);
|
||||||
result.ToChecked();
|
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,
|
void injectFunctions(const char *objectName, const char *functionName,
|
||||||
bool hashKey);
|
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:
|
public:
|
||||||
V8Executor();
|
V8Executor();
|
||||||
|
|
||||||
@ -39,6 +44,9 @@ public:
|
|||||||
|
|
||||||
void injectGlobalJSFunction(QString name, QObject *function,
|
void injectGlobalJSFunction(QString name, QObject *function,
|
||||||
QString property);
|
QString property);
|
||||||
|
|
||||||
|
void invokeObject(QString objectName, QString functionName,
|
||||||
|
QVariantList arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // V8EXECUTOR_H
|
#endif // V8EXECUTOR_H
|
||||||
|
Reference in New Issue
Block a user