code format & class prefix

This commit is contained in:
王劲鹏 2021-02-04 16:59:58 +08:00 committed by osborn
parent 99afe83b19
commit be37a71699
90 changed files with 1196 additions and 1274 deletions

View File

@ -0,0 +1,69 @@
#include "DoricContext.h"
#include "DoricContextManager.h"
#include "DoricNativeDriver.h"
#include "utils/DoricConstant.h"
DoricContext::DoricContext(QString contextId, QString source, QString extra) {
this->mRootNode = new DoricRootNode();
this->mContextId = contextId;
this->source = source;
this->extra = extra;
}
DoricContext *DoricContext::create(QString script, QString source,
QString extra) {
DoricContext *context =
DoricContextManager::getInstance()->createContext(script, source, extra);
context->script = script;
context->init(extra);
QVariantList args;
context->callEntity(DoricConstant::DORIC_ENTITY_CREATE, args);
return context;
}
void DoricContext::init(QString initData) {
this->extra = initData;
if (!initData.isEmpty()) {
QVariantList args;
args.push_back(initData);
callEntity(DoricConstant::DORIC_ENTITY_INIT, args);
}
}
void DoricContext::build(int width, int height) {
QMap<QString, QVariant> 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(DoricConstant::DORIC_ENTITY_BUILD, args);
}
void DoricContext::callEntity(QString methodName, QVariantList args) {
return getDriver()->invokeContextEntityMethod(this->mContextId, methodName,
args);
}
DoricInterfaceDriver *DoricContext::getDriver() {
if (driver == NULL) {
driver = DoricNativeDriver::getInstance();
return driver;
}
return driver;
}
QObject *DoricContext::obtainPlugin(QString name) {
if (mPluginMap.keys().contains(name)) {
return mPluginMap.value(name);
} else {
QObject *plugin =
getDriver()->getRegistry()->pluginInfoMap.createObject(name);
mPluginMap.insert(name, plugin);
return plugin;
}
}

View File

@ -0,0 +1,36 @@
#ifndef CONTEXT_H
#define CONTEXT_H
#include <QVariant>
#include "DoricInterfaceDriver.h"
#include "shader/DoricRootNode.h"
class DoricContext {
private:
QString mContextId;
QMap<QString, QObject *> mPluginMap;
DoricRootNode *mRootNode;
QString source;
QString script;
QString extra;
QVariant initParams;
DoricInterfaceDriver *driver = NULL;
public:
DoricContext(QString contextId, QString source, QString extra);
static DoricContext *create(QString script, QString source, QString extra);
void init(QString initData);
void build(int width, int height);
void callEntity(QString methodName, QVariantList args);
DoricInterfaceDriver *getDriver();
QObject *obtainPlugin(QString name);
};
#endif // CONTEXT_H

View File

@ -0,0 +1,16 @@
#include "DoricContextManager.h"
DoricContext *DoricContextManager::createContext(QString script, QString source,
QString extra) {
int contextId = counter->fetchAndAddOrdered(1);
DoricContext *context =
new DoricContext(QString::number(contextId), source, extra);
contextMap->insert(QString::number(contextId), context);
context->getDriver()->createContext(QString::number(contextId), script,
source);
return context;
}
DoricContext *DoricContextManager::getContext(QString contextId) {
return contextMap->take(contextId);
}

View File

@ -0,0 +1,30 @@
#ifndef CONTEXTMANAGER_H
#define CONTEXTMANAGER_H
#include <QDebug>
#include "DoricContext.h"
class DoricContextManager {
private:
static DoricContextManager *local_instance;
DoricContextManager() {}
~DoricContextManager() {}
QAtomicInt *counter = new QAtomicInt();
QMap<QString, DoricContext *> *contextMap =
new QMap<QString, DoricContext *>();
public:
static DoricContextManager *getInstance() {
static DoricContextManager instance;
return &instance;
}
DoricContext *createContext(QString script, QString source, QString extra);
DoricContext *getContext(QString contextId);
};
#endif // CONTEXTMANAGER_H

View File

@ -0,0 +1,24 @@
#ifndef INTERFACEDRIVER_H
#define INTERFACEDRIVER_H
#include <QString>
#include <QVariant>
#include "DoricRegistry.h"
class DoricInterfaceDriver {
public:
virtual void invokeContextEntityMethod(QString contextId, QString method,
QVariantList args) = 0;
virtual void invokeDoricMethod(QString method, QVariantList args) = 0;
virtual void createContext(QString contextId, QString script,
QString source) = 0;
virtual void destroyContext(QString contextId) = 0;
virtual DoricRegistry *getRegistry() = 0;
};
#endif // INTERFACEDRIVER_H

View File

@ -0,0 +1,34 @@
#include <functional>
#include "DoricNativeDriver.h"
#include "async/DoricAsyncCall.h"
#include "utils/DoricConstant.h"
void DoricNativeDriver::invokeContextEntityMethod(QString contextId,
QString method,
QVariantList args) {
args.insert(0, QVariant(contextId));
args.insert(1, QVariant(method));
invokeDoricMethod(DoricConstant::DORIC_CONTEXT_INVOKE, args);
}
void DoricNativeDriver::invokeDoricMethod(QString method, QVariantList args) {
return DoricAsyncCall::ensureRunInThreadPool(
&jsEngine.mJSThreadPool, [this, method, args] {
this->jsEngine.invokeDoricMethod(method, args).toString();
});
}
void DoricNativeDriver::createContext(QString contextId, QString script,
QString source) {
DoricAsyncCall::ensureRunInThreadPool(
&jsEngine.mJSThreadPool, [this, contextId, script, source] {
this->jsEngine.prepareContext(contextId, script, source);
});
}
void DoricNativeDriver::destroyContext(QString contextId) {}
DoricRegistry *DoricNativeDriver::getRegistry() {
return this->jsEngine.getRegistry();
}

View File

@ -0,0 +1,36 @@
#ifndef NATIVEDRIVER_H
#define NATIVEDRIVER_H
#include <QDebug>
#include "DoricInterfaceDriver.h"
#include "engine/DoricJSEngine.h"
class DoricNativeDriver : public DoricInterfaceDriver {
private:
static DoricNativeDriver *local_instance;
DoricNativeDriver() {}
~DoricNativeDriver() {}
DoricJSEngine jsEngine;
public:
static DoricNativeDriver *getInstance() {
static DoricNativeDriver instance;
return &instance;
}
void invokeContextEntityMethod(QString contextId, QString method,
QVariantList args) override;
void invokeDoricMethod(QString method, QVariantList args) override;
void createContext(QString contextId, QString script,
QString source) override;
void destroyContext(QString contextId) override;
DoricRegistry *getRegistry() override;
};
#endif // NATIVEDRIVER_H

View File

@ -0,0 +1,13 @@
#include "DoricPanel.h"
DoricPanel::DoricPanel() {}
void DoricPanel::config(QString script, QString alias, QString extra) {
DoricContext *context = DoricContext::create(script, alias, extra);
config(context);
}
void DoricPanel::config(DoricContext *context) {
this->mContext = context;
this->mContext->build(960, 720);
}

View File

@ -0,0 +1,20 @@
#ifndef PANEL_H
#define PANEL_H
#include "DoricContext.h"
class DoricPanel {
private:
DoricContext *mContext;
int renderedWidth = -1;
int renderedHeight = -1;
public:
DoricPanel();
void config(QString script, QString alias, QString extra);
void config(DoricContext *context);
};
#endif // PANEL_H

View File

@ -0,0 +1,11 @@
#include "DoricRegistry.h"
#include "plugin/DoricShaderPlugin.h"
DoricRegistry::DoricRegistry() {
registerNativePlugin<DoricShaderPlugin>("shader");
}
bool DoricRegistry::acquirePluginInfo(QString name) {
return pluginInfoMap.acquireClass(name);
}

View File

@ -0,0 +1,21 @@
#ifndef REGISTRY_H
#define REGISTRY_H
#include <QString>
#include "utils/DoricObjectFactory.h"
class DoricRegistry {
public:
DoricObjectFactory pluginInfoMap;
DoricRegistry();
template <typename T> void registerNativePlugin(QString name) {
pluginInfoMap.registerClass<T>(name);
}
bool acquirePluginInfo(QString name);
};
#endif // REGISTRY_H

View File

@ -0,0 +1,16 @@
#ifndef ASYNC_CALL_H
#define ASYNC_CALL_H
#include <QThreadPool>
#include <QtConcurrent/QtConcurrent>
class DoricAsyncCall {
public:
static void ensureRunInThreadPool(QThreadPool *threadPool,
std::function<void()> lambda) {
QtConcurrent::run(threadPool, lambda);
}
};
#endif // ASYNC_CALL_H

View File

@ -0,0 +1,38 @@
#include "DoricAsyncResult.h"
DoricAsyncResult::DoricAsyncResult() {}
DoricAsyncResult::DoricAsyncResult(QJSValue result) { this->result = result; }
void DoricAsyncResult::setResult(QJSValue result) {
this->result = result;
if (this->callback != NULL) {
this->callback->onResult(result);
this->callback->onFinish();
}
}
void DoricAsyncResult::setError(QJSValue exception) {
this->result = exception;
if (this->callback != NULL) {
this->callback->onResult(result);
this->callback->onFinish();
}
}
bool DoricAsyncResult::hasResult() { return !result.equals(EMPTY); }
QJSValue DoricAsyncResult::getResult() { return this->result; }
void DoricAsyncResult::setCallback(DoricCallback *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();
}
}
DoricSettableFuture *DoricAsyncResult::synchronous() { return NULL; }

View File

@ -0,0 +1,34 @@
#ifndef ASYNCRESULT_H
#define ASYNCRESULT_H
#include <QJSValue>
#include "DoricCallback.h"
#include "DoricSettableFuture.h"
static QJSValue EMPTY(QJSValue::NullValue);
class DoricAsyncResult {
private:
QJSValue result = EMPTY;
DoricCallback *callback;
public:
DoricAsyncResult();
DoricAsyncResult(QJSValue result);
void setResult(QJSValue result);
void setError(QJSValue exception);
bool hasResult();
QJSValue getResult();
void setCallback(DoricCallback *callback);
DoricSettableFuture *synchronous();
};
#endif // ASYNCRESULT_H

View File

@ -0,0 +1,15 @@
#ifndef CALLBACK_H
#define CALLBACK_H
#include <QJSValue>
class DoricCallback {
public:
virtual void onResult(QJSValue result) = 0;
virtual void onError(QJSValue error) = 0;
virtual void onFinish() = 0;
};
#endif // CALLBACK_H

View File

@ -0,0 +1,17 @@
#include <QDebug>
#include "DoricSettableFuture.h"
void DoricSettableFuture::set(QJSValue result) {
if (mReadyLatch == NULL) {
qDebug() << "Result has already been set!";
return;
}
mResult = result;
delete mReadyLatch;
}
QJSValue DoricSettableFuture::get() {
mReadyLatch->lock();
return mResult;
}

View File

@ -0,0 +1,19 @@
#ifndef SETTABLE_FUTURE_H
#define SETTABLE_FUTURE_H
#include <QJSValue>
#include "utils/DoricCountDownLatch.h"
class DoricSettableFuture {
private:
QJSValue mResult;
DoricCountDownLatch *mReadyLatch = new DoricCountDownLatch();
public:
void set(QJSValue result);
QJSValue get();
};
#endif // SETTABLE_FUTURE_H

View File

@ -1,16 +0,0 @@
#ifndef ASYNC_CALL_H
#define ASYNC_CALL_H
#include <QThreadPool>
#include <QtConcurrent/QtConcurrent>
class AsyncCall {
public:
static void ensureRunInThreadPool(QThreadPool *threadPool, std::function<void()> lambda)
{
QtConcurrent::run(threadPool, lambda);
}
};
#endif // ASYNC_CALL_H

View File

@ -1,56 +0,0 @@
#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;
}

View File

@ -1,35 +0,0 @@
#ifndef ASYNCRESULT_H
#define ASYNCRESULT_H
#include <QJSValue>
#include "callback.h"
#include "settable_future.h"
static QJSValue EMPTY(QJSValue::NullValue);
class AsyncResult
{
private:
QJSValue result = EMPTY;
Callback *callback;
public:
AsyncResult();
AsyncResult(QJSValue result);
void setResult(QJSValue result);
void setError(QJSValue exception);
bool hasResult();
QJSValue getResult();
void setCallback(Callback *callback);
SettableFuture *synchronous();
};
#endif // ASYNCRESULT_H

View File

@ -1,15 +0,0 @@
#ifndef CALLBACK_H
#define CALLBACK_H
#include <QJSValue>
class Callback {
public:
virtual void onResult(QJSValue result) = 0;
virtual void onError(QJSValue error) = 0;
virtual void onFinish() = 0;
};
#endif // CALLBACK_H

View File

@ -1,20 +0,0 @@
#include <QDebug>
#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;
}

View File

@ -1,18 +0,0 @@
#ifndef SETTABLE_FUTURE_H
#define SETTABLE_FUTURE_H
#include <QJSValue>
#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

View File

@ -1,73 +0,0 @@
#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;
}
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<QString, QVariant> 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)
{
driver = NativeDriver::getInstance();
return driver;
}
return driver;
}
QObject* Context::obtainPlugin(QString name)
{
if (mPluginMap.keys().contains(name)) {
return mPluginMap.value(name);
} else {
QObject *plugin = getDriver()->getRegistry()->pluginInfoMap.createObject(name);
mPluginMap.insert(name, plugin);
return plugin;
}
}

View File

@ -1,37 +0,0 @@
#ifndef CONTEXT_H
#define CONTEXT_H
#include <QVariant>
#include "interface_driver.h"
#include "shader/root_node.h"
class Context
{
private:
QString mContextId;
QMap<QString, QObject*> mPluginMap;
RootNode *mRootNode;
QString source;
QString script;
QString extra;
QVariant initParams;
InterfaceDriver *driver = NULL;
public:
Context(QString contextId, QString source, QString extra);
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();
QObject* obtainPlugin(QString name);
};
#endif // CONTEXT_H

View File

@ -1,15 +0,0 @@
#include "context_manager.h"
Context *ContextManager::createContext(QString script, QString source, QString extra)
{
int contextId = counter->fetchAndAddOrdered(1);
Context *context = new Context(QString::number(contextId), source, extra);
contextMap->insert(QString::number(contextId), context);
context->getDriver()->createContext(QString::number(contextId), script, source);
return context;
}
Context *ContextManager::getContext(QString contextId)
{
return contextMap->take(contextId);
}

View File

@ -1,35 +0,0 @@
#ifndef CONTEXTMANAGER_H
#define CONTEXTMANAGER_H
#include <QDebug>
#include "context.h"
class ContextManager
{
private:
static ContextManager *local_instance;
ContextManager()
{
}
~ContextManager()
{
}
QAtomicInt *counter = new QAtomicInt();
QMap<QString, Context*> *contextMap = new QMap<QString, Context*>();
public:
static ContextManager *getInstance()
{
static ContextManager instance;
return &instance;
}
Context *createContext(QString script, QString source, QString extra);
Context *getContext(QString contextId);
};
#endif // CONTEXTMANAGER_H

View File

@ -0,0 +1,19 @@
#include <QDebug>
#include "DoricDemoBridge.h"
#include "DoricPanel.h"
#include "utils/DoricUtils.h"
DoricDemoBridge::DoricDemoBridge(QObject *parent) : QObject(parent) {}
void DoricDemoBridge::navigate(QVariant route) {
switch (route.toInt()) {
case 0:
QString name = "Snake.es5.js";
QString script = DoricUtils::readAssetFile("/doric/bundles", name);
DoricPanel panel;
panel.config(script, name, NULL);
break;
}
}

View File

@ -0,0 +1,17 @@
#ifndef DEMOBRIDGE_H
#define DEMOBRIDGE_H
#include <QObject>
#include <QVariant>
class DoricDemoBridge : public QObject {
Q_OBJECT
public:
explicit DoricDemoBridge(QObject *parent = nullptr);
Q_INVOKABLE
void navigate(QVariant route);
signals:
};
#endif // DEMOBRIDGE_H

View File

@ -1,23 +0,0 @@
#include <QDebug>
#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.es5.js";
QString script = Utils::readAssetFile("/doric/bundles", name);
Panel panel;
panel.config(script, name, NULL);
break;
}
}

View File

@ -1,19 +0,0 @@
#ifndef DEMOBRIDGE_H
#define DEMOBRIDGE_H
#include <QObject>
#include <QVariant>
class DemoBridge : public QObject
{
Q_OBJECT
public:
explicit DemoBridge(QObject *parent = nullptr);
Q_INVOKABLE
void navigate(QVariant route);
signals:
};
#endif // DEMOBRIDGE_H

View File

@ -14,25 +14,25 @@ DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
async/async_result.cpp \
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 \
DoricContext.cpp \
DoricContextManager.cpp \
DoricNativeDriver.cpp \
DoricPanel.cpp \
DoricRegistry.cpp \
async/DoricAsyncResult.cpp \
async/DoricSettableFuture.cpp \
demo/DoricDemoBridge.cpp \
engine/DoricBridgeExtension.cpp \
engine/DoricJSEngine.cpp \
engine/DoricNativeEmpty.cpp \
engine/DoricNativeJSE.cpp \
engine/DoricNativeLog.cpp \
engine/DoricNativeRequire.cpp \
engine/DoricTimerExtension.cpp \
main.cpp \
native_driver.cpp \
panel.cpp \
plugin/shader_plugin.cpp \
registry.cpp \
shader/root_node.cpp \
utils/constant.cpp
plugin/DoricShaderPlugin.cpp \
shader/DoricRootNode.cpp \
utils/DoricConstant.cpp
RESOURCES += qml.qrc
@ -48,29 +48,29 @@ 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 \
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 \
plugin/shader_plugin.h \
registry.h \
shader/root_node.h \
template/singleton.h \
utils/constant.h \
utils/count_down_latch.h \
utils/object_factory.h \
utils/utils.h
DoricContext.h \
DoricContextManager.h \
DoricInterfaceDriver.h \
DoricNativeDriver.h \
DoricPanel.h \
DoricRegistry.h \
async/DoricAsyncCall.h \
async/DoricAsyncResult.h \
async/DoricCallback.h \
async/DoricSettableFuture.h \
demo/DoricDemoBridge.h \
engine/DoricBridgeExtension.h \
engine/DoricInterfaceJSE.h \
engine/DoricJSEngine.h \
engine/DoricNativeEmpty.h \
engine/DoricNativeJSE.h \
engine/DoricNativeLog.h \
engine/DoricNativeRequire.h \
engine/DoricTimerExtension.h \
plugin/DoricShaderPlugin.h \
shader/DoricRootNode.h \
template/DoricSingleton.h \
utils/DoricConstant.h \
utils/DoricCountDownLatch.h \
utils/DoricObjectFactory.h \
utils/DoricUtils.h

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.11.1, 2021-02-04T14:31:29. -->
<!-- Written by QtCreator 4.11.1, 2021-02-04T16:22:10. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@ -0,0 +1,29 @@
#include <QDebug>
#include <QMetaObject>
#include "../DoricContextManager.h"
#include "DoricBridgeExtension.h"
DoricBridgeExtension::DoricBridgeExtension(QObject *parent) : QObject(parent) {}
void DoricBridgeExtension::callNative(QString contextId, QString module,
QString methodName, QString callbackId,
QJSValue jsValue) {
DoricContext *context =
DoricContextManager::getInstance()->getContext(contextId);
bool classRegistered =
context->getDriver()->getRegistry()->acquirePluginInfo(module);
if (classRegistered) {
QObject *plugin = context->obtainPlugin(module);
QMetaObject::invokeMethod(plugin, methodName.toStdString().c_str(),
Qt::DirectConnection, QGenericReturnArgument(),
Q_ARG(QJSValue, jsValue),
Q_ARG(QString, callbackId));
qDebug() << plugin;
}
qDebug() << "contextId: " + contextId;
qDebug() << "module: " + module;
qDebug() << "methodName: " + methodName;
qDebug() << "callbackId: " + callbackId;
qDebug() << "jsValue: " + jsValue.toString();
}

View File

@ -0,0 +1,17 @@
#ifndef BRIDGEEXTENSION_H
#define BRIDGEEXTENSION_H
#include <QJSValue>
#include <QObject>
class DoricBridgeExtension : public QObject {
Q_OBJECT
public:
explicit DoricBridgeExtension(QObject *parent = nullptr);
Q_INVOKABLE void callNative(QString contextId, QString module,
QString methodName, QString callbackId,
QJSValue jsValue);
};
#endif // BRIDGEEXTENSION_H

View File

@ -0,0 +1,21 @@
#ifndef INTERFACE_JSE_H
#define INTERFACE_JSE_H
#include <QJSValue>
#include <QString>
#include <QVariant>
class DoricInterfaceJSE {
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,
QVariantList arguments) = 0;
};
#endif // INTERFACE_JSE_H

View File

@ -0,0 +1,120 @@
#include <QGuiApplication>
#include <QJsonObject>
#include <QRect>
#include <QScreen>
#include <QSysInfo>
#include <QtConcurrent/QtConcurrent>
#include "../utils/DoricConstant.h"
#include "../utils/DoricUtils.h"
#include "DoricBridgeExtension.h"
#include "DoricJSEngine.h"
#include "DoricNativeEmpty.h"
#include "DoricNativeJSE.h"
#include "DoricNativeLog.h"
#include "DoricNativeRequire.h"
#include "DoricTimerExtension.h"
DoricJSEngine::DoricJSEngine(QObject *parent) : QObject(parent) {
mJSThreadPool.setMaxThreadCount(1);
QtConcurrent::run(&mJSThreadPool, [this] { mJSE = new DoricNativeJSE(); });
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(DoricConstant::INJECT_ENVIRONMENT, envObject);
// inject log
DoricNativeLog *nativeLog = new DoricNativeLog();
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_LOG, nativeLog,
"function");
// inject empty
DoricNativeEmpty *nativeEmpty = new DoricNativeEmpty();
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_EMPTY, nativeEmpty,
"function");
// inject require
DoricNativeRequire *nativeRequire = new DoricNativeRequire();
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_REQUIRE, nativeRequire,
"function");
// inject timer set & clear
DoricTimerExtension *timerExtension =
new DoricTimerExtension([this](long timerId) {
QVariantList arguments;
arguments.push_back(QVariant((int)timerId));
this->invokeDoricMethod(DoricConstant::DORIC_TIMER_CALLBACK,
arguments);
});
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_TIMER_SET,
timerExtension, "setTimer");
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_TIMER_CLEAR,
timerExtension, "clearTimer");
DoricBridgeExtension *bridgeExtension = new DoricBridgeExtension();
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_BRIDGE, bridgeExtension,
"callNative");
});
QtConcurrent::run(&mJSThreadPool, [this] {
loadBuiltinJS(DoricConstant::DORIC_BUNDLE_SANDBOX);
QString libName = DoricConstant::DORIC_MODULE_LIB;
QString libJS =
DoricUtils::readAssetFile("/doric", DoricConstant::DORIC_BUNDLE_LIB);
QString script = packageModuleScript(libName, libJS);
mJSE->loadJS(script, "Module://" + libName);
});
}
void DoricJSEngine::prepareContext(QString contextId, QString script,
QString source) {
mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source);
}
QJSValue DoricJSEngine::invokeDoricMethod(QString method,
QVariantList arguments) {
return mJSE->invokeObject(DoricConstant::GLOBAL_DORIC, method, arguments);
}
void DoricJSEngine::loadBuiltinJS(QString assetName) {
QString script = DoricUtils::readAssetFile("/doric", assetName);
QString result = mJSE->loadJS(script, "Assets://" + assetName);
}
QString DoricJSEngine::packageContextScript(QString contextId,
QString content) {
return QString(DoricConstant::TEMPLATE_CONTEXT_CREATE)
.replace("%s1", content)
.replace("%s2", contextId)
.replace("%s3", contextId);
}
QString DoricJSEngine::packageModuleScript(QString moduleName,
QString content) {
return QString(DoricConstant::TEMPLATE_MODULE)
.replace("%s1", moduleName)
.replace("%s2", content);
}
DoricRegistry *DoricJSEngine::getRegistry() { return this->mRegistry; }
DoricJSEngine::~DoricJSEngine() {}

View File

@ -0,0 +1,32 @@
#ifndef JSENGINE_H
#define JSENGINE_H
#include <QJSValue>
#include <QThreadPool>
#include "../DoricRegistry.h"
#include "DoricInterfaceJSE.h"
class DoricJSEngine : public QObject {
Q_OBJECT
private:
DoricInterfaceJSE *mJSE;
DoricRegistry *mRegistry = new DoricRegistry();
void loadBuiltinJS(QString assetName);
QString packageContextScript(QString contextId, QString content);
QString packageModuleScript(QString moduleName, QString content);
public:
QThreadPool mJSThreadPool;
explicit DoricJSEngine(QObject *parent = nullptr);
~DoricJSEngine();
void prepareContext(QString contextId, QString script, QString source);
QJSValue invokeDoricMethod(QString method, QVariantList arguments);
DoricRegistry *getRegistry();
};
#endif // JSENGINE_H

View File

@ -0,0 +1,7 @@
#include "DoricNativeEmpty.h"
#include <QDebug>
Q_INVOKABLE QJSValue DoricNativeEmpty::function() {
qDebug() << "nativeEmpty";
return QJSValue::NullValue;
}

View File

@ -0,0 +1,16 @@
#ifndef NATIVEEMPTY_H
#define NATIVEEMPTY_H
#include <QJSValue>
#include <QObject>
class DoricNativeEmpty : public QObject {
Q_OBJECT
public:
DoricNativeEmpty(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE QJSValue function();
};
#endif // NATIVEEMPTY_H

View File

@ -0,0 +1,65 @@
#include "DoricNativeJSE.h"
#include <QDebug>
DoricNativeJSE::DoricNativeJSE() {
mJSEngine.installExtensions(QJSEngine::AllExtensions);
}
QString DoricNativeJSE::loadJS(QString script, QString source) {
return mJSEngine.evaluate(script, source).toString();
}
void DoricNativeJSE::injectGlobalJSObject(QString name, QObject *object) {
QJSValue jsObject = mJSEngine.newQObject(object);
QList<QByteArray> 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 DoricNativeJSE::injectGlobalJSFunction(QString name, QObject *function,
QString property) {
QJSValue functionObject = mJSEngine.newQObject(function);
mJSEngine.globalObject().setProperty(name, functionObject.property(property));
}
QJSValue DoricNativeJSE::invokeObject(QString objectName, QString functionName,
QVariantList arguments) {
QJSValue object = mJSEngine.evaluate(objectName);
QJSValue function = object.property(functionName);
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<QString, QVariant> 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;
}

View File

@ -0,0 +1,25 @@
#ifndef NATIVE_JSE_H
#define NATIVE_JSE_H
#include "DoricInterfaceJSE.h"
#include <QJSEngine>
class DoricNativeJSE : public DoricInterfaceJSE {
private:
QJSEngine mJSEngine;
public:
DoricNativeJSE();
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,
QVariantList arguments) override;
};
#endif // NATIVE_JSE_H

View File

@ -0,0 +1,13 @@
#include <QDebug>
#include "DoricNativeLog.h"
Q_INVOKABLE void DoricNativeLog::function(QString level, QString content) {
if (level == 'w') {
qWarning() << content;
} else if (level == 'd') {
qDebug() << content;
} else if (level == 'e') {
qCritical() << content;
}
}

View File

@ -0,0 +1,15 @@
#ifndef NATIVE_LOG_H
#define NATIVE_LOG_H
#include <QObject>
class DoricNativeLog : public QObject {
Q_OBJECT
public:
DoricNativeLog(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void function(QString level, QString content);
};
#endif // NATIVE_LOG_H

View File

@ -0,0 +1,8 @@
#include "DoricNativeRequire.h"
#include <QDebug>
Q_INVOKABLE QJSValue DoricNativeRequire::function(QString name) {
qDebug() << "nativeRequire";
return QJSValue::NullValue;
}

View File

@ -0,0 +1,16 @@
#ifndef NATIVE_REQUIRE_H
#define NATIVE_REQUIRE_H
#include <QJSValue>
#include <QObject>
class DoricNativeRequire : public QObject {
Q_OBJECT
public:
DoricNativeRequire(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE QJSValue function(QString name);
};
#endif // NATIVE_REQUIRE_H

View File

@ -0,0 +1,28 @@
#include <QTimer>
#include "../utils/DoricConstant.h"
#include "DoricTimerExtension.h"
Q_INVOKABLE void DoricTimerExtension::setTimer(long timerId, int time,
bool repeat) {
QTimer *timer = new QTimer(this);
timer->setSingleShot(!repeat);
connect(timer, &QTimer::timeout, this, [=]() {
if (deletedTimerIds->contains(timerId)) {
deletedTimerIds->remove(timerId);
delete timer;
} else {
this->method(timerId);
if (!repeat) {
deletedTimerIds->remove(timerId);
delete timer;
}
}
});
timer->start(time);
}
Q_INVOKABLE void DoricTimerExtension::clearTimer(long timerId) {
deletedTimerIds->insert(timerId);
}

View File

@ -0,0 +1,25 @@
#ifndef NATIVETIMER_H
#define NATIVETIMER_H
#include <QObject>
#include <QSet>
class DoricTimerExtension : public QObject {
Q_OBJECT
private:
QSet<long> *deletedTimerIds = new QSet<long>();
std::function<void(long)> method;
public:
explicit DoricTimerExtension(std::function<void(long)> 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

View File

@ -1,30 +0,0 @@
#include <QDebug>
#include <QMetaObject>
#include "bridge_extension.h"
#include "../context_manager.h"
BridgeExtension::BridgeExtension(QObject *parent) : QObject(parent)
{
}
void BridgeExtension::callNative(QString contextId, QString module, QString methodName, QString callbackId, QJSValue jsValue)
{
Context *context = ContextManager::getInstance()->getContext(contextId);
bool classRegistered = context->getDriver()->getRegistry()->acquirePluginInfo(module);
if (classRegistered) {
QObject *plugin = context->obtainPlugin(module);
QMetaObject::invokeMethod(
plugin,
methodName.toStdString().c_str(),
Qt::DirectConnection, QGenericReturnArgument(),
Q_ARG(QJSValue, jsValue), Q_ARG(QString, callbackId));
qDebug() << plugin;
}
qDebug() << "contextId: " + contextId;
qDebug() << "module: " + module;
qDebug() << "methodName: " + methodName;
qDebug() << "callbackId: " + callbackId;
qDebug() << "jsValue: " + jsValue.toString();
}

View File

@ -1,16 +0,0 @@
#ifndef BRIDGEEXTENSION_H
#define BRIDGEEXTENSION_H
#include <QObject>
#include <QJSValue>
class BridgeExtension : public QObject
{
Q_OBJECT
public:
explicit BridgeExtension(QObject *parent = nullptr);
Q_INVOKABLE void callNative(QString contextId, QString module, QString methodName, QString callbackId, QJSValue jsValue);
};
#endif // BRIDGEEXTENSION_H

View File

@ -1,19 +0,0 @@
#ifndef INTERFACE_JSE_H
#define INTERFACE_JSE_H
#include <QString>
#include <QJSValue>
#include <QVariant>
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, QVariantList arguments) = 0;
};
#endif // INTERFACE_JSE_H

View File

@ -1,116 +0,0 @@
#include <QGuiApplication>
#include <QJsonObject>
#include <QRect>
#include <QScreen>
#include <QSysInfo>
#include <QtConcurrent/QtConcurrent>
#include "js_engine.h"
#include "native_jse.h"
#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"
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 require
NativeRequire *nativeRequire = new NativeRequire();
mJSE->injectGlobalJSFunction(Constant::INJECT_REQUIRE, nativeRequire, "function");
// inject timer set & clear
TimerExtension *timerExtension = new TimerExtension([this](long timerId){
QVariantList arguments;
arguments.push_back(QVariant((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(QString contextId, QString script, QString source)
{
mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source);
}
QJSValue JSEngine::invokeDoricMethod(QString method, QVariantList arguments)
{
return mJSE->invokeObject(Constant::GLOBAL_DORIC, method, arguments);
}
void JSEngine::loadBuiltinJS(QString assetName)
{
QString script = Utils::readAssetFile("/doric", assetName);
QString result = mJSE->loadJS(script, "Assets://" + assetName);
}
QString JSEngine::packageContextScript(QString contextId, QString content)
{
return QString(Constant::TEMPLATE_CONTEXT_CREATE).replace("%s1", content).replace("%s2", contextId).replace("%s3", contextId);
}
QString JSEngine::packageModuleScript(QString moduleName, QString content)
{
return QString(Constant::TEMPLATE_MODULE).replace("%s1", moduleName).replace("%s2", content);
}
Registry *JSEngine::getRegistry()
{
return this->mRegistry;
}
JSEngine::~JSEngine()
{
}

View File

@ -1,32 +0,0 @@
#ifndef JSENGINE_H
#define JSENGINE_H
#include <QJSValue>
#include <QThreadPool>
#include "interface_jse.h"
#include "../registry.h"
class JSEngine : public QObject
{
Q_OBJECT
private:
InterfaceJSE *mJSE;
Registry *mRegistry = new Registry();
void loadBuiltinJS(QString assetName);
QString packageContextScript(QString contextId, QString content);
QString packageModuleScript(QString moduleName, QString content);
public:
QThreadPool mJSThreadPool;
explicit JSEngine(QObject *parent = nullptr);
~JSEngine();
void prepareContext(QString contextId, QString script, QString source);
QJSValue invokeDoricMethod(QString method, QVariantList arguments);
Registry *getRegistry();
};
#endif // JSENGINE_H

View File

@ -1,7 +0,0 @@
#include "native_empty.h"
#include <QDebug>
Q_INVOKABLE QJSValue NativeEmpty::function() {
qDebug() << "nativeEmpty";
return QJSValue::NullValue;
}

View File

@ -1,16 +0,0 @@
#ifndef NATIVEEMPTY_H
#define NATIVEEMPTY_H
#include <QObject>
#include <QJSValue>
class NativeEmpty : public QObject {
Q_OBJECT
public:
NativeEmpty(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE QJSValue function();
};
#endif // NATIVEEMPTY_H

View File

@ -1,69 +0,0 @@
#include "native_jse.h"
#include <QDebug>
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<QByteArray> 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, QVariantList arguments)
{
QJSValue object = mJSEngine.evaluate(objectName);
QJSValue function = object.property(functionName);
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<QString, QVariant> 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;
}

View File

@ -1,23 +0,0 @@
#ifndef NATIVE_JSE_H
#define NATIVE_JSE_H
#include <QJSEngine>
#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, QVariantList arguments) override;
};
#endif // NATIVE_JSE_H

View File

@ -1,13 +0,0 @@
#include <QDebug>
#include "native_log.h"
Q_INVOKABLE void NativeLog::function(QString level, QString content) {
if (level == 'w') {
qWarning() << content;
} else if (level == 'd') {
qDebug() << content;
} else if (level == 'e') {
qCritical() << content;
}
}

View File

@ -1,15 +0,0 @@
#ifndef NATIVE_LOG_H
#define NATIVE_LOG_H
#include <QObject>
class NativeLog : public QObject {
Q_OBJECT
public:
NativeLog(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void function(QString level, QString content);
};
#endif // NATIVE_LOG_H

View File

@ -1,8 +0,0 @@
#include "native_require.h"
#include <QDebug>
Q_INVOKABLE QJSValue NativeRequire::function(QString name) {
qDebug() << "nativeRequire";
return QJSValue::NullValue;
}

View File

@ -1,18 +0,0 @@
#ifndef NATIVE_REQUIRE_H
#define NATIVE_REQUIRE_H
#include <QObject>
#include <QJSValue>
class NativeRequire : public QObject {
Q_OBJECT
public:
NativeRequire(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE QJSValue function(QString name);
};
#endif // NATIVE_REQUIRE_H

View File

@ -1,27 +0,0 @@
#include <QTimer>
#include "timer_extension.h"
#include "../utils/constant.h"
Q_INVOKABLE void TimerExtension::setTimer(long timerId, int time, bool repeat) {
QTimer *timer = new QTimer(this);
timer->setSingleShot(!repeat);
connect(timer, &QTimer::timeout, this, [=] () {
if (deletedTimerIds->contains(timerId)) {
deletedTimerIds->remove(timerId);
delete timer;
} else {
this->method(timerId);
if (!repeat) {
deletedTimerIds->remove(timerId);
delete timer;
}
}
});
timer->start(time);
}
Q_INVOKABLE void TimerExtension::clearTimer(long timerId) {
deletedTimerIds->insert(timerId);
}

View File

@ -1,24 +0,0 @@
#ifndef NATIVETIMER_H
#define NATIVETIMER_H
#include <QObject>
#include <QSet>
class TimerExtension : public QObject {
Q_OBJECT
private:
QSet<long> *deletedTimerIds = new QSet<long>();
std::function<void(long)> method;
public:
explicit TimerExtension(std::function<void(long)> 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

View File

@ -1,23 +0,0 @@
#ifndef INTERFACEDRIVER_H
#define INTERFACEDRIVER_H
#include <QString>
#include <QVariant>
#include "registry.h"
class InterfaceDriver
{
public:
virtual void invokeContextEntityMethod(QString contextId, QString method, QVariantList args) = 0;
virtual void invokeDoricMethod(QString method, QVariantList args) = 0;
virtual void createContext(QString contextId, QString script, QString source) = 0;
virtual void destroyContext(QString contextId) = 0;
virtual Registry* getRegistry() = 0;
};
#endif // INTERFACEDRIVER_H

View File

@ -2,26 +2,26 @@
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "demo/demo_bridge.h"
#include "demo/DoricDemoBridge.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
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);
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
DemoBridge *demoBridge = new DemoBridge();
auto context = engine.rootContext();
context->setContextProperty("demoBridge", demoBridge);
engine.load(url);
return app.exec();
DoricDemoBridge *demoBridge = new DoricDemoBridge();
auto context = engine.rootContext();
context->setContextProperty("demoBridge", demoBridge);
engine.load(url);
return app.exec();
}

View File

@ -1,36 +0,0 @@
#include <functional>
#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, QVariantList args)
{
return AsyncCall::ensureRunInThreadPool(&jsEngine.mJSThreadPool, [this, method, args]{
this->jsEngine.invokeDoricMethod(method, args).toString();
});
}
void NativeDriver::createContext(QString contextId, QString script, QString source)
{
AsyncCall::ensureRunInThreadPool(&jsEngine.mJSThreadPool, [this, contextId, script, source]{
this->jsEngine.prepareContext(contextId, script, source);
});
}
void NativeDriver::destroyContext(QString contextId)
{
}
Registry *NativeDriver::getRegistry()
{
return this->jsEngine.getRegistry();
}

View File

@ -1,40 +0,0 @@
#ifndef NATIVEDRIVER_H
#define NATIVEDRIVER_H
#include <QDebug>
#include "interface_driver.h"
#include "engine/js_engine.h"
class NativeDriver : public InterfaceDriver
{
private:
static NativeDriver *local_instance;
NativeDriver()
{
}
~NativeDriver()
{
}
JSEngine jsEngine;
public:
static NativeDriver *getInstance()
{
static NativeDriver instance;
return &instance;
}
void invokeContextEntityMethod(QString contextId, QString method, QVariantList args) override;
void invokeDoricMethod(QString method, QVariantList args) override;
void createContext(QString contextId, QString script, QString source) override;
void destroyContext(QString contextId) override;
Registry * getRegistry() override;
};
#endif // NATIVEDRIVER_H

View File

@ -1,18 +0,0 @@
#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);
}

View File

@ -1,21 +0,0 @@
#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

View File

@ -0,0 +1,9 @@
#include "DoricShaderPlugin.h"
#include <QDebug>
DoricShaderPlugin::DoricShaderPlugin(QObject *parent) : QObject(parent) {}
void DoricShaderPlugin::render(QJSValue jsValue, QString callbackId) {
qDebug() << "";
}

View File

@ -0,0 +1,15 @@
#ifndef SHADERPLUGIN_H
#define SHADERPLUGIN_H
#include <QJSValue>
#include <QObject>
class DoricShaderPlugin : public QObject {
Q_OBJECT
public:
DoricShaderPlugin(QObject *parent);
Q_INVOKABLE void render(QJSValue jsValue, QString callbackId);
};
#endif // SHADERPLUGIN_H

View File

@ -1,13 +0,0 @@
#include "shader_plugin.h"
#include <QDebug>
ShaderPlugin::ShaderPlugin(QObject* parent) : QObject (parent)
{
}
void ShaderPlugin::render(QJSValue jsValue, QString callbackId)
{
qDebug() << "";
}

View File

@ -1,16 +0,0 @@
#ifndef SHADERPLUGIN_H
#define SHADERPLUGIN_H
#include <QJSValue>
#include <QObject>
class ShaderPlugin : public QObject
{
Q_OBJECT
public:
ShaderPlugin(QObject* parent);
Q_INVOKABLE void render(QJSValue jsValue, QString callbackId);
};
#endif // SHADERPLUGIN_H

View File

@ -1,13 +0,0 @@
#include "registry.h"
#include "plugin/shader_plugin.h"
Registry::Registry()
{
registerNativePlugin<ShaderPlugin>("shader");
}
bool Registry::acquirePluginInfo(QString name)
{
return pluginInfoMap.acquireClass(name);
}

View File

@ -1,24 +0,0 @@
#ifndef REGISTRY_H
#define REGISTRY_H
#include <QString>
#include "utils/object_factory.h"
class Registry
{
public:
ObjectFactory pluginInfoMap;
Registry();
template<typename T>
void registerNativePlugin(QString name)
{
pluginInfoMap.registerClass<T>(name);
}
bool acquirePluginInfo(QString name);
};
#endif // REGISTRY_H

View File

@ -0,0 +1,3 @@
#include "DoricRootNode.h"
DoricRootNode::DoricRootNode() {}

View File

@ -1,10 +1,9 @@
#ifndef ROOTNODE_H
#define ROOTNODE_H
class RootNode
{
class DoricRootNode {
public:
RootNode();
DoricRootNode();
};
#endif // ROOTNODE_H

View File

@ -1,6 +0,0 @@
#include "root_node.h"
RootNode::RootNode()
{
}

View File

@ -0,0 +1,20 @@
#ifndef SINGLETON_H
#define SINGLETON_H
#include <QDebug>
class DoricSingleton {
private:
static DoricSingleton *local_instance;
DoricSingleton() { qDebug() << "constructor"; }
~DoricSingleton() { qDebug() << "destructor"; }
public:
static DoricSingleton *getInstance() {
static DoricSingleton locla_s;
return &locla_s;
}
};
#endif // SINGLETON_H

View File

@ -1,28 +0,0 @@
#ifndef SINGLETON_H
#define SINGLETON_H
#include <QDebug>
class Singleton
{
private:
static Singleton *local_instance;
Singleton()
{
qDebug() << "constructor";
}
~Singleton()
{
qDebug() << "destructor";
}
public:
static Singleton *getInstance()
{
static Singleton locla_s;
return &locla_s;
}
};
#endif // SINGLETON_H

View File

@ -0,0 +1,34 @@
#include "DoricConstant.h"
const QString DoricConstant::DORIC_BUNDLE_SANDBOX = "doric-sandbox.es5.js";
const QString DoricConstant::DORIC_BUNDLE_LIB = "doric-lib.es5.js";
const QString DoricConstant::DORIC_MODULE_LIB = "doric";
const QString DoricConstant::INJECT_ENVIRONMENT = "Environment";
const QString DoricConstant::INJECT_LOG = "nativeLog";
const QString DoricConstant::INJECT_EMPTY = "nativeEmpty";
const QString DoricConstant::INJECT_REQUIRE = "nativeRequire";
const QString DoricConstant::INJECT_TIMER_SET = "nativeSetTimer";
const QString DoricConstant::INJECT_TIMER_CLEAR = "nativeClearTimer";
const QString DoricConstant::INJECT_BRIDGE = "nativeBridge";
const QString DoricConstant::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 DoricConstant::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 DoricConstant::TEMPLATE_CONTEXT_DESTROY =
QString("doric.jsReleaseContext(\"%s\")");
const QString DoricConstant::GLOBAL_DORIC = "doric";
const QString DoricConstant::DORIC_CONTEXT_INVOKE = "jsCallEntityMethod";
const QString DoricConstant::DORIC_TIMER_CALLBACK = "jsCallbackTimer";
const QString DoricConstant::DORIC_ENTITY_INIT = "__init__";
const QString DoricConstant::DORIC_ENTITY_CREATE = "__onCreate__";
const QString DoricConstant::DORIC_ENTITY_BUILD = "__build__";

View File

@ -0,0 +1,34 @@
#ifndef CONSTANT_H
#define CONSTANT_H
#include <QString>
class DoricConstant {
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 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_CREATE;
static const QString DORIC_ENTITY_INIT;
static const QString DORIC_ENTITY_BUILD;
};
#endif // CONSTANT_H

View File

@ -0,0 +1,32 @@
#ifndef COUNTDOWNLATCH_H
#define COUNTDOWNLATCH_H
#include <QSemaphore>
#include <climits>
class DoricCountDownLatch {
Q_DISABLE_COPY(DoricCountDownLatch)
QSemaphore m_sem{INT_MAX};
public:
DoricCountDownLatch() {}
~DoricCountDownLatch() {
m_sem.acquire(INT_MAX);
m_sem.release(INT_MAX);
}
class Locker {
DoricCountDownLatch *sem;
public:
Locker(const Locker &other) : sem{other.sem} { sem->m_sem.acquire(); }
Locker(Locker &&other) : sem{other.sem} { other.sem = nullptr; }
Locker(DoricCountDownLatch *sem) : sem{sem} { sem->m_sem.acquire(); }
~Locker() {
if (sem)
sem->m_sem.release();
}
};
Locker lock() { return Locker{this}; }
};
#endif // COUNTDOWNLATCH_H

View File

@ -0,0 +1,38 @@
#include <QByteArray>
#include <QHash>
#include <QMetaObject>
#ifndef OBJECTFACTORY_H
#define OBJECTFACTORY_H
class DoricObjectFactory {
public:
template <typename T> static void registerClass(QString name) {
constructors().insert(name, &constructorHelper<T>);
}
static bool acquireClass(QString name) {
return constructors().keys().contains(name);
}
static QObject *createObject(const QString &name, QObject *parent = NULL) {
Constructor constructor = constructors().value(name);
if (constructor == NULL)
return NULL;
return (*constructor)(parent);
}
private:
typedef QObject *(*Constructor)(QObject *parent);
template <typename T> static QObject *constructorHelper(QObject *parent) {
return new T(parent);
}
static QHash<QString, Constructor> &constructors() {
static QHash<QString, Constructor> instance;
return instance;
}
};
#endif // OBJECTFACTORY_H

View File

@ -0,0 +1,25 @@
#ifndef UTILS_H
#define UTILS_H
#include <QFile>
#include <QResource>
#include <QString>
#include <QTextStream>
class DoricUtils {
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);
in.setCodec("UTF-8");
QString content = in.readAll();
file->close();
delete file;
return content;
}
};
#endif // UTILS_H

View File

@ -1,42 +0,0 @@
#include "constant.h"
const QString Constant::DORIC_BUNDLE_SANDBOX = "doric-sandbox.es5.js";
const QString Constant::DORIC_BUNDLE_LIB = "doric-lib.es5.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_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__";

View File

@ -1,35 +0,0 @@
#ifndef CONSTANT_H
#define CONSTANT_H
#include <QString>
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 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_CREATE;
static const QString DORIC_ENTITY_INIT;
static const QString DORIC_ENTITY_BUILD;
};
#endif // CONSTANT_H

View File

@ -1,27 +0,0 @@
#ifndef COUNTDOWNLATCH_H
#define COUNTDOWNLATCH_H
#include <climits>
#include <QSemaphore>
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

View File

@ -1,46 +0,0 @@
#include <QByteArray>
#include <QMetaObject>
#include <QHash>
#ifndef OBJECTFACTORY_H
#define OBJECTFACTORY_H
class ObjectFactory
{
public:
template<typename T>
static void registerClass(QString name)
{
constructors().insert(name, &constructorHelper<T>);
}
static bool acquireClass(QString name)
{
return constructors().keys().contains(name);
}
static QObject* createObject(const QString& name, QObject* parent = NULL)
{
Constructor constructor = constructors().value(name);
if ( constructor == NULL )
return NULL;
return (*constructor)(parent);
}
private:
typedef QObject* (*Constructor)(QObject* parent);
template<typename T>
static QObject* constructorHelper(QObject* parent)
{
return new T(parent);
}
static QHash<QString, Constructor>& constructors()
{
static QHash<QString, Constructor> instance;
return instance;
}
};
#endif // OBJECTFACTORY_H

View File

@ -1,26 +0,0 @@
#ifndef UTILS_H
#define UTILS_H
#include <QString>
#include <QResource>
#include <QFile>
#include <QTextStream>
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);
in.setCodec("UTF-8");
QString content = in.readAll();
file->close();
delete file;
return content;
}
};
#endif // UTILS_H