diff --git a/doric-Qt/doric/context.cpp b/doric-Qt/doric/context.cpp index 6b6c5105..ca91e455 100644 --- a/doric-Qt/doric/context.cpp +++ b/doric-Qt/doric/context.cpp @@ -1,9 +1,12 @@ #include "context.h" #include "native_driver.h" #include "context_manager.h" +#include "utils/constant.h" Context::Context(QString contextId, QString source, QString extra) { + this->mRootNode = new RootNode(); + this->mContextId = contextId; this->source = source; this->extra = extra; @@ -13,9 +16,41 @@ Context* Context::create(QString script, QString source, QString extra) { Context *context = ContextManager::getInstance()->createContext(script, source, extra); context->script = script; + context->init(extra); + + QVariantList args; + context->callEntity(Constant::DORIC_ENTITY_CREATE, args); return context; } +void Context::init(QString initData) +{ + this->extra = initData; + if (!initData.isEmpty()) { + QVariantList args; + args.push_back(initData); + callEntity(Constant::DORIC_ENTITY_INIT, args); + } +} + +void Context::build(int width, int height) +{ + QMap map; + map.insert("width", QVariant(width)); + map.insert("height", QVariant(height)); + QVariant jsValue(map); + this->initParams = jsValue; + + QVariantList args; + args.push_back(this->initParams); + callEntity(Constant::DORIC_ENTITY_BUILD, args); +} + +void Context::callEntity(QString methodName, QVariantList args) +{ + return getDriver()->invokeContextEntityMethod(this->mContextId, methodName, args); +} + InterfaceDriver* Context::getDriver() { if (driver == NULL) diff --git a/doric-Qt/doric/context.h b/doric-Qt/doric/context.h index 0cbaaa27..2f4d46e6 100644 --- a/doric-Qt/doric/context.h +++ b/doric-Qt/doric/context.h @@ -1,17 +1,20 @@ #ifndef CONTEXT_H #define CONTEXT_H -#include +#include #include "interface_driver.h" +#include "shader/root_node.h" class Context { private: QString mContextId; + RootNode *mRootNode; QString source; QString script; QString extra; + QVariant initParams; InterfaceDriver *driver = NULL; public: @@ -19,6 +22,12 @@ public: static Context* create(QString script, QString source, QString extra); + void init(QString initData); + + void build(int width, int height); + + void callEntity(QString methodName, QVariantList args); + InterfaceDriver* getDriver(); }; diff --git a/doric-Qt/doric/demo/demo_bridge.cpp b/doric-Qt/doric/demo/demo_bridge.cpp new file mode 100644 index 00000000..c1a40437 --- /dev/null +++ b/doric-Qt/doric/demo/demo_bridge.cpp @@ -0,0 +1,23 @@ +#include + +#include "demo_bridge.h" +#include "utils/utils.h" +#include "panel.h" + +DemoBridge::DemoBridge(QObject *parent) : QObject(parent) +{ + +} + +void DemoBridge::navigate(QVariant route) +{ + switch (route.toInt()) { + case 0: + QString name = "Snake.js"; + QString script = Utils::readAssetFile("/doric/bundles", name); + + Panel panel; + panel.config(script, name, NULL); + break; + } +} diff --git a/doric-Qt/doric/demo/demo_bridge.h b/doric-Qt/doric/demo/demo_bridge.h new file mode 100644 index 00000000..258da1c6 --- /dev/null +++ b/doric-Qt/doric/demo/demo_bridge.h @@ -0,0 +1,19 @@ +#ifndef DEMOBRIDGE_H +#define DEMOBRIDGE_H + +#include +#include + +class DemoBridge : public QObject +{ + Q_OBJECT +public: + explicit DemoBridge(QObject *parent = nullptr); + + Q_INVOKABLE + void navigate(QVariant route); +signals: + +}; + +#endif // DEMOBRIDGE_H diff --git a/doric-Qt/doric/doric.pro b/doric-Qt/doric/doric.pro index 74a6081a..2afbc2b9 100644 --- a/doric-Qt/doric/doric.pro +++ b/doric-Qt/doric/doric.pro @@ -18,14 +18,18 @@ SOURCES += \ async/settable_future.cpp \ context.cpp \ context_manager.cpp \ + demo/demo_bridge.cpp \ engine/bridge_extension.cpp \ engine/js_engine.cpp \ engine/native_empty.cpp \ engine/native_jse.cpp \ engine/native_log.cpp \ + engine/native_require.cpp \ engine/timer_extension.cpp \ main.cpp \ native_driver.cpp \ + panel.cpp \ + shader/root_node.cpp \ utils/constant.cpp RESOURCES += qml.qrc @@ -48,15 +52,19 @@ HEADERS += \ async/settable_future.h \ context.h \ context_manager.h \ + demo/demo_bridge.h \ engine/bridge_extension.h \ engine/interface_jse.h \ engine/js_engine.h \ engine/native_empty.h \ engine/native_jse.h \ engine/native_log.h \ + engine/native_require.h \ engine/timer_extension.h \ interface_driver.h \ native_driver.h \ + panel.h \ + shader/root_node.h \ template/singleton.h \ utils/constant.h \ utils/count_down_latch.h \ diff --git a/doric-Qt/doric/doric.pro.user b/doric-Qt/doric/doric.pro.user index 139c9ffe..86fd3c26 100644 --- a/doric-Qt/doric/doric.pro.user +++ b/doric-Qt/doric/doric.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/doric-Qt/doric/engine/interface_jse.h b/doric-Qt/doric/engine/interface_jse.h index d45bc67a..7f740b2f 100644 --- a/doric-Qt/doric/engine/interface_jse.h +++ b/doric-Qt/doric/engine/interface_jse.h @@ -13,7 +13,7 @@ public: virtual void injectGlobalJSFunction(QString name, QObject *function, QString property) = 0; - virtual QJSValue invokeObject(QString objectName, QString functionName, QJSValueList arguments) = 0; + virtual QJSValue invokeObject(QString objectName, QString functionName, QVariantList arguments) = 0; }; #endif // INTERFACE_JSE_H diff --git a/doric-Qt/doric/engine/js_engine.cpp b/doric-Qt/doric/engine/js_engine.cpp index 6a612b96..76ef3d86 100644 --- a/doric-Qt/doric/engine/js_engine.cpp +++ b/doric-Qt/doric/engine/js_engine.cpp @@ -10,6 +10,7 @@ #include "../utils/constant.h" #include "native_log.h" #include "native_empty.h" +#include "native_require.h" #include "timer_extension.h" #include "bridge_extension.h" #include "../utils/utils.h" @@ -51,11 +52,14 @@ JSEngine::JSEngine(QObject *parent) : QObject(parent) NativeEmpty *nativeEmpty = new NativeEmpty(); mJSE->injectGlobalJSFunction(Constant::INJECT_EMPTY, nativeEmpty, "function"); + // inject require + NativeRequire *nativeRequire = new NativeRequire(); + mJSE->injectGlobalJSFunction(Constant::INJECT_REQUIRE, nativeRequire, "function"); + // inject timer set & clear - std::function func = [](){}; TimerExtension *timerExtension = new TimerExtension([this](long timerId){ - QJSValueList arguments; - arguments.append(QJSValue((int)timerId)); + QVariantList arguments; + arguments.push_back(QVariant((int)timerId)); this->invokeDoricMethod(Constant::DORIC_TIMER_CALLBACK, arguments); }); mJSE->injectGlobalJSFunction(Constant::INJECT_TIMER_SET, timerExtension, "setTimer"); @@ -75,7 +79,7 @@ JSEngine::JSEngine(QObject *parent) : QObject(parent) }); } -QJSValue JSEngine::invokeDoricMethod(QString method, QJSValueList arguments) +QJSValue JSEngine::invokeDoricMethod(QString method, QVariantList arguments) { return mJSE->invokeObject(Constant::GLOBAL_DORIC, method, arguments); } diff --git a/doric-Qt/doric/engine/js_engine.h b/doric-Qt/doric/engine/js_engine.h index 7eefa1d7..61e974aa 100644 --- a/doric-Qt/doric/engine/js_engine.h +++ b/doric-Qt/doric/engine/js_engine.h @@ -22,7 +22,7 @@ public: ~JSEngine(); - QJSValue invokeDoricMethod(QString method, QJSValueList arguments); + QJSValue invokeDoricMethod(QString method, QVariantList arguments); void prepareContext(QString contextId, QString script, QString source); }; diff --git a/doric-Qt/doric/engine/native_jse.cpp b/doric-Qt/doric/engine/native_jse.cpp index 22cb6314..b6ea870c 100644 --- a/doric-Qt/doric/engine/native_jse.cpp +++ b/doric-Qt/doric/engine/native_jse.cpp @@ -35,9 +35,35 @@ void NativeJSE::injectGlobalJSFunction(QString name, QObject *function, QString mJSEngine.globalObject().setProperty(name, functionObject.property(property)); } -QJSValue NativeJSE::invokeObject(QString objectName, QString functionName, QJSValueList arguments) +QJSValue NativeJSE::invokeObject(QString objectName, QString functionName, QVariantList arguments) { QJSValue object = mJSEngine.evaluate(objectName); QJSValue function = object.property(functionName); - return function.call(arguments); + + QJSValueList args; + foreach(QVariant variant, arguments) { + if (variant.type() == QVariant::String) { + args.push_back(QJSValue(variant.toString())); + } else if (variant.type() == QVariant::Map) { + QJSValue arg = mJSEngine.newObject(); + QMap map = variant.toMap(); + foreach (QString key, map.keys()) { + QVariant value = map.value(key); + if (value.type() == QVariant::String) { + arg.setProperty(key, value.toString()); + } else if (value.type() == QVariant::Int) { + arg.setProperty(key, value.toInt()); + } + } + args.push_back(arg); + } + } + + QJSValue result = function.call(args); + if (result.isError()) + qDebug() + << "Uncaught exception at line" + << result.property("lineNumber").toInt() + << ":" << result.toString(); + return result; } diff --git a/doric-Qt/doric/engine/native_jse.h b/doric-Qt/doric/engine/native_jse.h index 21792afd..dbdb62f2 100644 --- a/doric-Qt/doric/engine/native_jse.h +++ b/doric-Qt/doric/engine/native_jse.h @@ -17,7 +17,7 @@ public: void injectGlobalJSFunction(QString name, QObject *function, QString property) override; - QJSValue invokeObject(QString objectName, QString functionName, QJSValueList arguments) override; + QJSValue invokeObject(QString objectName, QString functionName, QVariantList arguments) override; }; #endif // NATIVE_JSE_H diff --git a/doric-Qt/doric/engine/native_require.cpp b/doric-Qt/doric/engine/native_require.cpp new file mode 100644 index 00000000..407a956e --- /dev/null +++ b/doric-Qt/doric/engine/native_require.cpp @@ -0,0 +1,8 @@ +#include "native_require.h" + +#include + +Q_INVOKABLE QJSValue NativeRequire::function(QString name) { + qDebug() << "nativeRequire"; + return QJSValue::NullValue; +} diff --git a/doric-Qt/doric/engine/native_require.h b/doric-Qt/doric/engine/native_require.h new file mode 100644 index 00000000..3044ad2f --- /dev/null +++ b/doric-Qt/doric/engine/native_require.h @@ -0,0 +1,18 @@ +#ifndef NATIVE_REQUIRE_H +#define NATIVE_REQUIRE_H + + +#include +#include + +class NativeRequire : public QObject { + Q_OBJECT + +public: + NativeRequire(QObject *parent = nullptr) : QObject(parent) {} + + Q_INVOKABLE QJSValue function(QString name); +}; + + +#endif // NATIVE_REQUIRE_H diff --git a/doric-Qt/doric/interface_driver.h b/doric-Qt/doric/interface_driver.h index 82d2a196..892780d4 100644 --- a/doric-Qt/doric/interface_driver.h +++ b/doric-Qt/doric/interface_driver.h @@ -2,14 +2,14 @@ #define INTERFACEDRIVER_H #include -#include +#include class InterfaceDriver { public: - virtual void invokeContextEntityMethod(QString contextId, QString method, QList args) = 0; + virtual void invokeContextEntityMethod(QString contextId, QString method, QVariantList args) = 0; - virtual void invokeDoricMethod(QString method, QList args) = 0; + virtual void invokeDoricMethod(QString method, QVariantList args) = 0; virtual void createContext(QString contextId, QString script, QString source) = 0; diff --git a/doric-Qt/doric/main.cpp b/doric-Qt/doric/main.cpp index db8d3b83..6a67adf4 100644 --- a/doric-Qt/doric/main.cpp +++ b/doric-Qt/doric/main.cpp @@ -1,5 +1,8 @@ #include #include +#include + +#include "demo/demo_bridge.h" int main(int argc, char *argv[]) { @@ -14,7 +17,11 @@ int main(int argc, char *argv[]) if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); - engine.load(url); + + DemoBridge *demoBridge = new DemoBridge(); + auto context = engine.rootContext(); + context->setContextProperty("demoBridge", demoBridge); + engine.load(url); return app.exec(); } diff --git a/doric-Qt/doric/main.qml b/doric-Qt/doric/main.qml index 382f8f5e..e0a81f51 100644 --- a/doric-Qt/doric/main.qml +++ b/doric-Qt/doric/main.qml @@ -12,11 +12,20 @@ ApplicationWindow { ListView { width: parent.width - model: 20 - delegate: ItemDelegate { - text: "Item " + (index + 1) + model: 1 + delegate: Rectangle { + Column { + anchors.centerIn: parent + Text { + text: {return "Snake.js"} + } + } width: parent.width - height: 100 + height: 60 + MouseArea { + anchors.fill: parent + onClicked: {demoBridge.navigate(index)} + } } } } diff --git a/doric-Qt/doric/native_driver.cpp b/doric-Qt/doric/native_driver.cpp index 497d12ce..db45c515 100644 --- a/doric-Qt/doric/native_driver.cpp +++ b/doric-Qt/doric/native_driver.cpp @@ -1,16 +1,21 @@ -#include "native_driver.h" -#include "async/async_call.h" - #include -void NativeDriver::invokeContextEntityMethod(QString contextId, QString method, QList args) -{ +#include "native_driver.h" +#include "async/async_call.h" +#include "utils/constant.h" +void NativeDriver::invokeContextEntityMethod(QString contextId, QString method, QVariantList args) +{ + args.insert(0, QVariant(contextId)); + args.insert(1, QVariant(method)); + invokeDoricMethod(Constant::DORIC_CONTEXT_INVOKE, args); } -void NativeDriver::invokeDoricMethod(QString method, QList args) +void NativeDriver::invokeDoricMethod(QString method, QVariantList args) { - + return AsyncCall::ensureRunInThreadPool(&jsEngine.mJSThreadPool, [this, method, args]{ + qDebug() << "invokeDoricMethod: " << this->jsEngine.invokeDoricMethod(method, args).toString(); + }); } void NativeDriver::createContext(QString contextId, QString script, QString source) diff --git a/doric-Qt/doric/native_driver.h b/doric-Qt/doric/native_driver.h index b8315a68..d194d785 100644 --- a/doric-Qt/doric/native_driver.h +++ b/doric-Qt/doric/native_driver.h @@ -29,9 +29,9 @@ public: return &instance; } - void invokeContextEntityMethod(QString contextId, QString method, QList args) override; + void invokeContextEntityMethod(QString contextId, QString method, QVariantList args) override; - void invokeDoricMethod(QString method, QList args) override; + void invokeDoricMethod(QString method, QVariantList args) override; void createContext(QString contextId, QString script, QString source) override; diff --git a/doric-Qt/doric/panel.cpp b/doric-Qt/doric/panel.cpp new file mode 100644 index 00000000..749c034e --- /dev/null +++ b/doric-Qt/doric/panel.cpp @@ -0,0 +1,18 @@ +#include "panel.h" + +Panel::Panel() +{ + +} + +void Panel::config(QString script, QString alias, QString extra) +{ + Context *context = Context::create(script, alias, extra); + config(context); +} + +void Panel::config(Context *context) +{ + this->mContext = context; + this->mContext->build(960, 720); +} diff --git a/doric-Qt/doric/panel.h b/doric-Qt/doric/panel.h new file mode 100644 index 00000000..363d44b7 --- /dev/null +++ b/doric-Qt/doric/panel.h @@ -0,0 +1,21 @@ +#ifndef PANEL_H +#define PANEL_H + +#include "context.h" + +class Panel +{ +private: + Context *mContext; + int renderedWidth = -1; + int renderedHeight = -1; + +public: + Panel(); + + void config(QString script, QString alias, QString extra); + + void config(Context *context); +}; + +#endif // PANEL_H diff --git a/doric-Qt/doric/qml.qrc b/doric-Qt/doric/qml.qrc index 79a873d0..8888cbef 100644 --- a/doric-Qt/doric/qml.qrc +++ b/doric-Qt/doric/qml.qrc @@ -2,10 +2,13 @@ main.qml qtquickcontrols2.conf + view.qml ../../doric-js/bundle/doric-sandbox.js ../../doric-js/bundle/doric-lib.js + + ../../doric-demo/bundle/src/Snake.js diff --git a/doric-Qt/doric/shader/root_node.cpp b/doric-Qt/doric/shader/root_node.cpp new file mode 100644 index 00000000..66e79a9b --- /dev/null +++ b/doric-Qt/doric/shader/root_node.cpp @@ -0,0 +1,6 @@ +#include "root_node.h" + +RootNode::RootNode() +{ + +} diff --git a/doric-Qt/doric/shader/root_node.h b/doric-Qt/doric/shader/root_node.h new file mode 100644 index 00000000..11643b6d --- /dev/null +++ b/doric-Qt/doric/shader/root_node.h @@ -0,0 +1,10 @@ +#ifndef ROOTNODE_H +#define ROOTNODE_H + +class RootNode +{ +public: + RootNode(); +}; + +#endif // ROOTNODE_H diff --git a/doric-Qt/doric/utils/constant.cpp b/doric-Qt/doric/utils/constant.cpp index 65b95ae5..2dd39c01 100644 --- a/doric-Qt/doric/utils/constant.cpp +++ b/doric-Qt/doric/utils/constant.cpp @@ -34,4 +34,9 @@ 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 = "doric"; +const QString Constant::DORIC_CONTEXT_INVOKE = "jsCallEntityMethod"; const QString Constant::DORIC_TIMER_CALLBACK = "jsCallbackTimer"; + +const QString Constant::DORIC_ENTITY_INIT = "__init__"; +const QString Constant::DORIC_ENTITY_CREATE = "__onCreate__"; +const QString Constant::DORIC_ENTITY_BUILD = "__build__"; diff --git a/doric-Qt/doric/utils/constant.h b/doric-Qt/doric/utils/constant.h index bb623eba..af236335 100644 --- a/doric-Qt/doric/utils/constant.h +++ b/doric-Qt/doric/utils/constant.h @@ -23,7 +23,12 @@ 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_CREATE; + static const QString DORIC_ENTITY_INIT; + static const QString DORIC_ENTITY_BUILD; }; diff --git a/doric-Qt/doric/utils/utils.h b/doric-Qt/doric/utils/utils.h index 56add525..2996a7aa 100644 --- a/doric-Qt/doric/utils/utils.h +++ b/doric-Qt/doric/utils/utils.h @@ -14,6 +14,7 @@ public: QFile *file = new QFile(resource.fileName()); file->open(QFile::ReadOnly | QFile::Text); QTextStream in(file); + in.setCodec("UTF-8"); QString content = in.readAll(); file->close(); delete file; diff --git a/doric-Qt/doric/view.qml b/doric-Qt/doric/view.qml new file mode 100644 index 00000000..7aef5fee --- /dev/null +++ b/doric-Qt/doric/view.qml @@ -0,0 +1,6 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.5 + +Rectangle { + color: 'red' +}