From 06f96f33fe3f85b9d6c2c4a8d8add48111d8e299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8A=B2=E9=B9=8F?= Date: Fri, 6 Dec 2019 19:47:59 +0800 Subject: [PATCH] handle js value convert & function invocation --- doric/constant.cpp | 2 ++ doric/constant.h | 2 ++ doric/context.h | 32 ++++++++++++++++------- doric/doric.pro | 3 ++- doric/driver/driver.h | 4 ++- doric/driver/native_driver.cpp | 33 ++++++++++++++++++++++- doric/driver/native_driver.h | 4 +-- doric/main.cpp | 1 + doric/utility/utility.h | 48 ++++++++++++++++++++++++++++++++++ 9 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 doric/utility/utility.h diff --git a/doric/constant.cpp b/doric/constant.cpp index b6452a0c..a7b07131 100644 --- a/doric/constant.cpp +++ b/doric/constant.cpp @@ -29,6 +29,8 @@ const QString Constant::TEMPLATE_MODULE = QString("Reflect.apply(doric.jsRegiste const QString Constant::TEMPLATE_CONTEXT_DESTROY = QString("doric.jsReleaseContext(\"%s\")"); const QString Constant::GLOBAL_DORIC = QString("doric"); +const QString Constant::DORIC_CONTEXT_INVOKE = QString("jsCallEntityMethod"); const QString Constant::DORIC_TIMER_CALLBACK = QString("jsCallbackTimer"); const QString Constant::DORIC_ENTITY_INIT = QString("__init__"); +const QString Constant::DORIC_ENTITY_SHOW = QString("__onShow__"); diff --git a/doric/constant.h b/doric/constant.h index e6d32a66..c02a3ba0 100644 --- a/doric/constant.h +++ b/doric/constant.h @@ -18,9 +18,11 @@ public: static const QString TEMPLATE_CONTEXT_DESTROY; static const QString GLOBAL_DORIC; + static const QString DORIC_CONTEXT_INVOKE; static const QString DORIC_TIMER_CALLBACK; static const QString DORIC_ENTITY_INIT; + static const QString DORIC_ENTITY_SHOW; }; #endif // CONSTANT_H diff --git a/doric/context.h b/doric/context.h index e53d8956..59cbf45e 100644 --- a/doric/context.h +++ b/doric/context.h @@ -24,16 +24,30 @@ public: this->source = source; } - void init(double width, double height) { - QJsonObject* params = new QJsonObject(); - params->insert("width", width); - params->insert("height", height); - QJsonDocument* jsonDocument = new QJsonDocument(); - jsonDocument->setObject(*params); - QString strJson(jsonDocument->toJson(QJsonDocument::Compact)); + void show() { + QString* method = new QString(Constant::DORIC_ENTITY_SHOW); + QVector* arguments = new QVector(); - delete params; - delete jsonDocument; + driver->invokeContextEntityMethod(contextId, method, nullptr); + + delete arguments; + delete method; + } + + void init(double width, double height) { + QJsonObject* jsonObject = new QJsonObject(); + jsonObject->insert("width", width); + jsonObject->insert("height", height); + + QString* method = new QString(Constant::DORIC_ENTITY_INIT); + QVariant* variant = new QVariant(); + variant->setValue(*jsonObject); + + driver->invokeContextEntityMethod(contextId, method, variant, nullptr); + + delete variant; + delete method; + delete jsonObject; } }; diff --git a/doric/doric.pro b/doric/doric.pro index 69c073fa..64b9c924 100644 --- a/doric/doric.pro +++ b/doric/doric.pro @@ -42,4 +42,5 @@ HEADERS += \ native/native_empty.h \ native/native_log.h \ native/native_timer.h \ - template/singleton.h + template/singleton.h \ + utility/utility.h diff --git a/doric/driver/driver.h b/doric/driver/driver.h index 42a2c829..aafb11b5 100644 --- a/doric/driver/driver.h +++ b/doric/driver/driver.h @@ -8,7 +8,9 @@ class Driver { public: virtual void createContext(int contextId, QString* script) = 0; virtual void destroyContext(int contextId) = 0; - virtual void invokeContextEntityMethod(int contextId, QString* method, QVector* arguments) = 0; + + virtual void invokeContextEntityMethod(int contextId, QString* method, ...) = 0; + virtual void invokeDoricMethod(QString* method, ...) = 0; virtual ~Driver() = default; }; diff --git a/doric/driver/native_driver.cpp b/doric/driver/native_driver.cpp index 716d88a4..9f479952 100644 --- a/doric/driver/native_driver.cpp +++ b/doric/driver/native_driver.cpp @@ -1,4 +1,7 @@ +#include "stdarg.h" + #include "native_driver.h" +#include "utility/utility.h" NativeDriver::~NativeDriver() { qDebug() << "NativeDriver destructor"; @@ -12,6 +15,34 @@ void NativeDriver::destroyContext(int contextId) { jsEngine->destroyContext(contextId); } -void NativeDriver::invokeContextEntityMethod(int contextId, QString* method, QVector* arguments) { +void NativeDriver::invokeContextEntityMethod(int contextId, QString* method, ...) { + QJSValueList* arguments = new QJSValueList(); + arguments->append(QJSValue(QString::number(contextId))); + arguments->append(QJSValue(*method)); + + va_list vaList; + va_start(vaList, method); + auto argument = va_arg(vaList, QVariant*); + while (argument != nullptr) { + if (QString(typeid(QJsonObject).name()).contains(QString(argument->typeName()))) { + QJsonObject* jsonObject = static_cast(argument->data()); + QJsonValue* jsonValue = new QJsonValue(*jsonObject); + QJSValue jsValue = Utility::convert(jsEngine->engine, *jsonValue); + delete jsonValue; + arguments->append(jsValue); + } + argument = va_arg(vaList, QVariant*); + } + va_end(vaList); + + QJSValue result = jsEngine->engine->globalObject() + .property(Constant::GLOBAL_DORIC) + .property(Constant::DORIC_CONTEXT_INVOKE) + .call(*arguments); + qDebug() << result.toString(); + delete arguments; +} + +void NativeDriver::invokeDoricMethod(QString *method, ...) { } diff --git a/doric/driver/native_driver.h b/doric/driver/native_driver.h index 542ae4eb..488d05db 100644 --- a/doric/driver/native_driver.h +++ b/doric/driver/native_driver.h @@ -26,10 +26,10 @@ public: } void createContext(int contextId, QString *script) override; - void destroyContext(int contextId) override; - void invokeContextEntityMethod(int contextId, QString* method, QVector* arguments) override; + void invokeContextEntityMethod(int contextId, QString* method, ...) override; + void invokeDoricMethod(QString* method, ...) override; }; #endif // NATIVE_DRIVER_H diff --git a/doric/main.cpp b/doric/main.cpp index 24455ba2..72dfca14 100644 --- a/doric/main.cpp +++ b/doric/main.cpp @@ -31,6 +31,7 @@ int main(int argc, char *argv[]) QString* source = new QString("Snake.js"); Context *context = ContextManager::getInstance()->createContext(&script, source); + context->show(); context->init(180, 320); delete source; } diff --git a/doric/utility/utility.h b/doric/utility/utility.h new file mode 100644 index 00000000..74cdb12f --- /dev/null +++ b/doric/utility/utility.h @@ -0,0 +1,48 @@ +#ifndef UTILITY_H +#define UTILITY_H + +#include +#include +#include +#include + +class Utility { + +public: + static QJSValue convert(QJSEngine* jsEngine, QJsonValue jsonValue) { + if (jsonValue.isBool()) { + return QJSValue(jsonValue.toBool()); + } else if (jsonValue.isString()) { + return QJSValue(jsonValue.toString()); + } else if (jsonValue.isDouble()) { + return QJSValue(jsonValue.toDouble()); + } else if (jsonValue.isNull()) { + return QJSValue(QJSValue::NullValue); + } else if (jsonValue.isUndefined()) { + return QJSValue(QJSValue::UndefinedValue); + } else if (jsonValue.isObject()) { + QJsonObject jsonObject = jsonValue.toObject(); + QJSValue jsValue = jsEngine->newObject(); + for (auto iterator = jsonObject.begin(); iterator != jsonObject.end(); iterator++) { + QString key = iterator.key(); + QJsonValue value = iterator.value(); + QJSValue convertedValue = convert(jsEngine, value); + jsValue.setProperty(key, convertedValue); + } + return jsValue; + } else if (jsonValue.isArray()) { + QJsonArray jsonArray = jsonValue.toArray(); + QJSValue jsValue = jsEngine->newArray(jsonArray.size()); + for (int i = 0; i < jsonArray.size(); i++) { + QJsonValue value = jsonArray[i]; + QJSValue convertedValue = convert(jsEngine, value); + jsValue.setProperty(i, convertedValue); + } + return jsValue; + } + + return QJSValue(QJSValue::UndefinedValue); + } +}; + +#endif // UTILITY_H