add files from main project

This commit is contained in:
pengfei.zhou 2019-12-04 15:51:46 +08:00
parent 2ca38388f3
commit dbdd1770ef
19 changed files with 579 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build-doric-*/

73
doric/.gitignore vendored Normal file
View File

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

32
doric/constant.cpp Normal file
View File

@ -0,0 +1,32 @@
#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_TIMER_CALLBACK = QString("jsCallbackTimer");

24
doric/constant.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef CONSTANT_H
#define CONSTANT_H
#include <QString>
class Constant {
public:
static const QString INJECT_LOG;
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_TIMER_CALLBACK;
};
#endif // CONSTANT_H

24
doric/context.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef CONTEXT_H
#define CONTEXT_H
#include <QString>
#include "driver/driver.h"
#include "driver/native_driver.h"
class Context
{
private:
int contextId;
QString* source;
public:
Driver* driver = NativeDriver::getInstance();
Context(int contextId, QString* source) {
this->contextId = contextId;
this->source = source;
}
};
#endif // CONTEXT_H

41
doric/context_manager.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef CONTEXT_MANAGER_H
#define CONTEXT_MANAGER_H
#include <QAtomicInt>
#include <QDebug>
#include <QMap>
#include "context.h"
class ContextManager
{
private:
static ContextManager *local_instance;
ContextManager() {
qDebug() << "ContextManager constructor";
}
~ContextManager() {
qDebug() << "ContextManager destructor";
}
QAtomicInt *counter = new QAtomicInt();
QMap<int, Context*> *contextMap = new QMap<int, Context*>();
public:
static ContextManager *getInstance() {
static ContextManager locla_s;
return &locla_s;
}
Context* createContext(QString* script, QString* source) {
int contextId = counter->fetchAndAddOrdered(1);
Context* context = new Context(contextId, source);
contextMap->insert(contextId, context);
context->driver->createContext(contextId, script);
return context;
}
};
#endif // CONTEXT_MANAGER_H

45
doric/doric.pro Normal file
View File

@ -0,0 +1,45 @@
QT += quick
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
constant.cpp \
driver/native_driver.cpp \
main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
constant.h \
context.h \
context_manager.h \
driver/driver.h \
driver/native_driver.h \
engine/js_engine.h \
native/native_bridge.h \
native/native_empty.h \
native/native_log.h \
native/native_timer.h \
template/singleton.h

19
doric/driver/driver.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef DRIVER_H
#define DRIVER_H
#include <QtPlugin>
class Driver {
public:
virtual void createContext(int contextId, QString* script) = 0;
virtual void destroyContext(int contextId) = 0;
virtual ~Driver() = default;
};
#define DriverInterface "pub.doric.DriverInterface"
Q_DECLARE_INTERFACE(Driver, DriverInterface)
#endif // DRIVER_H

View File

@ -0,0 +1,13 @@
#include "native_driver.h"
NativeDriver::~NativeDriver() {
qDebug() << "NativeDriver destructor";
}
void NativeDriver::createContext(int contextId, QString *script) {
jsEngine->prepareContext(contextId, script);
}
void NativeDriver::destroyContext(int contextId) {
jsEngine->destroyContext(contextId);
}

View File

@ -0,0 +1,33 @@
#ifndef NATIVE_DRIVER_H
#define NATIVE_DRIVER_H
#include <QDebug>
#include "driver.h"
#include "engine/js_engine.h"
class NativeDriver : public Driver {
Q_INTERFACES(Driver)
private:
static NativeDriver *local_instance;
NativeDriver() {
qDebug() << "NativeDriver constructor";
}
~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;
};
#endif // NATIVE_DRIVER_H

91
doric/engine/js_engine.h Normal file
View File

@ -0,0 +1,91 @@
#ifndef JS_ENGINE_H
#define JS_ENGINE_H
#include <QFile>
#include <QObject>
#include <QJSEngine>
#include "constant.h"
#include "native/native_empty.h"
#include "native/native_log.h"
#include "native/native_timer.h"
class JSEngine : public QObject {
Q_OBJECT
public:
QJSEngine *engine;
JSEngine(QObject *parent = nullptr) : QObject(parent) {
initJSEngine();
injectGlobal();
initDoricRuntime();
}
void 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();
}
void 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();
}
private:
void initJSEngine() {
engine = new QJSEngine();
engine->installExtensions(QJSEngine::AllExtensions);
}
void injectGlobal() {
QJSValue nativeLog = engine->newQObject(new NativeLog());
engine->globalObject().setProperty(Constant::INJECT_LOG, nativeLog.property("function"));
QJSValue nativeTimer = engine->newQObject(new NativeTimer(engine));
engine->globalObject().setProperty(Constant::INJECT_TIMER_SET, nativeTimer.property("setTimer"));
engine->globalObject().setProperty(Constant::INJECT_TIMER_CLEAR, nativeTimer.property("clearTimer"));
QJSValue nativeEmpty = engine->newQObject(new NativeEmpty());
engine->globalObject().setProperty(Constant::INJECT_EMPTY, nativeEmpty.property("function"));
}
void initDoricRuntime() {
{
QFile *file = new QFile("/Users/maverick/Workspace/doric/js-framework/bundle/doric-sandbox.js");
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();
}
{
QFile *file = new QFile("/Users/maverick/Workspace/doric/js-framework/bundle/doric-lib.js");
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();
}
}
};
#endif // JS_ENGINE_H

33
doric/main.cpp Normal file
View File

@ -0,0 +1,33 @@
#include <QFile>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTextStream>
#include "context_manager.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
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) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
QFile* file = new QFile("/Users/maverick/Workspace/doric/demo/bundle/src/Snake.js");
file->open(QFile::ReadOnly | QFile::Text);
QTextStream in(file);
QString script = in.readAll();
file->close();
delete file;
QString* source = new QString("Snake.js");
ContextManager::getInstance()->createContext(&script, source);
return app.exec();
}

9
doric/main.qml Normal file
View File

@ -0,0 +1,9 @@
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
}

View File

@ -0,0 +1,18 @@
#ifndef NATIVE_BRIDGE_H
#define NATIVE_BRIDGE_H
#include <QObject>
#include <QDebug>
class NativeBridge : public QObject {
Q_OBJECT
public:
NativeBridge(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void function() {
}
};
#endif // NATIVE_BRIDGE_H

View File

@ -0,0 +1,18 @@
#ifndef NATIVE_EMPTY_H
#define NATIVE_EMPTY_H
#include <QObject>
#include <QDebug>
class NativeEmpty : public QObject {
Q_OBJECT
public:
NativeEmpty(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void function() {
qDebug() << "nativeEmpty";
}
};
#endif // NATIVE_EMPTY_H

24
doric/native/native_log.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef NATIVELOG_H
#define NATIVELOG_H
#include <QObject>
#include <QDebug>
class NativeLog : public QObject {
Q_OBJECT
public:
NativeLog(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void function(QString level, QString content) {
if (level == 'w') {
qWarning() << content;
} else if (level == 'd') {
qDebug() << content;
} else if (level == 'e') {
qCritical() << content;
}
}
};
#endif // NATIVELOG_H

View File

@ -0,0 +1,51 @@
#ifndef NATIVE_TIMER_H
#define NATIVE_TIMER_H
#include <QJSEngine>
#include <QObject>
#include <QSet>
#include <QTimer>
#include "constant.h"
class NativeTimer : public QObject {
Q_OBJECT
private:
QSet<long> *deletedTimerIds = new QSet<long>();
QJSEngine* engine;
public:
NativeTimer(QJSEngine* engine, QObject *parent = nullptr) : QObject(parent) {
this->engine = engine;
}
Q_INVOKABLE void 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 {
engine->evaluate(
Constant::GLOBAL_DORIC + "." +
Constant::DORIC_TIMER_CALLBACK + "(" +
QString::number(timerId) + ")"
);
if (!repeat) {
deletedTimerIds->remove(timerId);
delete timer;
}
}
});
timer->start(time);
}
Q_INVOKABLE void clearTimer(long timerId) {
deletedTimerIds->insert(timerId);
}
};
#endif // NATIVE_TIMER_H

5
doric/qml.qrc Normal file
View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>

View File

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