From bd0cd3ed1093022762ac37d7190482da0a534e35 Mon Sep 17 00:00:00 2001 From: "pls.153" Date: Sat, 14 Oct 2023 19:38:44 +0200 Subject: [PATCH] fix autom. conversion integer (Lisp) <-> hex string (JS) --- doc/help.htm | 8 +++---- src/cpp/lqml.cpp | 2 +- src/cpp/qml_ext.cpp | 56 ++++++++++++++------------------------------- src/lisp/qml.lisp | 18 ++++++++++----- 4 files changed, 33 insertions(+), 51 deletions(-) diff --git a/doc/help.htm b/doc/help.htm index 1583681..daa153b 100644 --- a/doc/help.htm +++ b/doc/help.htm @@ -56,13 +56,11 @@ automatically to hex strings, if (1) populating an item model, or (2) passed with function QJS. Those hex strings are automatically converted back to a 'qint64' integer when - passed with 'Lisp.call()'. - If the conversion to 'qint64' is not possible, the hex string is returned, - which can be passed to READ-FROM-STRING to get arbitrary integer length. + passed with 'Lisp.call()' or 'Lisp.apply()'. Important note: because of the automatic conversion of INTEGERs, you need to - explicitly add '(float x)' to values you don't want to be converted to hex - strings, like drawing a line in a QML Canvas. + explicitly add '(float x)' in Lisp to values you don't want to be converted + to hex strings, like drawing a line in a QML Canvas, or FIXNUM integers. mobile-p () diff --git a/src/cpp/lqml.cpp b/src/cpp/lqml.cpp index d2c2c34..4b2117d 100644 --- a/src/cpp/lqml.cpp +++ b/src/cpp/lqml.cpp @@ -7,7 +7,7 @@ #include #include -const char LQML::version[] = "23.10.2"; // October 2023 +const char LQML::version[] = "23.10.3"; // October 2023 extern "C" void ini_LQML(cl_object); diff --git a/src/cpp/qml_ext.cpp b/src/cpp/qml_ext.cpp index be6a4f5..b4a735c 100644 --- a/src/cpp/qml_ext.cpp +++ b/src/cpp/qml_ext.cpp @@ -13,28 +13,6 @@ static QVariant qmlApply(QObject* caller, QVariant(arguments)); } -static QVariant toVariant(const QJSValue& value) { - QVariant var = value.toVariant(); -#if QT_VERSION < 0x060000 - const int type = var.type(); -#else - const int type = var.typeId(); -#endif - if (type == QMetaType::QString) { - QString s(var.toString()); - // numbers passed with '(qml:hex number)' to QML (and stored there as - // strings) are automatically converted back to a number (qint64). - if (s.startsWith("#x")) { - bool ok; - qint64 num = s.mid(2).toLongLong(&ok, 16); - if (ok) { - return QVariant(num); - } - } - } - return var; -} - QVariant Lisp::call(const QJSValue& caller_or_function, const QJSValue& function_or_arg0, const QJSValue& arg1, @@ -62,41 +40,41 @@ QVariant Lisp::call(const QJSValue& caller_or_function, } else if (caller_or_function.isString()) { function = caller_or_function.toString(); if (!function_or_arg0.isUndefined()) { - arguments << toVariant(function_or_arg0); + arguments << function_or_arg0.toVariant(); } } if (!arg1.isUndefined()) { - arguments << toVariant(arg1); + arguments << arg1.toVariant(); if (!arg2.isUndefined()) { - arguments << toVariant(arg2); + arguments << arg2.toVariant(); if (!arg3.isUndefined()) { - arguments << toVariant(arg3); + arguments << arg3.toVariant(); if (!arg4.isUndefined()) { - arguments << toVariant(arg4); + arguments << arg4.toVariant(); if (!arg5.isUndefined()) { - arguments << toVariant(arg5); + arguments << arg5.toVariant(); if (!arg6.isUndefined()) { - arguments << toVariant(arg6); + arguments << arg6.toVariant(); if (!arg7.isUndefined()) { - arguments << toVariant(arg7); + arguments << arg7.toVariant(); if (!arg8.isUndefined()) { - arguments << toVariant(arg8); + arguments << arg8.toVariant(); if (!arg9.isUndefined()) { - arguments << toVariant(arg9); + arguments << arg9.toVariant(); if (!arg10.isUndefined()) { - arguments << toVariant(arg10); + arguments << arg10.toVariant(); if (!arg11.isUndefined()) { - arguments << toVariant(arg11); + arguments << arg11.toVariant(); if (!arg12.isUndefined()) { - arguments << toVariant(arg12); + arguments << arg12.toVariant(); if (!arg13.isUndefined()) { - arguments << toVariant(arg13); + arguments << arg13.toVariant(); if (!arg14.isUndefined()) { - arguments << toVariant(arg14); + arguments << arg14.toVariant(); if (!arg15.isUndefined()) { - arguments << toVariant(arg15); + arguments << arg15.toVariant(); if (!arg16.isUndefined()) { - arguments << toVariant(arg16); + arguments << arg16.toVariant(); } } } diff --git a/src/lisp/qml.lisp b/src/lisp/qml.lisp index ad458ee..c6b9327 100644 --- a/src/lisp/qml.lisp +++ b/src/lisp/qml.lisp @@ -21,13 +21,11 @@ automatically to hex strings, if (1) populating an item model, or (2) passed with function QJS. Those hex strings are automatically converted back to a 'qint64' integer when - passed with 'Lisp.call()'. - If the conversion to 'qint64' is not possible, the hex string is returned, - which can be passed to READ-FROM-STRING to get arbitrary integer length. + passed with 'Lisp.call()' or 'Lisp.apply()'. Important note: because of the automatic conversion of INTEGERs, you need to - explicitly add '(float x)' to values you don't want to be converted to hex - strings, like drawing a line in a QML Canvas." + explicitly add '(float x)' in Lisp to values you don't want to be converted + to hex strings, like drawing a line in a QML Canvas, or FIXNUM integers." (assert (integerp integer)) (let ((*print-base* 16)) (x:cc "#x" (princ-to-string integer)))) @@ -38,12 +36,20 @@ ;; Every 'Lisp.call()' or 'Lisp.apply()' function call in QML will call this ;: function. The variable *CALLER* will be bound to the calling QQuickItem, ;; if passed with 'this' as first argument to 'Lisp.call()' / 'Lisp.apply()'. + ;; Possible integers encoded as hex strings in JS (see function HEX above) + ;; are automatically converted back to integers. (let ((fun (string-to-symbol function)) (*caller* (if (zerop caller) *caller* (qt-object caller)))) (if (fboundp fun) - (apply fun arguments) + (apply fun (mapcar (lambda (arg) + (if (and (stringp arg) + (x:starts-with "#x" arg)) + (or (ignore-errors (read-from-string arg)) + arg) + arg)) + arguments)) (let ((msg (format nil "[LQML:error] Lisp.call(): ~S is undefined." function))) (when *break-on-errors* (break msg)