add files from main project
This commit is contained in:
parent
2ca38388f3
commit
dbdd1770ef
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build-doric-*/
|
73
doric/.gitignore
vendored
Normal file
73
doric/.gitignore
vendored
Normal 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
32
doric/constant.cpp
Normal 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
24
doric/constant.h
Normal 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
24
doric/context.h
Normal 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
41
doric/context_manager.h
Normal 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
45
doric/doric.pro
Normal 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
19
doric/driver/driver.h
Normal 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
|
13
doric/driver/native_driver.cpp
Normal file
13
doric/driver/native_driver.cpp
Normal 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);
|
||||
}
|
33
doric/driver/native_driver.h
Normal file
33
doric/driver/native_driver.h
Normal 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
91
doric/engine/js_engine.h
Normal 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
33
doric/main.cpp
Normal 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
9
doric/main.qml
Normal 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")
|
||||
}
|
18
doric/native/native_bridge.h
Normal file
18
doric/native/native_bridge.h
Normal 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
|
18
doric/native/native_empty.h
Normal file
18
doric/native/native_empty.h
Normal 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
24
doric/native/native_log.h
Normal 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
|
51
doric/native/native_timer.h
Normal file
51
doric/native/native_timer.h
Normal 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
5
doric/qml.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
25
doric/template/singleton.h
Normal file
25
doric/template/singleton.h
Normal 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
|
Reference in New Issue
Block a user