mirror of
https://gitlab.com/eql/lqml.git
synced 2026-01-18 23:31:05 -08:00
first working desktop version
This commit is contained in:
parent
0e6ff84388
commit
42e8912912
30 changed files with 2561 additions and 3 deletions
115
src/cpp/lqml.cpp
Normal file
115
src/cpp/lqml.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include "lqml.h"
|
||||
#include "qml.h"
|
||||
#include "ecl_ext.h"
|
||||
#include <iostream>
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
#include <QStringList>
|
||||
#include <QDebug>
|
||||
|
||||
const char LQML::version[] = "22.1.1"; // Jan 2022
|
||||
|
||||
extern "C" void ini_LQML(cl_object);
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
static void logMessageHandler(QtMsgType, const QMessageLogContext& context, const QString& msg) {
|
||||
// for logging on android (see 'adb logcat')
|
||||
// examples:
|
||||
// Lisp: (qlog "x: ~A y: ~A" x y)
|
||||
// QML: console.log("message")
|
||||
QString report(msg);
|
||||
if (context.file && !QString(context.file).isEmpty()) {
|
||||
report += " in file ";
|
||||
report += QString(context.file);
|
||||
report += " line ";
|
||||
report += QString::number(context.line);
|
||||
}
|
||||
if (context.function && !QString(context.function).isEmpty()) {
|
||||
report += " function ";
|
||||
report += QString(context.function);
|
||||
}
|
||||
__android_log_write(ANDROID_LOG_DEBUG, "[EQL5]", report.toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
LQML::LQML(int argc, char* argv[], QQuickView* view) : QObject() {
|
||||
me = this;
|
||||
quickView = view;
|
||||
iniQml();
|
||||
#ifdef Q_OS_ANDROID
|
||||
qInstallMessageHandler(logMessageHandler); // see above
|
||||
#endif
|
||||
if (!cl_booted_p) {
|
||||
cl_boot(argc, argv); }
|
||||
iniCLFunctions();
|
||||
ecl_init_module(NULL, ini_LQML);
|
||||
eval("(in-package :qml-user)");
|
||||
eval(QString("(setf *quick-view* (make-qobject %1))").arg((quintptr)view));
|
||||
}
|
||||
|
||||
LQML::~LQML() {
|
||||
if (!LQML::cl_shutdown_p) {
|
||||
cl_shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void LQML::ini(int argc, char* argv[]) {
|
||||
cl_booted_p = true;
|
||||
cl_boot(argc, argv);
|
||||
}
|
||||
|
||||
static cl_object safe_eval(const char* lisp_code) {
|
||||
cl_object ret = ECL_NIL;
|
||||
CL_CATCH_ALL_BEGIN(ecl_process_env()) {
|
||||
ret = si_safe_eval(3,
|
||||
ecl_read_from_cstring(lisp_code),
|
||||
ECL_NIL,
|
||||
ecl_make_fixnum(EVAL_ERROR_VALUE));
|
||||
}
|
||||
CL_CATCH_ALL_END;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LQML::eval(const QString& lisp_code) {
|
||||
cl_object ret = safe_eval(lisp_code.toLatin1().constData());
|
||||
if (ecl_t_of(ret) == t_fixnum && (fix(ret) == EVAL_ERROR_VALUE)) {
|
||||
qDebug() << "Error evaluating " << lisp_code;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void LQML::ignoreIOStreams() {
|
||||
// [Windows] print output would cause a gui exe to crash (without console)
|
||||
eval("(eql::ignore-io-streams)");
|
||||
}
|
||||
|
||||
void LQML::exec(lisp_ini ini, const QByteArray& expression, const QByteArray& package) {
|
||||
// see my_app example
|
||||
ecl_init_module(NULL, ini);
|
||||
eval(QString("(in-package :%1)").arg(QString(package)));
|
||||
eval(expression);
|
||||
}
|
||||
|
||||
void LQML::runOnUiThread(void* function_or_closure) {
|
||||
const cl_env_ptr l_env = ecl_process_env();
|
||||
CL_CATCH_ALL_BEGIN(l_env) {
|
||||
CL_UNWIND_PROTECT_BEGIN(l_env) {
|
||||
cl_object l_fun = (cl_object)function_or_closure;
|
||||
cl_funcall(1, l_fun);
|
||||
}
|
||||
CL_UNWIND_PROTECT_EXIT {}
|
||||
CL_UNWIND_PROTECT_END;
|
||||
}
|
||||
CL_CATCH_ALL_END;
|
||||
}
|
||||
|
||||
bool LQML::cl_booted_p = false;
|
||||
bool LQML::cl_shutdown_p = false;
|
||||
QEventLoop* LQML::eventLoop = 0;
|
||||
LQML* LQML::me = nullptr;
|
||||
QQuickView* LQML::quickView = nullptr;
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue