add internal function for fast, direct JS calls, see also 'qml-lisp.lisp' in QML examples

This commit is contained in:
polos 2021-03-08 18:53:52 +01:00
parent 322b737e7b
commit bfdc227b21
2 changed files with 67 additions and 0 deletions

View file

@ -145,6 +145,7 @@ void iniCLFunctions() {
DEFUN ("qfrom-utf8", qfrom_utf8, 1)
DEFUN ("qid", qid, 1)
DEFUN ("%qinvoke-method", qinvoke_method2, 4)
DEFUN ("qjs-call", qjs_call, 3)
DEFUN ("%qload-c++", qload_cpp, 2)
DEFUN ("qload-ui", qload_ui, 1)
DEFUN ("qlocal8bit", qlocal8bit, 1)
@ -962,6 +963,30 @@ static QVariantList toQVariantList(cl_object l_list) {
l_el = cl_cdr(l_el); }}
return l; }
static QVariantList lispToQVariantList(cl_object l_list) {
// converts (nested) Lisp lists to (nested) QVariant lists
QVariantList l;
if(LISTP(l_list)) {
cl_object l_do_list = l_list;
while(l_do_list != Cnil) {
cl_object l_el = cl_car(l_do_list);
if(cl_integerp(l_el) == ECL_T) { // int
l << QVariant(toInt(l_el)); }
else if(cl_floatp(l_el) == ECL_T) { // double
l << QVariant(toFloat<double>(l_el)); }
else if(cl_stringp(l_el) == ECL_T) { // string
l << QVariant(toQString(l_el)); }
else if(l_el == ECL_T) { // true
l << QVariant(true); }
else if(l_el == ECL_NIL) { // null
l << QVariant(); }
else if(LISTP(l_el)) { // list
l << QVariant::fromValue(lispToQVariantList(l_el)); }
else { // null
l << QVariant(); }
l_do_list = cl_cdr(l_do_list); }}
return l; }
static cl_object from_char(char ch) {
cl_object l_char = cl_code_char(MAKE_FIXNUM((int)ch));
return l_char; }
@ -3021,6 +3046,47 @@ cl_object qlog2(cl_object l_msg) {
qDebug() << toQString(l_msg);
return Cnil; }
cl_object qjs_call(cl_object l_item, cl_object l_name, cl_object l_args) {
// direct, fast JS calls, see 'qml-lisp' in QML examples
// max. 10 arguments
// supported argument types: T, NIL, INTEGER, FLOAT, STRING, (nested) LIST of mentioned arguments
ecl_process_env()->nvalues = 1;
QVariant arg[10];
QGenericArgument genA[10];
const char* v = "QVariant";
cl_object l_do_args = l_args;
int i = 0;
for(; l_do_args != Cnil; i++) {
cl_object l_arg = cl_car(l_do_args);
if(cl_integerp(l_arg) == ECL_T) { // int
arg[i] = QVariant(toInt(l_arg)); }
else if(cl_floatp(l_arg) == ECL_T) { // double
arg[i] = QVariant(toFloat<double>(l_arg)); }
else if(cl_stringp(l_arg) == ECL_T) { // string
arg[i] = QVariant(toQString(l_arg)); }
else if(l_arg == ECL_T) { // true
arg[i] = QVariant(true); }
else if(l_arg == ECL_NIL) { // null
arg[i] = QVariant(); }
else if(LISTP(l_arg)) { // list
arg[i] = QVariant::fromValue(lispToQVariantList(l_arg)); }
else { // default: null
arg[i] = QVariant(); }
genA[i] = QGenericArgument(v, &arg[i]);
l_do_args = cl_cdr(l_do_args); }
QGenericArgument null;
for(; i < 10; i++) {
genA[i] = null; }
QtObject o = toQtObject(l_item);
QVariant ret;
QGenericReturnArgument genR(v, &ret);
if(o.isQObject()) {
QMetaObject::invokeMethod((QObject*)o.pointer, toCString(l_name), genR,
genA[0], genA[1], genA[2], genA[3], genA[4], genA[5], genA[6], genA[7], genA[8], genA[9]);
return from_qvariant_value(ret); }
error_msg("QJS-CALL", LIST3(l_item, l_name, l_args));
return ECL_NIL; }
// *** special extensions ***

View file

@ -259,6 +259,7 @@ cl_object qfind_children2 (cl_object, cl_object, cl_object);
cl_object qfrom_utf8 (cl_object);
cl_object qid (cl_object);
cl_object qinvoke_method2 (cl_object, cl_object, cl_object, cl_object);
cl_object qjs_call (cl_object, cl_object, cl_object);
cl_object qload_cpp (cl_object, cl_object);
cl_object qload_ui (cl_object);
cl_object qlocal8bit (cl_object);