diff --git a/doric-Qt/doric/.gitignore b/doric-Qt/doric/.gitignore deleted file mode 100644 index fab7372d..00000000 --- a/doric-Qt/doric/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# This file is used to ignore files which are generated -# ---------------------------------------------------------------------------- - -*~ -*.autosave -*.a -*.core -*.moc -*.o -*.obj -*.orig -*.rej -*.so -*.so.* -*_pch.h.cpp -*_resource.rc -*.qm -.#* -*.*# -core -!core/ -tags -.DS_Store -.directory -*.debug -Makefile* -*.prl -*.app -moc_*.cpp -ui_*.h -qrc_*.cpp -Thumbs.db -*.res -*.rc -/.qmake.cache -/.qmake.stash - -# qtcreator generated files -*.pro.user* - -# xemacs temporary files -*.flc - -# Vim temporary files -.*.swp - -# Visual Studio generated files -*.ib_pdb_index -*.idb -*.ilk -*.pdb -*.sln -*.suo -*.vcproj -*vcproj.*.*.user -*.ncb -*.sdf -*.opensdf -*.vcxproj -*vcxproj.* - -# MinGW generated files -*.Debug -*.Release - -# Python byte code -*.pyc - -# Binaries -# -------- -*.dll -*.exe - diff --git a/doric-Qt/doric/async/async_call.h b/doric-Qt/doric/async/async_call.h new file mode 100644 index 00000000..f9ec5fab --- /dev/null +++ b/doric-Qt/doric/async/async_call.h @@ -0,0 +1,15 @@ +#ifndef ASYNC_CALL_H +#define ASYNC_CALL_H + +#include + +class AsyncCall { + +public: + static void ensureRunInThreadPool(QThreadPool &threadPool, QRunnable *runnable) + { + + } +}; + +#endif // ASYNC_CALL_H diff --git a/doric-Qt/doric/async/async_result.cpp b/doric-Qt/doric/async/async_result.cpp new file mode 100644 index 00000000..a1d20f90 --- /dev/null +++ b/doric-Qt/doric/async/async_result.cpp @@ -0,0 +1,56 @@ +#include "async_result.h" + +AsyncResult::AsyncResult() +{ + +} + +AsyncResult::AsyncResult(QJSValue result) +{ + this->result = result; +} + +void AsyncResult::setResult(QJSValue result) +{ + this->result = result; + if (this->callback != NULL) { + this->callback->onResult(result); + this->callback->onFinish(); + } +} + +void AsyncResult::setError(QJSValue exception) +{ + this->result = exception; + if (this->callback != NULL) { + this->callback->onResult(result); + this->callback->onFinish(); + } +} + +bool AsyncResult::hasResult() +{ + return !result.equals(EMPTY); +} + +QJSValue AsyncResult::getResult() +{ + return this->result; +} + +void AsyncResult::setCallback(Callback *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(); + } +} + +SettableFuture* AsyncResult::synchronous() +{ + return NULL; +} diff --git a/doric-Qt/doric/async/async_result.h b/doric-Qt/doric/async/async_result.h index 2b12b77b..922414e2 100644 --- a/doric-Qt/doric/async/async_result.h +++ b/doric-Qt/doric/async/async_result.h @@ -1,60 +1,35 @@ -#ifndef ASYNC_RESULT_H -#define ASYNC_RESULT_H +#ifndef ASYNCRESULT_H +#define ASYNCRESULT_H -#include -#include +#include #include "callback.h" +#include "settable_future.h" -template -class AsyncResult { +static QJSValue EMPTY(QJSValue::NullValue); +class AsyncResult +{ private: - QVariant result; - Callback *callback = nullptr; + QJSValue result = EMPTY; + Callback *callback; public: - AsyncResult() {} + AsyncResult(); - AsyncResult(R result) { - this->result.setValue(result); - } + AsyncResult(QJSValue result); - void setResult(R result) { - this->result.setValue(result); - if (callback != nullptr) { - this->callback->onResult(result); - this->callback->onFinish(); - } - } + void setResult(QJSValue result); - void setError(QException exception) { - this->result->setValue(exception); - if (callback != nullptr) { - this->callback->onError(exception); - this->callback->onFinish(); - } - } + void setError(QJSValue exception); - bool hasResult() { - qDebug() << result.typeName(); - return !QString(result.typeName()).isEmpty(); - } + bool hasResult(); - R *getResult() { - return static_cast(result.data()); - } + QJSValue getResult(); - void setCallback(Callback *callback) { - this->callback = callback; - if (QException *exception = static_cast(result.data())) { - this->callback->onError(*exception); - this->callback->onFinish(); - } else if (hasResult()) { - this->callback->onResult(*getResult()); - this->callback->onFinish(); - } - } + void setCallback(Callback *callback); + + SettableFuture *synchronous(); }; -#endif // ASYNC_RESULT_H +#endif // ASYNCRESULT_H diff --git a/doric-Qt/doric/async/callback.h b/doric-Qt/doric/async/callback.h index 767b9eac..92ed77bd 100644 --- a/doric-Qt/doric/async/callback.h +++ b/doric-Qt/doric/async/callback.h @@ -1,16 +1,13 @@ #ifndef CALLBACK_H #define CALLBACK_H -#include +#include -template class Callback { - public: + virtual void onResult(QJSValue result) = 0; - virtual void onResult(R result) = 0; - - virtual void onError(QException exception) = 0; + virtual void onError(QJSValue error) = 0; virtual void onFinish() = 0; }; diff --git a/doric-Qt/doric/async/settable_future.cpp b/doric-Qt/doric/async/settable_future.cpp new file mode 100644 index 00000000..8141ba43 --- /dev/null +++ b/doric-Qt/doric/async/settable_future.cpp @@ -0,0 +1,20 @@ +#include + +#include "settable_future.h" + +void SettableFuture::set(QJSValue result) +{ + if (mReadyLatch == NULL) + { + qDebug() << "Result has already been set!"; + return; + } + mResult = result; + delete mReadyLatch; +} + +QJSValue SettableFuture::get() +{ + mReadyLatch->lock(); + return mResult; +} diff --git a/doric-Qt/doric/async/settable_future.h b/doric-Qt/doric/async/settable_future.h new file mode 100644 index 00000000..e24751e8 --- /dev/null +++ b/doric-Qt/doric/async/settable_future.h @@ -0,0 +1,18 @@ +#ifndef SETTABLE_FUTURE_H +#define SETTABLE_FUTURE_H + +#include +#include "utils/count_down_latch.h" + +class SettableFuture { +private: + QJSValue mResult; + CountDownLatch *mReadyLatch = new CountDownLatch(); + +public: + void set(QJSValue result); + + QJSValue get(); +}; + +#endif // SETTABLE_FUTURE_H diff --git a/doric-Qt/doric/constant.cpp b/doric-Qt/doric/constant.cpp deleted file mode 100644 index a7b07131..00000000 --- a/doric-Qt/doric/constant.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "constant.h" - -const QString Constant::INJECT_LOG = "nativeLog"; -const QString Constant::INJECT_REQUIRE = "nativeRequire"; -const QString Constant::INJECT_TIMER_SET = "nativeSetTimer"; -const QString Constant::INJECT_TIMER_CLEAR = "nativeClearTimer"; -const QString Constant::INJECT_BRIDGE = "nativeBridge"; -const QString Constant::INJECT_EMPTY = "nativeEmpty"; - -const QString Constant::TEMPLATE_CONTEXT_CREATE = QString("Reflect.apply(") + - QString("function(doric,context,Entry,require,exports){") + QString("\n") + - QString("%s1") + QString("\n") + - QString("},doric.jsObtainContext(\"%s2\"),[") + - QString("undefined,") + - QString("doric.jsObtainContext(\"%s3\"),") + - QString("doric.jsObtainEntry(\"%s4\"),") + - QString("doric.__require__") + - QString(",{}") + - QString("])"); -const QString Constant::TEMPLATE_MODULE = QString("Reflect.apply(doric.jsRegisterModule,this,[") + - QString("\"%s1\",") + - QString("Reflect.apply(function(__module){") + - QString("(function(module,exports,require){") + QString("\n") + - QString("%s2") + QString("\n") + - QString("})(__module,__module.exports,doric.__require__);") + - QString("\nreturn __module.exports;") + - QString("},this,[{exports:{}}])") + - QString("])"); -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-Qt/doric/context.cpp b/doric-Qt/doric/context.cpp index c12b3788..94468793 100644 --- a/doric-Qt/doric/context.cpp +++ b/doric-Qt/doric/context.cpp @@ -1,39 +1,19 @@ -#include -#include - -#include "constant.h" #include "context.h" -#include "driver/native_driver.h" +#include "native_driver.h" -Context::Context(int contextId, QString *source) { - this->driver = NativeDriver::getInstance(); - - this->contextId = contextId; +Context::Context(QString contextId, QString source, QString extra) +{ + this->mContextId = contextId; this->source = source; + this->extra = extra; } -void Context::show() { - QString *method = new QString(Constant::DORIC_ENTITY_SHOW); - QVector *arguments = new QVector(); - - driver->invokeContextEntityMethod(contextId, method, nullptr); - - delete arguments; - delete method; -} - -void Context::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; +InterfaceDriver* Context::getDriver() +{ + if (driver == NULL) + { + driver = NativeDriver::getInstance(); + return driver; + } + return driver; } diff --git a/doric-Qt/doric/context.h b/doric-Qt/doric/context.h index 727b248a..03fd73ce 100644 --- a/doric-Qt/doric/context.h +++ b/doric-Qt/doric/context.h @@ -3,23 +3,26 @@ #include -#include "driver/driver.h" +#include "interface_driver.h" class Context { - private: - int contextId; - QString *source; + QString mContextId; + QString source; + QString script; + QString extra; + InterfaceDriver *driver; public: - Driver *driver; + Context(QString contextId, QString source, QString extra); - Context(int contextId, QString *source); + static Context* create(QString script, QString source, QString extra) + { + return NULL; + } - void show(); - - void init(double width, double height); + InterfaceDriver* getDriver(); }; #endif // CONTEXT_H diff --git a/doric-Qt/doric/context_holder.h b/doric-Qt/doric/context_holder.h deleted file mode 100644 index 6db27da1..00000000 --- a/doric-Qt/doric/context_holder.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CONTEXT_HOLDER_H -#define CONTEXT_HOLDER_H - -#include "context.h" - -class ContextHolder : public QObject { - Q_OBJECT -public: - Context *_context; - -public: - ContextHolder(Context *context, QObject *parent = nullptr) : QObject(parent) { - this->_context = context; - } -}; - -#endif // CONTEXT_HOLDER_H diff --git a/doric-Qt/doric/context_manager.h b/doric-Qt/doric/context_manager.h index 47a3f943..6df2cd56 100644 --- a/doric-Qt/doric/context_manager.h +++ b/doric-Qt/doric/context_manager.h @@ -1,45 +1,41 @@ -#ifndef CONTEXT_MANAGER_H -#define CONTEXT_MANAGER_H +#ifndef CONTEXTMANAGER_H +#define CONTEXTMANAGER_H -#include #include -#include #include "context.h" class ContextManager { private: - static ContextManager *local_instance; - ContextManager() { - qDebug() << "ContextManager constructor"; + ContextManager() + { + qDebug() << "ContextManager create"; } - ~ContextManager() { - qDebug() << "ContextManager destructor"; + ~ContextManager() + { + qDebug() << "ContextManager destroy"; } QAtomicInt *counter = new QAtomicInt(); - QMap *contextMap = new QMap(); + QMap *contextMap = new QMap(); public: - static ContextManager *getInstance() { - static ContextManager locla_s; - return &locla_s; + static ContextManager *getInstance() + { + static ContextManager instance; + return &instance; } - Context *createContext(QString *script, QString *source) { + Context *createContext(QString script, QString source, QString extra) { int contextId = counter->fetchAndAddOrdered(1); - Context *context = new Context(contextId, source); - contextMap->insert(contextId, context); + Context *context = new Context(QString::number(contextId), source, extra); + contextMap->insert(QString::number(contextId), context); context->driver->createContext(contextId, script); return context; } - - Context *getContext(int contextId) { - return contextMap->take(contextId); - } }; -#endif // CONTEXT_MANAGER_H +#endif // CONTEXTMANAGER_H diff --git a/doric-Qt/doric/doric.pro b/doric-Qt/doric/doric.pro index 1d33eaf7..acb21499 100644 --- a/doric-Qt/doric/doric.pro +++ b/doric-Qt/doric/doric.pro @@ -1,6 +1,4 @@ -QT += \ - quick \ - widgets +QT += quick CONFIG += c++11 @@ -16,17 +14,18 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ - constant.cpp \ + async/async_result.cpp \ + async/settable_future.cpp \ context.cpp \ - driver/native_driver.cpp \ + engine/bridge_extension.cpp \ engine/js_engine.cpp \ + engine/native_empty.cpp \ + engine/native_jse.cpp \ + engine/native_log.cpp \ + engine/timer_extension.cpp \ main.cpp \ - native/native_bridge.cpp \ - native/native_empty.cpp \ - native/native_log.cpp \ - native/native_timer.cpp \ - plugin/shader_plugin.cpp \ - registry.cpp + native_driver.cpp \ + utils/constant.cpp RESOURCES += qml.qrc @@ -42,22 +41,22 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ + async/async_call.h \ async/async_result.h \ async/callback.h \ - constant.h \ + async/settable_future.h \ context.h \ - context_holder.h \ context_manager.h \ - driver/driver.h \ - driver/native_driver.h \ + engine/bridge_extension.h \ + engine/interface_jse.h \ engine/js_engine.h \ - native/native_bridge.h \ - native/native_empty.h \ - native/native_log.h \ - native/native_timer.h \ - plugin/shader_plugin.h \ - registry.h \ - shader/layer.h \ - template/custom_callback.h \ + engine/native_empty.h \ + engine/native_jse.h \ + engine/native_log.h \ + engine/timer_extension.h \ + interface_driver.h \ + native_driver.h \ template/singleton.h \ - utility/utility.h + utils/constant.h \ + utils/count_down_latch.h \ + utils/utils.h diff --git a/doric-Qt/doric/doric.pro.user b/doric-Qt/doric/doric.pro.user new file mode 100644 index 00000000..03539434 --- /dev/null +++ b/doric-Qt/doric/doric.pro.user @@ -0,0 +1,320 @@ + + + + + + EnvironmentId + {824ffc72-3002-4c5f-b578-b99df65133bd} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + C:/Users/admin/Documents/build-doric-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + C:/Users/admin/Documents/build-doric-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + C:/Users/admin/Documents/build-doric-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + doric2 + Qt4ProjectManager.Qt4RunConfiguration:C:/Users/admin/Workspace/Doric/doric-Qt/doric/doric.pro + C:/Users/admin/Workspace/Doric/doric-Qt/doric/doric.pro + + false + + false + true + true + false + false + true + + C:/Users/admin/Documents/build-doric-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/doric-Qt/doric/driver/driver.h b/doric-Qt/doric/driver/driver.h deleted file mode 100644 index 0bcac900..00000000 --- a/doric-Qt/doric/driver/driver.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef DRIVER_H -#define DRIVER_H - -#include - -#include "registry.h" - -class Driver { - -public: - virtual void createContext(int contextId, QString *script) = 0; - virtual void destroyContext(int contextId) = 0; - - virtual void invokeContextEntityMethod(int contextId, QString *method, ...) = 0; - virtual void invokeDoricMethod(QString *method, ...) = 0; - - virtual Registry *getRegistry() = 0; - - virtual ~Driver() = default; -}; - -#define DriverInterface "pub.doric.DriverInterface" - -Q_DECLARE_INTERFACE(Driver, DriverInterface) - -#endif // DRIVER_H diff --git a/doric-Qt/doric/driver/native_driver.cpp b/doric-Qt/doric/driver/native_driver.cpp deleted file mode 100644 index 9eb55d4c..00000000 --- a/doric-Qt/doric/driver/native_driver.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#include "stdarg.h" - -#include "native_driver.h" -#include "utility/utility.h" - -NativeDriver::NativeDriver() { - qDebug() << "NativeDriver constructor"; -} - -NativeDriver::~NativeDriver() { - qDebug() << "NativeDriver destructor"; -} - -void NativeDriver::createContext(int contextId, QString *script) { - jsEngine->prepareContext(contextId, script); -} - -void NativeDriver::destroyContext(int contextId) { - jsEngine->destroyContext(contextId); -} - -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() << "invokeContextEntityMethod: " + result.toString(); - delete arguments; -} - -void NativeDriver::invokeDoricMethod(QString *method, ...) { - -} - -Registry* NativeDriver::getRegistry() { - return jsEngine->registry; -} diff --git a/doric-Qt/doric/driver/native_driver.h b/doric-Qt/doric/driver/native_driver.h deleted file mode 100644 index 2d2d6590..00000000 --- a/doric-Qt/doric/driver/native_driver.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef NATIVE_DRIVER_H -#define NATIVE_DRIVER_H - -#include "driver.h" -#include "engine/js_engine.h" - -class NativeDriver : public Driver { - Q_INTERFACES(Driver) - -private: - static NativeDriver *local_instance; - NativeDriver(); - - ~NativeDriver() override; - - JSEngine *jsEngine = new JSEngine(); - -public: - static NativeDriver *getInstance() { - static NativeDriver locla_s; - return &locla_s; - } - - void createContext(int contextId, QString *script) override; - void destroyContext(int contextId) override; - - void invokeContextEntityMethod(int contextId, QString *method, ...) override; - void invokeDoricMethod(QString *method, ...) override; - - Registry * getRegistry() override; -}; - -#endif // NATIVE_DRIVER_H diff --git a/doric-Qt/doric/engine/bridge_extension.cpp b/doric-Qt/doric/engine/bridge_extension.cpp new file mode 100644 index 00000000..da334428 --- /dev/null +++ b/doric-Qt/doric/engine/bridge_extension.cpp @@ -0,0 +1,16 @@ +#include +#include "bridge_extension.h" + +BridgeExtension::BridgeExtension(QObject *parent) : QObject(parent) +{ + +} + +void BridgeExtension::callNative(QString contextId, QString module, QString methodName, QString callbackId, QJSValue jsValue) +{ + qDebug() << "contextId: " + contextId; + qDebug() << "module: " + module; + qDebug() << "methodName: " + methodName; + qDebug() << "callbackId: " + callbackId; + qDebug() << "jsValue: " + jsValue.toString(); +} diff --git a/doric-Qt/doric/engine/bridge_extension.h b/doric-Qt/doric/engine/bridge_extension.h new file mode 100644 index 00000000..f131bad4 --- /dev/null +++ b/doric-Qt/doric/engine/bridge_extension.h @@ -0,0 +1,16 @@ +#ifndef BRIDGEEXTENSION_H +#define BRIDGEEXTENSION_H + +#include +#include + +class BridgeExtension : public QObject +{ + Q_OBJECT +public: + explicit BridgeExtension(QObject *parent = nullptr); + + void callNative(QString contextId, QString module, QString methodName, QString callbackId, QJSValue jsValue); +}; + +#endif // BRIDGEEXTENSION_H diff --git a/doric-Qt/doric/engine/interface_jse.h b/doric-Qt/doric/engine/interface_jse.h new file mode 100644 index 00000000..d45bc67a --- /dev/null +++ b/doric-Qt/doric/engine/interface_jse.h @@ -0,0 +1,19 @@ +#ifndef INTERFACE_JSE_H +#define INTERFACE_JSE_H + +#include +#include +#include + +class InterfaceJSE { +public: + virtual QString loadJS(QString script, QString source) = 0; + + virtual void injectGlobalJSObject(QString name, QObject *object) = 0; + + virtual void injectGlobalJSFunction(QString name, QObject *function, QString property) = 0; + + virtual QJSValue invokeObject(QString objectName, QString functionName, QJSValueList 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 1f8fd4f7..6a612b96 100644 --- a/doric-Qt/doric/engine/js_engine.cpp +++ b/doric-Qt/doric/engine/js_engine.cpp @@ -1,81 +1,107 @@ -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include "constant.h" #include "js_engine.h" +#include "native_jse.h" +#include "../utils/constant.h" +#include "native_log.h" +#include "native_empty.h" +#include "timer_extension.h" +#include "bridge_extension.h" +#include "../utils/utils.h" -JSEngine::JSEngine() { - initJSEngine(); - injectGlobal(); - initDoricRuntime(); +JSEngine::JSEngine(QObject *parent) : QObject(parent) +{ + mJSThreadPool.setMaxThreadCount(1); + + QtConcurrent::run(&mJSThreadPool, [this]{ + mJSE = new NativeJSE(); + }); + QtConcurrent::run(&mJSThreadPool, [this]{ + // inject env + QScreen *screen = QGuiApplication::primaryScreen(); + QRect screenGeometry = screen->geometry(); + int screenWidth = screenGeometry.width(); + int screenHeight = screenGeometry.height(); + + QObject *envObject = new QObject(); + envObject->setProperty("platform", "Qt"); + envObject->setProperty("platformVersion", qVersion()); + envObject->setProperty("appName", "appName"); + envObject->setProperty("appVersion", "appVersion"); + envObject->setProperty("screenWidth", screenWidth); + envObject->setProperty("screenHeight", screenHeight); + envObject->setProperty("screenScale", 1); + envObject->setProperty("statusBarHeight", 0); + envObject->setProperty("hasNotch", false); + envObject->setProperty("deviceBrand", QSysInfo::prettyProductName()); + envObject->setProperty("deviceModel", QSysInfo::productType()); + + mJSE->injectGlobalJSObject(Constant::INJECT_ENVIRONMENT, envObject); + + // inject log + NativeLog *nativeLog = new NativeLog(); + mJSE->injectGlobalJSFunction(Constant::INJECT_LOG, nativeLog, "function"); + + // inject empty + NativeEmpty *nativeEmpty = new NativeEmpty(); + mJSE->injectGlobalJSFunction(Constant::INJECT_EMPTY, nativeEmpty, "function"); + + // inject timer set & clear + std::function func = [](){}; + TimerExtension *timerExtension = new TimerExtension([this](long timerId){ + QJSValueList arguments; + arguments.append(QJSValue((int)timerId)); + this->invokeDoricMethod(Constant::DORIC_TIMER_CALLBACK, arguments); + }); + mJSE->injectGlobalJSFunction(Constant::INJECT_TIMER_SET, timerExtension, "setTimer"); + mJSE->injectGlobalJSFunction(Constant::INJECT_TIMER_CLEAR, timerExtension, "clearTimer"); + + BridgeExtension *bridgeExtension = new BridgeExtension(); + mJSE->injectGlobalJSFunction(Constant::INJECT_BRIDGE, bridgeExtension, "callNative"); + }); + QtConcurrent::run(&mJSThreadPool, [this]{ + loadBuiltinJS(Constant::DORIC_BUNDLE_SANDBOX); + + QString libName = Constant::DORIC_MODULE_LIB; + QString libJS = Utils::readAssetFile("/doric", Constant::DORIC_BUNDLE_LIB); + QString script = packageModuleScript(libName, libJS); + + mJSE->loadJS(script, "Module://" + libName); + }); } -void JSEngine::prepareContext(int contextId, QString *script) { - QString contextIdString = QString::number(contextId); - QString source = QString(Constant::TEMPLATE_CONTEXT_CREATE) - .replace("%s1", *script) - .replace("%s2", contextIdString) - .replace("%s3", contextIdString) - .replace("%s4", contextIdString); - QJSValue result = engine->evaluate(source, "context://" + contextIdString); - qDebug() << "context://" + contextIdString + " result: " + result.toString(); +QJSValue JSEngine::invokeDoricMethod(QString method, QJSValueList arguments) +{ + return mJSE->invokeObject(Constant::GLOBAL_DORIC, method, arguments); } -void JSEngine::destroyContext(int contextId) { - QString contextIdString = QString::number(contextId); - QString source = QString(Constant::TEMPLATE_CONTEXT_DESTROY) - .replace("%s", contextIdString); - QJSValue result = engine->evaluate(source, "_context://" + contextIdString); - qDebug() << "context://" + contextIdString + " result: " + result.toString(); +void JSEngine::loadBuiltinJS(QString assetName) +{ + QString script = Utils::readAssetFile("/doric", assetName); + QString result = mJSE->loadJS(script, "Assets://" + assetName); } -void JSEngine::initJSEngine() { - engine->installExtensions(QJSEngine::AllExtensions); +void JSEngine::prepareContext(QString contextId, QString script, QString source) +{ + mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source); } -void JSEngine::injectGlobal() { - QJSValue log = engine->newQObject(nativeLog); - engine->globalObject().setProperty(Constant::INJECT_LOG, log.property("function")); - - QJSValue timer = engine->newQObject(nativeTimer); - engine->globalObject().setProperty(Constant::INJECT_TIMER_SET, timer.property("setTimer")); - engine->globalObject().setProperty(Constant::INJECT_TIMER_CLEAR, timer.property("clearTimer")); - - QJSValue empty = engine->newQObject(nativeEmpty); - engine->globalObject().setProperty(Constant::INJECT_EMPTY, empty.property("function")); - - QJSValue bridge = engine->newQObject(nativeBridge); - engine->globalObject().setProperty(Constant::INJECT_BRIDGE, bridge.property("function")); +QString JSEngine::packageContextScript(QString contextId, QString content) +{ + return QString(Constant::TEMPLATE_CONTEXT_CREATE).replace("%s1", content).replace("%s2", contextId).replace("%s3", contextId); } -void JSEngine::initDoricRuntime() { - { - QResource resource(":/doric/doric-sandbox.js"); - QFile *file = new QFile(resource.fileName()); - file->open(QFile::ReadOnly | QFile::Text); - QTextStream in(file); - QString script = in.readAll(); - file->close(); - delete file; - - QJSValue result = engine->evaluate(script, "doric-sandbox.js"); - qDebug() << "doric-sandbox.js result: " + result.toString(); - } - - { - QResource resource(":/doric/doric-lib.js"); - QFile *file = new QFile(resource.fileName()); - file->open(QFile::ReadOnly | QFile::Text); - QTextStream in(file); - QString script = in.readAll(); - file->close(); - delete file; - - QString lib = QString(Constant::TEMPLATE_MODULE) - .replace("%s1", "doric") - .replace("%s2", script); - QJSValue result = engine->evaluate(lib, "doric-lib.js"); - qDebug() << "doric-lib.js result: " + result.toString(); - } +QString JSEngine::packageModuleScript(QString moduleName, QString content) +{ + return QString(Constant::TEMPLATE_MODULE).replace("%s1", moduleName).replace("%s2", content); +} + +JSEngine::~JSEngine() +{ + } diff --git a/doric-Qt/doric/engine/js_engine.h b/doric-Qt/doric/engine/js_engine.h index 70bd2328..eb12bdf7 100644 --- a/doric-Qt/doric/engine/js_engine.h +++ b/doric-Qt/doric/engine/js_engine.h @@ -1,38 +1,28 @@ -#ifndef JS_ENGINE_H -#define JS_ENGINE_H +#ifndef JSENGINE_H +#define JSENGINE_H -#include +#include +#include -#include "native/native_bridge.h" -#include "native/native_empty.h" -#include "native/native_log.h" -#include "native/native_timer.h" -#include "registry.h" - -class JSEngine { - -public: - QJSEngine *engine = new QJSEngine(); - - Registry *registry = new Registry(); - - JSEngine(); - - void prepareContext(int contextId, QString *script); - - void destroyContext(int contextId); +#include "interface_jse.h" +class JSEngine : public QObject +{ + Q_OBJECT private: - NativeLog *nativeLog = new NativeLog(); - NativeTimer *nativeTimer = new NativeTimer(engine); - NativeEmpty *nativeEmpty = new NativeEmpty(); - NativeBridge *nativeBridge = new NativeBridge(); + QThreadPool mJSThreadPool; + InterfaceJSE *mJSE; - void initJSEngine(); + void loadBuiltinJS(QString assetName); + void prepareContext(QString contextId, QString script, QString source); + QString packageContextScript(QString contextId, QString content); + QString packageModuleScript(QString moduleName, QString content); +public: + explicit JSEngine(QObject *parent = nullptr); - void injectGlobal(); + QJSValue invokeDoricMethod(QString method, QJSValueList arguments); - void initDoricRuntime(); + ~JSEngine(); }; -#endif // JS_ENGINE_H +#endif // JSENGINE_H diff --git a/doric-Qt/doric/engine/native_empty.cpp b/doric-Qt/doric/engine/native_empty.cpp new file mode 100644 index 00000000..06c2d8d2 --- /dev/null +++ b/doric-Qt/doric/engine/native_empty.cpp @@ -0,0 +1,7 @@ +#include "native_empty.h" +#include + +Q_INVOKABLE QJSValue NativeEmpty::function() { + qDebug() << "nativeEmpty"; + return QJSValue::NullValue; +} diff --git a/doric-Qt/doric/native/native_empty.h b/doric-Qt/doric/engine/native_empty.h similarity index 54% rename from doric-Qt/doric/native/native_empty.h rename to doric-Qt/doric/engine/native_empty.h index 64135411..db0bc24d 100644 --- a/doric-Qt/doric/native/native_empty.h +++ b/doric-Qt/doric/engine/native_empty.h @@ -1,7 +1,8 @@ -#ifndef NATIVE_EMPTY_H -#define NATIVE_EMPTY_H +#ifndef NATIVEEMPTY_H +#define NATIVEEMPTY_H #include +#include class NativeEmpty : public QObject { Q_OBJECT @@ -9,7 +10,7 @@ class NativeEmpty : public QObject { public: NativeEmpty(QObject *parent = nullptr) : QObject(parent) {} - Q_INVOKABLE void function(); + Q_INVOKABLE QJSValue function(); }; -#endif // NATIVE_EMPTY_H +#endif // NATIVEEMPTY_H diff --git a/doric-Qt/doric/engine/native_jse.cpp b/doric-Qt/doric/engine/native_jse.cpp new file mode 100644 index 00000000..22cb6314 --- /dev/null +++ b/doric-Qt/doric/engine/native_jse.cpp @@ -0,0 +1,43 @@ +#include "native_jse.h" +#include + +NativeJSE::NativeJSE() +{ + mJSEngine.installExtensions(QJSEngine::AllExtensions); +} + +QString NativeJSE::loadJS(QString script, QString source) +{ + return mJSEngine.evaluate(script, source).toString(); +} + +void NativeJSE::injectGlobalJSObject(QString name, QObject *object) +{ + QJSValue jsObject = mJSEngine.newQObject(object); + + QList propertyNames = object->dynamicPropertyNames(); + foreach(QByteArray propertyName, propertyNames) + { + QString key = QString::fromStdString(propertyName.toStdString()); + if (key == "undefined") { + + } else { + jsObject.setProperty(key, mJSEngine.toScriptValue(object->property(propertyName))); + } + } + + mJSEngine.globalObject().setProperty(name, jsObject); +} + +void NativeJSE::injectGlobalJSFunction(QString name, QObject *function, QString property) +{ + QJSValue functionObject = mJSEngine.newQObject(function); + mJSEngine.globalObject().setProperty(name, functionObject.property(property)); +} + +QJSValue NativeJSE::invokeObject(QString objectName, QString functionName, QJSValueList arguments) +{ + QJSValue object = mJSEngine.evaluate(objectName); + QJSValue function = object.property(functionName); + return function.call(arguments); +} diff --git a/doric-Qt/doric/engine/native_jse.h b/doric-Qt/doric/engine/native_jse.h new file mode 100644 index 00000000..21792afd --- /dev/null +++ b/doric-Qt/doric/engine/native_jse.h @@ -0,0 +1,23 @@ +#ifndef NATIVE_JSE_H +#define NATIVE_JSE_H + +#include +#include "interface_jse.h" + +class NativeJSE : public InterfaceJSE +{ +private: + QJSEngine mJSEngine; +public: + NativeJSE(); + + QString loadJS(QString script, QString source) override; + + void injectGlobalJSObject(QString name, QObject *object) override; + + void injectGlobalJSFunction(QString name, QObject *function, QString property) override; + + QJSValue invokeObject(QString objectName, QString functionName, QJSValueList arguments) override; +}; + +#endif // NATIVE_JSE_H diff --git a/doric-Qt/doric/native/native_log.cpp b/doric-Qt/doric/engine/native_log.cpp similarity index 100% rename from doric-Qt/doric/native/native_log.cpp rename to doric-Qt/doric/engine/native_log.cpp diff --git a/doric-Qt/doric/native/native_log.h b/doric-Qt/doric/engine/native_log.h similarity index 76% rename from doric-Qt/doric/native/native_log.h rename to doric-Qt/doric/engine/native_log.h index 1649496b..56d9ae7f 100644 --- a/doric-Qt/doric/native/native_log.h +++ b/doric-Qt/doric/engine/native_log.h @@ -1,5 +1,5 @@ -#ifndef NATIVELOG_H -#define NATIVELOG_H +#ifndef NATIVE_LOG_H +#define NATIVE_LOG_H #include @@ -12,4 +12,4 @@ public: Q_INVOKABLE void function(QString level, QString content); }; -#endif // NATIVELOG_H +#endif // NATIVE_LOG_H diff --git a/doric-Qt/doric/native/native_timer.cpp b/doric-Qt/doric/engine/timer_extension.cpp similarity index 56% rename from doric-Qt/doric/native/native_timer.cpp rename to doric-Qt/doric/engine/timer_extension.cpp index 33eb8040..eade7260 100644 --- a/doric-Qt/doric/native/native_timer.cpp +++ b/doric-Qt/doric/engine/timer_extension.cpp @@ -1,8 +1,9 @@ #include -#include "native_timer.h" +#include "timer_extension.h" +#include "../utils/constant.h" -Q_INVOKABLE void NativeTimer::setTimer(long timerId, int time, bool repeat) { +Q_INVOKABLE void TimerExtension::setTimer(long timerId, int time, bool repeat) { QTimer *timer = new QTimer(this); timer->setSingleShot(!repeat); connect(timer, &QTimer::timeout, this, [=] () { @@ -10,11 +11,7 @@ Q_INVOKABLE void NativeTimer::setTimer(long timerId, int time, bool repeat) { deletedTimerIds->remove(timerId); delete timer; } else { - engine->evaluate( - Constant::GLOBAL_DORIC + "." + - Constant::DORIC_TIMER_CALLBACK + "(" + - QString::number(timerId) + ")" - ); + this->method(timerId); if (!repeat) { deletedTimerIds->remove(timerId); @@ -25,6 +22,6 @@ Q_INVOKABLE void NativeTimer::setTimer(long timerId, int time, bool repeat) { timer->start(time); } -void NativeTimer::clearTimer(long timerId) { +Q_INVOKABLE void TimerExtension::clearTimer(long timerId) { deletedTimerIds->insert(timerId); } diff --git a/doric-Qt/doric/engine/timer_extension.h b/doric-Qt/doric/engine/timer_extension.h new file mode 100644 index 00000000..0125c9dd --- /dev/null +++ b/doric-Qt/doric/engine/timer_extension.h @@ -0,0 +1,24 @@ +#ifndef NATIVETIMER_H +#define NATIVETIMER_H + +#include +#include + +class TimerExtension : public QObject { + Q_OBJECT + +private: + QSet *deletedTimerIds = new QSet(); + std::function method; + +public: + explicit TimerExtension(std::function method, QObject *parent = nullptr) : QObject(parent) { + this->method = method; + } + + Q_INVOKABLE void setTimer(long timerId, int time, bool repeat); + + Q_INVOKABLE void clearTimer(long timerId); + +}; +#endif // NATIVETIMER_H diff --git a/doric-Qt/doric/interface_driver.h b/doric-Qt/doric/interface_driver.h new file mode 100644 index 00000000..82d2a196 --- /dev/null +++ b/doric-Qt/doric/interface_driver.h @@ -0,0 +1,19 @@ +#ifndef INTERFACEDRIVER_H +#define INTERFACEDRIVER_H + +#include +#include + +class InterfaceDriver +{ +public: + virtual void invokeContextEntityMethod(QString contextId, QString method, QList args) = 0; + + virtual void invokeDoricMethod(QString method, QList args) = 0; + + virtual void createContext(QString contextId, QString script, QString source) = 0; + + virtual void destroyContext(QString contextId) = 0; +}; + +#endif // INTERFACEDRIVER_H diff --git a/doric-Qt/doric/main.cpp b/doric-Qt/doric/main.cpp index e633bd07..978b8e9b 100644 --- a/doric-Qt/doric/main.cpp +++ b/doric-Qt/doric/main.cpp @@ -1,46 +1,26 @@ -#include -#include -#include -#include +#include +#include +#include -#include "context_manager.h" +#include "engine/js_engine.h" #include "async/async_result.h" -#include "template/custom_callback.h" int main(int argc, char *argv[]) { - QApplication app(argc, argv); - { - QWidget *widget = new QWidget(nullptr, Qt::WindowType::Window); - widget->setWindowTitle(QString("Hello Doric")); - widget->resize(360, 640); - widget->show(); - } - { - QResource resource(":/doric/Snake.js"); - QFile *file = new QFile(resource.fileName()); - file->open(QFile::ReadOnly | QFile::Text); - QTextStream in(file); - QString script = in.readAll(); - file->close(); - delete file; + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QString *source = new QString("Snake.js"); - Context *context = ContextManager::getInstance()->createContext(&script, source); - context->show(); - context->init(180, 320); - delete source; - } + QGuiApplication app(argc, argv); - { - // code for test - QJsonValue *a = new QJsonValue(); - AsyncResult *result = new AsyncResult(*a); - CustomCallback *callback = new CustomCallback(); - result->setCallback(callback); - qDebug() << result->hasResult(); - qDebug() << result->getResult(); - } + QQmlApplicationEngine engine; + const QUrl url(QStringLiteral("qrc:/main.qml")); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, + &app, [url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, Qt::QueuedConnection); + engine.load(url); + + JSEngine jsEngine; return app.exec(); } diff --git a/doric-Qt/doric/main.qml b/doric-Qt/doric/main.qml new file mode 100644 index 00000000..382f8f5e --- /dev/null +++ b/doric-Qt/doric/main.qml @@ -0,0 +1,23 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.5 + +ApplicationWindow { + visible: true + width: 960 + height: 720 + title: qsTr("Scroll") + + ScrollView { + anchors.fill: parent + + ListView { + width: parent.width + model: 20 + delegate: ItemDelegate { + text: "Item " + (index + 1) + width: parent.width + height: 100 + } + } + } +} diff --git a/doric-Qt/doric/native/native_bridge.cpp b/doric-Qt/doric/native/native_bridge.cpp deleted file mode 100644 index a6f5b954..00000000 --- a/doric-Qt/doric/native/native_bridge.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "context_manager.h" -#include "native_bridge.h" -#include "plugin/shader_plugin.h" - -Q_INVOKABLE void NativeBridge::function(int contextId, QString module, QString methodName, QString callbackId, QJSValue jsValue) { - qDebug() << "contextId: " + QString::number(contextId) + ", " + - "module: " + module + ", " + - "methodName: " + methodName + ", " + - "callbackId: " + callbackId + ", " + - "arguments: " + jsValue.toString(); - Context *context = ContextManager::getInstance()->getContext(contextId); - QString value = context->driver->getRegistry()->acquirePluginInfo(module); - - qDebug() << value; - if (value.contains("ShaderPlugin")) { - ShaderPlugin shaderPlugin(context); - QMetaObject::invokeMethod( - &shaderPlugin, - methodName.toStdString().c_str(), - Qt::AutoConnection, - Q_ARG(QJSValue, jsValue)); - } -} diff --git a/doric-Qt/doric/native/native_bridge.h b/doric-Qt/doric/native/native_bridge.h deleted file mode 100644 index a274e1f7..00000000 --- a/doric-Qt/doric/native/native_bridge.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef NATIVE_BRIDGE_H -#define NATIVE_BRIDGE_H - -#include -#include - -class NativeBridge : public QObject { - Q_OBJECT - -public: - NativeBridge(QObject *parent = nullptr) : QObject(parent) {} - - Q_INVOKABLE void function(int contextId, QString module, QString methodName, QString callbackId, QJSValue jsValue); -}; - -#endif // NATIVE_BRIDGE_H diff --git a/doric-Qt/doric/native/native_empty.cpp b/doric-Qt/doric/native/native_empty.cpp deleted file mode 100644 index 06204bb7..00000000 --- a/doric-Qt/doric/native/native_empty.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -#include "native_empty.h" - -Q_INVOKABLE void NativeEmpty::function() { - qDebug() << "nativeEmpty"; -} diff --git a/doric-Qt/doric/native/native_timer.h b/doric-Qt/doric/native/native_timer.h deleted file mode 100644 index 6cb4eff9..00000000 --- a/doric-Qt/doric/native/native_timer.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef NATIVE_TIMER_H -#define NATIVE_TIMER_H - -#include -#include -#include - -#include "constant.h" - -class NativeTimer : public QObject { - Q_OBJECT - -private: - QSet *deletedTimerIds = new QSet(); - QJSEngine *engine; - -public: - NativeTimer(QJSEngine *engine, QObject *parent = nullptr) : QObject(parent) { - this->engine = engine; - } - - Q_INVOKABLE void setTimer(long timerId, int time, bool repeat); - - Q_INVOKABLE void clearTimer(long timerId); - -}; -#endif // NATIVE_TIMER_H diff --git a/doric-Qt/doric/native_driver.cpp b/doric-Qt/doric/native_driver.cpp new file mode 100644 index 00000000..e6361f04 --- /dev/null +++ b/doric-Qt/doric/native_driver.cpp @@ -0,0 +1,21 @@ +#include "native_driver.h" + +void NativeDriver::invokeContextEntityMethod(QString contextId, QString method, QList args) +{ + +} + +void NativeDriver::invokeDoricMethod(QString method, QList args) +{ + +} + +void NativeDriver::createContext(QString contextId, QString script, QString source) +{ + +} + +void NativeDriver::destroyContext(QString contextId) +{ + +} diff --git a/doric-Qt/doric/native_driver.h b/doric-Qt/doric/native_driver.h new file mode 100644 index 00000000..b8315a68 --- /dev/null +++ b/doric-Qt/doric/native_driver.h @@ -0,0 +1,40 @@ +#ifndef NATIVEDRIVER_H +#define NATIVEDRIVER_H + +#include + +#include "interface_driver.h" +#include "engine/js_engine.h" + +class NativeDriver : public InterfaceDriver +{ +private: + static NativeDriver *local_instance; + NativeDriver() + { + qDebug() << "constructor"; + } + + ~NativeDriver() + { + qDebug() << "destructor"; + } + + JSEngine jsEngine; + +public: + static NativeDriver *getInstance() + { + static NativeDriver instance; + return &instance; + } + + void invokeContextEntityMethod(QString contextId, QString method, QList args) override; + + void invokeDoricMethod(QString method, QList args) override; + + void createContext(QString contextId, QString script, QString source) override; + + void destroyContext(QString contextId) override; +}; +#endif // NATIVEDRIVER_H diff --git a/doric-Qt/doric/plugin/shader_plugin.cpp b/doric-Qt/doric/plugin/shader_plugin.cpp deleted file mode 100644 index 2d813bc1..00000000 --- a/doric-Qt/doric/plugin/shader_plugin.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "shader_plugin.h" - -Q_INVOKABLE void ShaderPlugin::render(QJSValue jsValue) { - QString viewId = jsValue.property("id").toString(); - qDebug() << viewId; -} diff --git a/doric-Qt/doric/plugin/shader_plugin.h b/doric-Qt/doric/plugin/shader_plugin.h deleted file mode 100644 index e6fd76a0..00000000 --- a/doric-Qt/doric/plugin/shader_plugin.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef SHADER_PLUGIN_H -#define SHADER_PLUGIN_H - -#include -#include - -#include "context_holder.h" - -class ShaderPlugin : public ContextHolder { - Q_OBJECT - -public: - ShaderPlugin(Context *context) : ContextHolder(context) {} - - Q_INVOKABLE void render(QJSValue jsValue); -}; - -#endif // SHADER_PLUGIN_H diff --git a/doric-Qt/doric/qml.qrc b/doric-Qt/doric/qml.qrc index 6d00a767..79a873d0 100644 --- a/doric-Qt/doric/qml.qrc +++ b/doric-Qt/doric/qml.qrc @@ -1,4 +1,8 @@ + + main.qml + qtquickcontrols2.conf + ../../doric-js/bundle/doric-sandbox.js ../../doric-js/bundle/doric-lib.js diff --git a/doric-Qt/doric/qtquickcontrols2.conf b/doric-Qt/doric/qtquickcontrols2.conf new file mode 100644 index 00000000..75b2cb8f --- /dev/null +++ b/doric-Qt/doric/qtquickcontrols2.conf @@ -0,0 +1,6 @@ +; This file can be edited to change the style of the application +; Read "Qt Quick Controls 2 Configuration File" for details: +; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html + +[Controls] +Style=Default diff --git a/doric-Qt/doric/registry.cpp b/doric-Qt/doric/registry.cpp deleted file mode 100644 index 12127a95..00000000 --- a/doric-Qt/doric/registry.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include - -#include "registry.h" -#include "plugin/shader_plugin.h" - -Registry::Registry() { - registerNativePlugin("shader", typeid(ShaderPlugin).name()); -} - -void Registry::registerNativePlugin(QString key, QString value) { - qDebug() << key + " " + value; - pluginInfoMap.insert(key, value); -} - -QString Registry::acquirePluginInfo(QString key) { - return pluginInfoMap.take(key); -} diff --git a/doric-Qt/doric/registry.h b/doric-Qt/doric/registry.h deleted file mode 100644 index 76e04878..00000000 --- a/doric-Qt/doric/registry.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef REGISTRY_H -#define REGISTRY_H - -#include - -class Registry { - -private: - QMap pluginInfoMap; - -public: - Registry(); - - void registerNativePlugin(QString key, QString value); - - QString acquirePluginInfo(QString key); -}; - -#endif // REGISTRY_H diff --git a/doric-Qt/doric/shader/layer.h b/doric-Qt/doric/shader/layer.h deleted file mode 100644 index 3bf73497..00000000 --- a/doric-Qt/doric/shader/layer.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef LAYER_H -#define LAYER_H - -#include -#include - -class Layer : public QWidget { - - void paintEvent(QPaintEvent *event) override { - QPainter painter(this); - QWidget::paintEvent(event); - } - -public: - - void setShadow(int sdColor, int sdOpacity, int sdRadius, int offsetX, int offsetY) { - - } - - void setBorder(int borderWidth, int borderColor) { - - } - - void setCornerRadius(int corner) { - - } - - void setCornerRadius(int leftTop, int rightTop, int rightBottom, int leftBottom) { - - } -}; - -#endif // LAYER_H diff --git a/doric-Qt/doric/template/custom_callback.h b/doric-Qt/doric/template/custom_callback.h deleted file mode 100644 index bc3da675..00000000 --- a/doric-Qt/doric/template/custom_callback.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef CUSTOM_CALLBACK_H -#define CUSTOM_CALLBACK_H - -#include - -#include "async/callback.h" - -template -class CustomCallback : public Callback { - -public: - void onResult(R result) override { - qDebug() << result; - } - - void onError(QException exception) override { - qDebug() << exception.what(); - } - - void onFinish() override { - - } -}; - -#endif // CUSTOM_CALLBACK_H diff --git a/doric-Qt/doric/template/singleton.h b/doric-Qt/doric/template/singleton.h index 0bee72fb..c2655879 100644 --- a/doric-Qt/doric/template/singleton.h +++ b/doric-Qt/doric/template/singleton.h @@ -7,16 +7,19 @@ class Singleton { private: static Singleton *local_instance; - Singleton() { + Singleton() + { qDebug() << "constructor"; } - ~Singleton() { + ~Singleton() + { qDebug() << "destructor"; } public: - static Singleton *getInstance() { + static Singleton *getInstance() + { static Singleton locla_s; return &locla_s; } diff --git a/doric-Qt/doric/utility/utility.h b/doric-Qt/doric/utility/utility.h deleted file mode 100644 index b5d051c8..00000000 --- a/doric-Qt/doric/utility/utility.h +++ /dev/null @@ -1,48 +0,0 @@ -#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 diff --git a/doric-Qt/doric/utils/constant.cpp b/doric-Qt/doric/utils/constant.cpp new file mode 100644 index 00000000..65b95ae5 --- /dev/null +++ b/doric-Qt/doric/utils/constant.cpp @@ -0,0 +1,37 @@ +#include "constant.h" + +const QString Constant::DORIC_BUNDLE_SANDBOX = "doric-sandbox.js"; +const QString Constant::DORIC_BUNDLE_LIB = "doric-lib.js"; +const QString Constant::DORIC_MODULE_LIB = "doric"; + +const QString Constant::INJECT_ENVIRONMENT = "Environment"; +const QString Constant::INJECT_LOG = "nativeLog"; +const QString Constant::INJECT_EMPTY = "nativeEmpty"; +const QString Constant::INJECT_REQUIRE = "nativeRequire"; +const QString Constant::INJECT_TIMER_SET = "nativeSetTimer"; +const QString Constant::INJECT_TIMER_CLEAR = "nativeClearTimer"; +const QString Constant::INJECT_BRIDGE = "nativeBridge"; + +const QString Constant::TEMPLATE_CONTEXT_CREATE = QString("Reflect.apply(") + + "function(doric,context,Entry,require,exports){" + "\n" + + "%s1" + "\n" + + "},undefined,[" + + "undefined," + + "doric.jsObtainContext(\"%s2\")," + + "doric.jsObtainEntry(\"%s3\")," + + "doric.__require__" + + ",{}" + + "])"; +const QString Constant::TEMPLATE_MODULE = QString("Reflect.apply(doric.jsRegisterModule,this,[") + + "\"%s1\"," + + "Reflect.apply(function(__module){" + + "(function(module,exports,require){" + "\n" + + "%s2" + "\n" + + "})(__module,__module.exports,doric.__require__);" + + "\nreturn __module.exports;" + + "},this,[{exports:{}}])" + + "])"; +const QString Constant::TEMPLATE_CONTEXT_DESTROY = QString("doric.jsReleaseContext(\"%s\")"); + +const QString Constant::GLOBAL_DORIC = "doric"; +const QString Constant::DORIC_TIMER_CALLBACK = "jsCallbackTimer"; diff --git a/doric-Qt/doric/constant.h b/doric-Qt/doric/utils/constant.h similarity index 76% rename from doric-Qt/doric/constant.h rename to doric-Qt/doric/utils/constant.h index c02a3ba0..bb623eba 100644 --- a/doric-Qt/doric/constant.h +++ b/doric-Qt/doric/utils/constant.h @@ -6,23 +6,25 @@ class Constant { public: + static const QString DORIC_BUNDLE_SANDBOX; + static const QString DORIC_BUNDLE_LIB; + static const QString DORIC_MODULE_LIB; + + static const QString INJECT_ENVIRONMENT; static const QString INJECT_LOG; + static const QString INJECT_EMPTY; static const QString INJECT_REQUIRE; static const QString INJECT_TIMER_SET; static const QString INJECT_TIMER_CLEAR; static const QString INJECT_BRIDGE; - static const QString INJECT_EMPTY; static const QString TEMPLATE_CONTEXT_CREATE; static const QString TEMPLATE_MODULE; 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-Qt/doric/utils/count_down_latch.h b/doric-Qt/doric/utils/count_down_latch.h new file mode 100644 index 00000000..6618ed20 --- /dev/null +++ b/doric-Qt/doric/utils/count_down_latch.h @@ -0,0 +1,27 @@ +#ifndef COUNTDOWNLATCH_H +#define COUNTDOWNLATCH_H + +#include +#include + +class CountDownLatch { + Q_DISABLE_COPY(CountDownLatch) + QSemaphore m_sem{INT_MAX}; +public: + CountDownLatch() {} + ~CountDownLatch() { + m_sem.acquire(INT_MAX); + m_sem.release(INT_MAX); + } + class Locker { + CountDownLatch * sem; + public: + Locker(const Locker & other) : sem{other.sem} { sem->m_sem.acquire(); } + Locker(Locker && other) : sem{other.sem} { other.sem = nullptr; } + Locker(CountDownLatch * sem) : sem{sem} { sem->m_sem.acquire(); } + ~Locker() { if (sem) sem->m_sem.release(); } + }; + Locker lock() { return Locker{this}; } +}; + +#endif // COUNTDOWNLATCH_H diff --git a/doric-Qt/doric/utils/utils.h b/doric-Qt/doric/utils/utils.h new file mode 100644 index 00000000..56add525 --- /dev/null +++ b/doric-Qt/doric/utils/utils.h @@ -0,0 +1,25 @@ +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include + +class Utils +{ +public: + static QString readAssetFile(QString preffix, QString assetName) { + QResource resource(":" + preffix + "/" + assetName); + QFile *file = new QFile(resource.fileName()); + file->open(QFile::ReadOnly | QFile::Text); + QTextStream in(file); + QString content = in.readAll(); + file->close(); + delete file; + + return content; + } +}; + +#endif // UTILS_H