summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Zotti <Georg.Zotti@univie.ac.at>2022-08-11 01:34:58 +0200
committerGeorg Zotti <Georg.Zotti@univie.ac.at>2022-08-11 01:34:58 +0200
commit90b1f2f8a1a058710377a368224d63be2086f7b5 (patch)
tree17813f8c80f959e57d7fe0d1e6d1295d84f641d9
parent6c9559a42ac62e9af5be7f1881f1825e93e6f0c5 (diff)
Assimilate old and new scripting functionsscripting/JSEngine
- allows writing scripts for both engines. - not pretty, but works - added SUG notes
-rw-r--r--guide/ch_scripting.tex61
-rw-r--r--src/scripting/StelMainScriptAPI.cpp14
-rw-r--r--src/scripting/StelMainScriptAPI.hpp16
-rw-r--r--src/scripting/StelScriptMgr.cpp253
-rw-r--r--src/scripting/V3d.cpp4
-rw-r--r--src/scripting/V3d.hpp108
-rw-r--r--src/tests/testJavaScripting.cpp150
-rw-r--r--src/tests/testJavaScripting.hpp5
8 files changed, 334 insertions, 277 deletions
diff --git a/guide/ch_scripting.tex b/guide/ch_scripting.tex
index 22779c86d6..963581484d 100644
--- a/guide/ch_scripting.tex
+++ b/guide/ch_scripting.tex
@@ -50,7 +50,8 @@ yet another scripting engine in 2022. Qt6 comes with QJSEngine, another
JavaScript engine which behaves mostly similar to the older QtScript.
However, small differences exist, so that care must be taken if scripts
should be developed for both series of Stellarium. Some older scripts
-will not work on versions 1.0 and later or at least require some adaptations.
+will not work on versions 1.0 and later or at least require some adaptations
+described in section~\ref{sec:scripting:differences}.
% Section 2020-03-26 by Wolfgang Laun
\section{The Script Console}
@@ -144,7 +145,7 @@ LabelMgr.deleteLabel(label);
\section{Critical Scripting Differences introduced with version 1.0}
\label{sec:scripting:differences}
-Qt5's QtScript module which has been used in versions 0.10 to 0.22 was more flexible than Qt6's QJSEngine,
+Qt5's QtScript module which has been used in versions 0.10 to 0.22 was more flexible and easier to fine-tune than Qt6's QJSEngine,
which is used in the 1.* series of the program, i.e., versions 1.0 (22.3) and later.
Still, most scripts that have been developed for Stellarium versions 0.10 to 0.22
still run without or with just minor modifications as described in this section.
@@ -161,6 +162,55 @@ One of the most important little helper classes in the main program are three-di
\texttt{Vec3f} describe those with single-precision floating point data,
and \texttt{Vec3d} are those with double-precision floating point data.
+\begin{sidewaystable}
+{\ttfamily\scriptsize
+\begin{tabular}{rlll}
+ &Input & Result with Qt5 & Result with Qt6 \\\hline
+x&\textbf{var f1=new V3d(.1,.2,.3);} & & \\
+ &core.output(f1); & [0.1, 0.2, 0.3] & V3d(0x249a1cf37c0) [some address] \\
+ &core.output(+f1.toString()); & [0.1, 0.2, 0.3] & V3d(0x249a1cf37c0) [some address] \\
+x&\textbf{core.output(f1.toHex());} & \#19334c & \#19334c \\
+x&\textbf{core.output(f1.toVec3d());} & [0.1, 0.2, 0.3] & [0.1, 0.2, 0.3] \\\hline
+x&\textbf{var f2=new V3d(f1.x(), 2*f1.y(), 3*f1.z());} & & \\
+ &core.output(f2); & [0.1, 0.4, 0.9] & V3d(0x249a1cf3a60) [some address] \\
+x&\textbf{core.output(f2.toVec3d());} & [0.1, 0.4, 0.8999999999999999] & [0.1, 0.4, 0.9] \\\hline
+x&\textbf{var crimson=new Color("Crimson");} & & \\
+x&\textbf{core.output(crimson.toHex());} & \#dc143c & \#dc143c \\
+ &core.output(crimson.toVec3f()); & [r:0.8627451062202454, g:0.0784313753247261, b:0.23529411852359772] & [0.862745, 0.0784314, 0.235294] \\
+ &core.output(crimson.r); & 0.8627451062202454 & error \\
+ &core.output(crimson.r()); & error & 0.8627451062202454 \\
+x&\textbf{core.output(crimson.getR());} & 0.8627451062202454 & 0.8627451062202454 \\
+x&\textbf{core.output(crimson.getG());} & 0.0784313753247261 & 0.0784313753247261 \\
+x&\textbf{core.output(crimson.getB());} & 0.23529411852359772 & 0.23529411852359772 \\
+ &crimson.g=0.444; & (works) & (error) \\
+ &crimson.setG(0.444); & (error) & (works) \\
+x&\textbf{crimson=new Color(crimson.getR(), 0.444, crimson.getB());} & (reassign crimson; recommended for Qt5 and Qt6) & \\
+x&\textbf{core.output(crimson.toRGBString());} & [r:0.862745, g:0.444, b:0.235294] & [r:0.862745, g:0.444, b:0.235294] \\\hline
+
+x&\multicolumn{2}{l}{\textbf{var eq=new Color(GridLinesMgr.getColorEquatorJ2000Grid());}} & \\
+x&\textbf{core.output(eq.toHex());} & \#00aaff & \#00aaff \\
+ &core.output(eq.toVec3f()); & [r:0, g:0.6666669845581055, b:1] & [0, 0.666667, 1] \\
+ &core.output(eq.toVec3d()); & (n.a.) & [0, 0.666667, 1] \\
+ &core.output(eq.toString()); & [0, 0.666667, 1] & Color(0x24a11712910) [some address] \\
+x&\textbf{core.output(eq.toRGBString());} & [r:0, g:0.666667, b:1] & [r:0, g:0.666667, b:1] \\\hline
+
+x&\textbf{var c=new Color(core.vec3f(.3, .4, .5));} & & \\
+ &core.output(c.toString()); & [0.3, 0.4, 0.5] & Color(0x249a1e078b0) [some address] \\
+ &core.output(c.toVec3f()); & [r:0.30000001192092896, g:0.4000000059604645, b:0.5] & [0.3, 0.4, 0.5] \\
+x&\textbf{var d=c;} // assign to other & & \\
+ &core.output(d.toVec3f()); & [r:0.30000001192092896, g:0.4000000059604645, b:0.5] & [0.3, 0.4, 0.5] \\\hline
+x&\textbf{var c2=new Color(.3, .4, .5);} & & \\
+ &core.output(c2.toString()); & [0.3, 0.4, 0.5] & Color(0x24a11712a60) [some address] \\
+ &core.output(c2.toVec3f()); & [r:0.30000001192092896, g:0.4000000059604645, b:0.5] & [0.3, 0.4, 0.5] \\
+x&\textbf{var d2=c2;} // assign to other & & \\
+ &core.output(d2.toVec3f()); & [r:0.30000001192092896, g:0.4000000059604645, b:0.5] & [0.3, 0.4, 0.5]
+\end{tabular}}
+\caption{Use of V3d, V3f and Color wrapper classes. Only use the calls marked with \texttt{x} in scripts targeted at all versions of Stellarium.}
+\label{tab:scripting:Vec3f}
+\end{sidewaystable}
+
+
+
As late as in version 0.19 we added \texttt{Vec3f} and later \texttt{Vec3d} data types to the Javascript environment.
These allowed addressing variables of C++ classes \texttt{Vec3f} or \texttt{Vec3d} with named sub-fields \texttt{r}, \texttt{g}, \texttt{b}
(if used to describe colors), or \texttt{x}, \texttt{y}, \texttt{z} (same data but contextually understood as 3D data).
@@ -169,15 +219,16 @@ Stellarium (series 0.*, now usually found on 32-bit systems), but we recommend t
Qt6's scripting module cannot be extended that easily. The \texttt{Vec3d} and \texttt{Vec3f} data types are not directly scriptable,
but we can deal with method arguments of these types when they are mentioned in the API documentation (see \ref{sec:scripting:introduction}).
-To access internals of these classes, we must use helper classes which bear different names:
+To access internals of these classes, we must use wrapper classes which bear different names:
\begin{description}
\item[\texttt{V3d}] can be used where \texttt{Vec3d} must be accessed.
\item[\texttt{V3f}] can be used where \texttt{Vec3f} must be accessed.
\item[\texttt{Color}] can be used where a \texttt{Vec3f} must be accessed which represents a color value.
\end{description}
-% TODO: ADD DETAILS
-
+They behave slightly different when run using Qt5 or Qt6, as shown in Table~\ref{tab:scripting:Vec3f}. If you aim for maximum compatibility between versions,
+only use the calls which provide equal results in both series. This current state is far from optimal or even pretty, but a pragmatic solution that works.
+We invite advanced developers to find a better solution that works with both Qt5 and Qt6.
\section{Example: Retrograde motion of Mars}
diff --git a/src/scripting/StelMainScriptAPI.cpp b/src/scripting/StelMainScriptAPI.cpp
index 2f7c91be44..ce5a5b4854 100644
--- a/src/scripting/StelMainScriptAPI.cpp
+++ b/src/scripting/StelMainScriptAPI.cpp
@@ -104,7 +104,9 @@ StelMainScriptAPI::StelMainScriptAPI(QObject *parent) : QObject(parent)
connect(this, SIGNAL(requestSetDiskViewport(bool)), StelApp::getInstance().getMainScriptAPIProxy(), SLOT(setDiskViewport(bool)));
connect(this, SIGNAL(requestSetHomePosition()), StelApp::getInstance().getCore(), SLOT(returnToHome()));
- QMetaType::registerConverter(&V3d::toString);
+ //QMetaType::registerConverter<V3d,QString>(&V3d::toString);
+ //QMetaType::registerConverter<V3f,QString>(&V3f::toString);
+ //QMetaType::registerConverter<Color,QString>(&Color::toString);
}
StelMainScriptAPI::~StelMainScriptAPI()
@@ -121,11 +123,11 @@ Vec3f StelMainScriptAPI::vec3f(const float x, const float y, const float z)
return Vec3f(x, y, z);
}
-Vec3f StelMainScriptAPI::vec3f(const QString &cstr){return color(cstr);}
-
-Vec3f StelMainScriptAPI::color(const QString &cstr)
+//Col StelMainScriptAPI::vec3f(const QString &cstr){return color(cstr);}
+#ifdef ENABLE_SCRIPT_QML
+Color StelMainScriptAPI::color(const QString &cstr)
{
- Vec3f res(0,0,0);
+ Color res(0,0,0);
QColor qcol = QColor(cstr);
if(qcol.isValid())
@@ -134,7 +136,7 @@ Vec3f StelMainScriptAPI::color(const QString &cstr)
qWarning() << "Color: invalid color name: " << cstr;
return res;
}
-
+#endif
//V3d StelMainScriptAPI::toV3d(const Vec3d &vec)
//{
// return V3d(vec);
diff --git a/src/scripting/StelMainScriptAPI.hpp b/src/scripting/StelMainScriptAPI.hpp
index 342472fd64..7653a0db53 100644
--- a/src/scripting/StelMainScriptAPI.hpp
+++ b/src/scripting/StelMainScriptAPI.hpp
@@ -71,21 +71,15 @@ public slots:
//! @endcode
static Vec3f vec3f(const float x, const float y, const float z);
- //! @returns Vec3f object from a color hexstring or even color name definition.
+#ifdef ENABLE_SCRIPT_QML
+ //! @returns Color object from a color hexstring or even color name definition.
//! @code
//! var crimson=core.color("Crimson");
//! var red=core.color("#ff0000");
//! @endcode
- static Vec3f vec3f(const QString &cstr);
- //! alias for vec3f(cstr)
- static Vec3f color(const QString &cstr);
-
- // Seems not to work properly! Use
- // @code
- // var my=new V3d(vec);
- // @endcode
- // instead.
- //static V3d toV3d(const Vec3d &vec); // should allow a conversion from that magic type
+ //! almost an alias for vec3f(cstr)
+ static Color color(const QString &cstr);
+#endif
//! Returns true if the script is running on the older, Qt5-based QtScript JavaScript engine.
//! Note that it is possible to build Stellarium on Qt5.14 and later also with the newer scripting engine.
diff --git a/src/scripting/StelScriptMgr.cpp b/src/scripting/StelScriptMgr.cpp
index c7e2bde567..3ab9418b35 100644
--- a/src/scripting/StelScriptMgr.cpp
+++ b/src/scripting/StelScriptMgr.cpp
@@ -62,136 +62,26 @@ void StelScriptMgr::defVecClasses(QJSEngine *engine)
qDebug() << "defVecClasses() not yet complete";
qRegisterMetaType<V3d>();
-
+ QMetaType::registerConverter<V3d,QString>(&V3d::toString);
QMetaType::registerConverter<V3d, Vec3d>(&V3d::toVec3d);
- QMetaType::registerConverter<Vec3d, V3d>(&V3d::fromVec3d);
-
+ //QMetaType::registerConverter<Vec3d, V3d>(&V3d::fromVec3d);
QJSValue v3dMetaObject = engine->newQMetaObject(&V3d::staticMetaObject);
engine->globalObject().setProperty("V3d", v3dMetaObject);
- /*
- // Allow Vec3f management in scripts
- qRegisterMetaType(engine, vec3fToScriptValue, vec3fFromScriptValue);
- QJSValue ctorVec3f = engine->newFunction(createVec3f);
- engine->globalObject().setProperty("Vec3f", ctorVec3f);
- engine->globalObject().setProperty("Color", engine->newFunction(createColor));
-
- // Allow Vec3d management in scripts
- qScriptRegisterMetaType(engine, vec3dToScriptValue, vec3dFromScriptValue);
- QScriptValue ctorVec3d = engine->newFunction(createVec3d);
- engine->globalObject().setProperty("Vec3d", ctorVec3d);
- */
-}
-
-// 3f - 3f - 3f - 3f - 3f - 3f - 3f - 3f - 3f - 3f - 3f - 3f - 3f - 3f
-
-/***
-The C++ type Vec3f is an array of three floats, used for representing
-colors according to the terms of the RGB color model. It is mapped to
-a JavaScript class with a constructor Vec3f, properties 'r', 'g' and 'b',
-and methods toString and toHex. The latter returns a string according to
-the pattern '#hhhhhh' (six hexadecimal digits). A second constructor,
-Color, is provided as a convenience. Both constructors may be called without
-argument to return 'white', a single argument which is either a color name
-or a '#hhhhhh' string, or three arguments, specifying the RGB values,
-floating point numbers between 0 and 1. Color names correspond to the names
-defined in https://www.w3.org/TR/SVG11/types.htm.
-***/
-
-/*
-// GZ These seem not to be portable to QJSEngine use
-// GZ Maybe we don't even need to port these functions given QVariant uses. Let's try.
-
-
-QJSValue vec3fToHex(QJSContext* context, QJSEngine *engine)
-{
- Q_UNUSED(engine)
- QJSValue that = context->thisObject();
- QJSValue rVal = that.property( "r", QScriptValue::ResolveLocal );
- QJSValue gVal = that.property( "g", QScriptValue::ResolveLocal );
- QJSValue bVal = that.property( "b", QScriptValue::ResolveLocal );
- return QString("#%1%2%3")
- .arg(qMin(255, int(rVal.toNumber() * 255)), 2, 16, QChar('0'))
- .arg(qMin(255, int(gVal.toNumber() * 255)), 2, 16, QChar('0'))
- .arg(qMin(255, int(bVal.toNumber() * 255)), 2, 16, QChar('0'));
-}
-
-void vec3fFromScriptValue(const QJSValue& obj, Vec3f& c)
-{
- c[0] = static_cast<float>(obj.property("r").toNumber());
- c[1] = static_cast<float>(obj.property("g").toNumber());
- c[2] = static_cast<float>(obj.property("b").toNumber());
-}
-
-QJSValue vec3fToScriptValue(QJSEngine *engine, const Vec3f& c)
-{
- QJSValue obj = engine->newObject();
- obj.setProperty("r", QJSValue(static_cast<qreal>(c[0])));
- obj.setProperty("g", QJSValue(static_cast<qreal>(c[1])));
- obj.setProperty("b", QJSValue(static_cast<qreal>(c[2])));
- obj.setProperty("toString", engine->newFunction( vec3fToString ));
- obj.setProperty("toHex", engine->newFunction( vec3fToHex ));
- return obj;
-}
-
-// Constructor Vec3f
-// Three arguments are r, g, b. One argument is "#hhhhhh", or, perhaps, a color name.
-QJSValue createVec3f(QJSContext* context, QJSEngine *engine)
-{
- Vec3f c;
- switch( context->argumentCount() )
- {
- case 0:
- // no color: black or white? Let's say: white, against a black sky.
- c.set( 1, 1, 1 );
- break;
- case 1:
- // either '#hhhhhh' or a color name - let QColor do the work
- if( context->argument(0).isString() )
- {
- QColor qcol = QColor( context->argument(0).toString() );
- if( qcol.isValid() )
- {
- c.set( static_cast<float>(qcol.redF()), static_cast<float>(qcol.greenF()), static_cast<float>(qcol.blueF()) );
- break;
- }
- else
- context->throwError( QString("Color: invalid color name") );
- }
- else
- {
- // Let's hope: a Color/Vec3f object
- return context->argument(0);
- }
- break;
- case 3:
- // r, g, b: between 0 and 1.
- if( context->argument(0).isNumber() &&
- context->argument(1).isNumber() &&
- context->argument(2).isNumber() )
- {
- c[0] = static_cast<float>(context->argument(0).toNumber());
- c[1] = static_cast<float>(context->argument(1).toNumber());
- c[2] = static_cast<float>(context->argument(2).toNumber());
- if( c[0] < 0 || 1 < c[0] ||
- c[1] < 0 || 1 < c[1] ||
- c[2] < 0 || 1 < c[2] )
- {
- context->throwError( QString("Color: RGB value out of range [0,1]") );
- }
- }
- break;
- default:
- context->throwError( QString("Color: invalid number of arguments") );
- }
- return vec3fToScriptValue(engine, c);
-}
-
-QJSValue createColor(QScriptContext* context, QScriptEngine *engine)
-{
- return engine->globalObject().property("Vec3f").construct(context->argumentsObject());
+ qRegisterMetaType<V3f>();
+ QMetaType::registerConverter<V3f,QString>(&V3f::toString);
+ QMetaType::registerConverter<V3f, Vec3f>(&V3f::toVec3f);
+ //QMetaType::registerConverter<Vec3f, V3f>(&V3f::fromVec3f);
+ QJSValue v3fMetaObject = engine->newQMetaObject(&V3f::staticMetaObject);
+ engine->globalObject().setProperty("V3f", v3fMetaObject);
+
+ qRegisterMetaType<Color>();
+ QMetaType::registerConverter<Color,QString>(&Color::toRGBString);
+ QMetaType::registerConverter<Color, Vec3f>(&Color::toVec3f);
+ //QMetaType::registerConverter<Vec3f, Color>(&Color::fromVec3f);
+ QJSValue colorMetaObject = engine->newQMetaObject(&Color::staticMetaObject);
+ engine->globalObject().setProperty("Color", colorMetaObject);
}
-*/
#else
#include <QtScript>
@@ -213,9 +103,8 @@ This functionality is however deprecated. We strongly advise not to use it in sc
Scripts using it will only work on Qt5-based builds of Stellarium (series 0.*)
***/
-QScriptValue vec3fToString(QScriptContext* context, QScriptEngine *engine)
+static QScriptValue vec3fToString(QScriptContext* context, QScriptEngine *engine)
{
- qWarning() << "The Vec3f script object is deprecated and will not work in future versions of Stellarium. Use V3d.";
Q_UNUSED(engine)
QScriptValue that = context->thisObject();
QScriptValue rVal = that.property( "r", QScriptValue::ResolveLocal );
@@ -225,9 +114,8 @@ QScriptValue vec3fToString(QScriptContext* context, QScriptEngine *engine)
"b:" + bVal.toString() + "]";
}
-QScriptValue vec3fToHex(QScriptContext* context, QScriptEngine *engine)
+static QScriptValue vec3fToHex(QScriptContext* context, QScriptEngine *engine)
{
- qWarning() << "The Vec3f script object is deprecated and will not work in future versions of Stellarium. Use V3d.toHex()";
Q_UNUSED(engine)
QScriptValue that = context->thisObject();
QScriptValue rVal = that.property( "r", QScriptValue::ResolveLocal );
@@ -239,31 +127,99 @@ QScriptValue vec3fToHex(QScriptContext* context, QScriptEngine *engine)
.arg(qMin(255, int(bVal.toNumber() * 255)), 2, 16, QChar('0'));
}
-void vec3fFromScriptValue(const QScriptValue& obj, Vec3f& c)
+// This just ensures that Color.toVec3f does nothing in Qt5/QtScript
+static QScriptValue vec3fNop(QScriptContext* context, QScriptEngine *engine)
+{
+ Q_UNUSED(engine)
+ return context->thisObject();
+}
+
+static QScriptValue vec3fGetR(QScriptContext* context, QScriptEngine *engine)
+{
+ Q_UNUSED(engine)
+ QScriptValue that = context->thisObject();
+ QScriptValue rVal = that.property( "r", QScriptValue::ResolveLocal );
+ return rVal;
+}
+
+static QScriptValue vec3fGetG(QScriptContext* context, QScriptEngine *engine)
+{
+ Q_UNUSED(engine)
+ QScriptValue that = context->thisObject();
+ QScriptValue rVal = that.property( "g", QScriptValue::ResolveLocal );
+ return rVal;
+}
+
+static QScriptValue vec3fGetB(QScriptContext* context, QScriptEngine *engine)
+{
+ Q_UNUSED(engine)
+ QScriptValue that = context->thisObject();
+ QScriptValue rVal = that.property( "b", QScriptValue::ResolveLocal );
+ return rVal;
+}
+
+// This does not work.
+static QScriptValue vec3fSetR(QScriptContext* context, QScriptEngine *engine)
+{
+ Q_UNUSED(engine)
+ qDebug() << "setR() does not work. Create a new Color.";
+ QScriptValue callee = context->callee();
+ if (context->argumentCount() == 1) // writing?
+ callee.setProperty("r", context->argument(0));
+ return callee.property("r");
+}
+// This does not work.
+static QScriptValue vec3fSetG(QScriptContext* context, QScriptEngine *engine)
+{
+ qDebug() << "setG() does not work. Create a new Color.";
+ //qDebug() << "setG called. argcount=" << context->argumentCount() << "value=" << context->argument(0).toNumber();
+ //Q_UNUSED(engine)
+ QScriptValue callee = context->callee();
+ if (context->argumentCount() == 1) // writing?
+ callee.setProperty("g", QScriptValue(engine, static_cast<qsreal>(context->argument(0).toNumber())));
+ return callee.property("g");
+}
+// This does not work.
+static QScriptValue vec3fSetB(QScriptContext* context, QScriptEngine *engine)
+{
+ Q_UNUSED(engine)
+ qDebug() << "setB() does not work. Create a new Color.";
+ QScriptValue callee = context->callee();
+ if (context->argumentCount() == 1) // writing?
+ callee.setProperty("b", context->argument(0));
+ return callee.property("b");
+}
+
+static void vec3fFromScriptValue(const QScriptValue& obj, Vec3f& c)
{
- qWarning() << "The Vec3f script object is deprecated and will not work in future versions of Stellarium. Use V3d.";
c[0] = static_cast<float>(obj.property("r").toNumber());
c[1] = static_cast<float>(obj.property("g").toNumber());
c[2] = static_cast<float>(obj.property("b").toNumber());
}
-QScriptValue vec3fToScriptValue(QScriptEngine *engine, const Vec3f& c)
+static QScriptValue vec3fToScriptValue(QScriptEngine *engine, const Vec3f& c)
{
- qWarning() << "The Vec3f script object is deprecated and will not work in future versions of Stellarium. Use V3d.";
QScriptValue obj = engine->newObject();
obj.setProperty("r", QScriptValue(engine, static_cast<qsreal>(c[0])));
obj.setProperty("g", QScriptValue(engine, static_cast<qsreal>(c[1])));
obj.setProperty("b", QScriptValue(engine, static_cast<qsreal>(c[2])));
obj.setProperty("toString", engine->newFunction( vec3fToString ));
+ obj.setProperty("toRGBString", engine->newFunction( vec3fToString )); // alias, compatibility to Qt6 scripting
obj.setProperty("toHex", engine->newFunction( vec3fToHex ));
+ obj.setProperty("toVec3f", engine->newFunction( vec3fNop )); // do nothing. Useful for a Color object. Compatibility for Qt6 scripting.
+ obj.setProperty("getR", engine->newFunction( vec3fGetR ));
+ obj.setProperty("getG", engine->newFunction( vec3fGetG ));
+ obj.setProperty("getB", engine->newFunction( vec3fGetB ));
+ obj.setProperty("setR", engine->newFunction( vec3fSetR, 1 )); // does nothing but emits a warning.
+ obj.setProperty("setG", engine->newFunction( vec3fSetG, 1 )); // does nothing but emits a warning.
+ obj.setProperty("setB", engine->newFunction( vec3fSetB, 1 )); // does nothing but emits a warning.
return obj;
}
// Constructor Vec3f
// Three arguments are r, g, b. One argument is "#hhhhhh", or, perhaps, a color name.
-QScriptValue createVec3f(QScriptContext* context, QScriptEngine *engine)
+static QScriptValue createVec3f(QScriptContext* context, QScriptEngine *engine)
{
- qWarning() << "The Vec3f script object is deprecated and will not work in future versions of Stellarium. Use core.vec3f()";
Vec3f c;
switch( context->argumentCount() )
{
@@ -313,9 +269,8 @@ QScriptValue createVec3f(QScriptContext* context, QScriptEngine *engine)
return vec3fToScriptValue(engine, c);
}
-QScriptValue createColor(QScriptContext* context, QScriptEngine *engine)
+static QScriptValue createColor(QScriptContext* context, QScriptEngine *engine)
{
- qWarning() << "The Color script object is deprecated and will not work in future versions of Stellarium. Use core.color()";
return engine->globalObject().property("Vec3f").construct(context->argumentsObject());
}
@@ -487,16 +442,21 @@ void StelScriptMgr::defVecClasses(QScriptEngine *engine)
QScriptValue ctorVec3d = engine->newFunction(createVec3d);
engine->globalObject().setProperty("Vec3d", ctorVec3d);
- // Configure replacement types so that new scripts should work also with the old engine.
- qRegisterMetaType<V3d>();
- //qScriptRegisterMetaType(engine, v3dtoScriptValue, v3dFromScriptValue);
+ // Configure the new replacement types so that new scripts should work also with the old engine.
+ qRegisterMetaType<V3d>();
+ QMetaType::registerConverter<V3d,QString>(&V3d::toString);
QMetaType::registerConverter<V3d, Vec3d>(&V3d::toVec3d);
- QMetaType::registerConverter<Vec3d, V3d>(&V3d::fromVec3d);
-
+ //QMetaType::registerConverter<Vec3d, V3d>(&V3d::fromVec3d);
QScriptValue v3dMetaObject = engine->newQMetaObject(&V3d::staticMetaObject);
engine->globalObject().setProperty("V3d", v3dMetaObject);
+ qRegisterMetaType<V3f>();
+ QMetaType::registerConverter<V3f,QString>(&V3f::toString);
+ QMetaType::registerConverter<V3f, Vec3f>(&V3f::toVec3f);
+ //QMetaType::registerConverter<Vec3f, V3f>(&V3f::fromVec3f);
+ QScriptValue v3fMetaObject = engine->newQMetaObject(&V3f::staticMetaObject);
+ engine->globalObject().setProperty("V3f", v3fMetaObject);
}
#endif
@@ -505,7 +465,7 @@ StelScriptMgr::StelScriptMgr(QObject *parent): QObject(parent)
waitEventLoop = new QEventLoop();
#ifdef ENABLE_SCRIPT_QML
engine = new QJSEngine(this);
- engine->installExtensions(QJSEngine::ConsoleExtension); // TODO: Maybe remove as unusable for us.
+ engine->installExtensions(QJSEngine::ConsoleExtension); // TBD: Maybe remove as unnecessary for us?
#else
engine = new QScriptEngine(this);
// This is enough for a simple Array access for a QVector<int> input or return type (e.g. Calendars plugin)
@@ -518,7 +478,7 @@ StelScriptMgr::StelScriptMgr(QObject *parent): QObject(parent)
scriptImages->init();
StelApp::getInstance().getModuleMgr().registerModule(scriptImages);
- defVecClasses(engine); // FIXME -- HELPME!
+ defVecClasses(engine); // Install handling of Vec3d[deprecated]/Vec3f[deprecated]/V3d/V3f/Color classes
// Add the core object to access methods related to core
mainAPI = new StelMainScriptAPI(this);
@@ -530,11 +490,6 @@ StelScriptMgr::StelScriptMgr(QObject *parent): QObject(parent)
#endif
engine->globalObject().setProperty("core", objectValue);
- // Make a global V3d object available for calling its static methods.
- V3d *v3dGlobal=new V3d();
- objectValue = engine->newQObject(v3dGlobal);
- engine->globalObject().setProperty("V3dfactory", objectValue);
-
// Add other classes which we want to be directly accessible from scripts
if(StelSkyLayerMgr* smgr = GETSTELMODULE(StelSkyLayerMgr))
objectValue = engine->newQObject(smgr);
diff --git a/src/scripting/V3d.cpp b/src/scripting/V3d.cpp
index f6e0fec248..01296e153b 100644
--- a/src/scripting/V3d.cpp
+++ b/src/scripting/V3d.cpp
@@ -24,7 +24,6 @@
#include <cmath>
-
V3d::V3d(const V3d &other) : QObject() // copy constructor
{
m_x=other.x();
@@ -65,6 +64,8 @@ V3f & V3f::operator =(const V3f &v)
}
///////////////////////
+#ifdef ENABLE_SCRIPT_QML
+
Color::Color(const Color &other) : QObject() // copy constructor
{
m_r=other.r();
@@ -103,3 +104,4 @@ QString Color::toHex() const
.arg(qMin(255, int(m_g * 255)), 2, 16, QChar('0'))
.arg(qMin(255, int(m_b * 255)), 2, 16, QChar('0'));
}
+#endif
diff --git a/src/scripting/V3d.hpp b/src/scripting/V3d.hpp
index c13f565916..c786bb99ac 100644
--- a/src/scripting/V3d.hpp
+++ b/src/scripting/V3d.hpp
@@ -42,12 +42,11 @@ class V3d: public QObject
{
Q_OBJECT
public:
- V3d() = default; // TODO: Make sure this (only) initializes m_x=m_y=m_z=0;
- V3d(const V3d &other); // copy constructor
+ Q_INVOKABLE V3d(): QObject(), m_x(0), m_y(0), m_z(0){};
+ Q_INVOKABLE V3d(const V3d &other); // copy constructor
V3d & operator =(const V3d &v);
//! The usual constructor to create a 3-dimensional vector that can be manipulated in JavaScript
Q_INVOKABLE V3d(const double x, const double y, const double z): QObject(), m_x(x), m_y(y), m_z(z){};
- //Q_INVOKABLE V3d(QString &hexColor);
//! Create a 3-dimensional vector from a Vec3d that can later be manipulated in JavaScript, e.g.
//! @code
//! myVec3d=new V3d(StelMovementMgr.getViewDirectionJ2000());
@@ -55,45 +54,33 @@ public:
Q_INVOKABLE V3d(const Vec3d &vec): QObject(), m_x(vec[0]), m_y(vec[1]), m_z(vec[2]){};
public slots:
- Q_INVOKABLE static V3d fromVec3d(const Vec3d &vec){return V3d(vec[0], vec[1], vec[2]);}
- Q_INVOKABLE static V3d fromVec3f(const Vec3f &vec){return V3d(double(vec[0]), double(vec[1]), double(vec[2]));}
//! @return a Vec3d object which is not directly accessible by scripts but can be used as arguments to other calls.
Q_INVOKABLE Vec3d toVec3d() const {return Vec3d(m_x, m_y, m_z);}
//! @return a Vec3f object which is not directly accessible by scripts but can be used as arguments to other calls.
Q_INVOKABLE Vec3f toVec3f() const {return Vec3f(float(m_x), float(m_y), float(m_z));}
- //! @return the R or X component
- Q_INVOKABLE double r() const {return m_x;}
- //! @return the G or Y component
- Q_INVOKABLE double g() const {return m_y;}
- //! @return the B or Z component
- Q_INVOKABLE double b() const {return m_z;}
- //! @return the R or X component
+ //! @return the X component
Q_INVOKABLE double x() const {return m_x;}
- //! @return the G or Y component
+ //! @return the Y component
Q_INVOKABLE double y() const {return m_y;}
- //! @return the B or Z component
+ //! @return the Z component
Q_INVOKABLE double z() const {return m_z;}
- //! Sets the R or X component
- Q_INVOKABLE void setR(double r) {m_x = r;}
- //! Sets the G or Y component
- Q_INVOKABLE void setG(double g) {m_y = g;}
- //! Sets the B or Z component
- Q_INVOKABLE void setB(double b) {m_z = b;}
- //! Sets the R or X component
+ //! Sets the components
+ Q_INVOKABLE void set(const double x, const double y, const double z) {m_x = x; m_y = y; m_z = z;}
+ //! Sets the X component
Q_INVOKABLE void setX(double x) {m_x = x;}
- //! Sets the G or Y component
+ //! Sets the Y component
Q_INVOKABLE void setY(double y) {m_y = y;}
- //! Sets the B or Z component
+ //! Sets the Z component
Q_INVOKABLE void setZ(double z) {m_z = z;}
//! Formats a comma-separated string in angle brackets
- Q_INVOKABLE inline QString toString() const {return QString("[%1, %2, %3]").arg(m_x).arg(m_y).arg(m_z);}
- //! Formats a comma-separated string of named rgb components in angle brackets
- Q_INVOKABLE inline QString toRGBString() const {return QString("[r:%1, g:%2, b:%3]").arg(m_x).arg(m_y).arg(m_z);}
- //! Formats a comma-separated string in angle brackets
+ //! @todo currently this seems to to nothing. JS print output shows "V3d(address)". Use toVec3d() to show the values formatted by Vec3d's method.
+ Q_INVOKABLE QString toString() const {return QString("[%1, %2, %3]").arg(m_x).arg(m_y).arg(m_z);}
+ //! Formats a hex string
Q_INVOKABLE QString toHex() const;
private:
double m_x, m_y, m_z;
};
+Q_DECLARE_METATYPE(V3d)
//! V3f is a glue class to allow some interaction between Vec3f and the scripting system.
//! Vec3f is not scriptable with the QJSEngine, but this intermediate V3f allows calling slots
@@ -103,8 +90,8 @@ class V3f: public QObject
{
Q_OBJECT
public:
- V3f() = default; // TODO: Make sure this (only) initializes m_x=m_y=m_z=0;
- V3f(const V3f &other); // copy constructor
+ Q_INVOKABLE V3f(): QObject(), m_x(0), m_y(0), m_z(0){};
+ Q_INVOKABLE V3f(const V3f &other); // copy constructor
V3f & operator =(const V3f &v);
//! The usual constructor to create a 3-dimensional vector that can be manipulated in JavaScript
Q_INVOKABLE V3f(const float x, const float y, const float z): QObject(), m_x(x), m_y(y), m_z(z){};
@@ -115,31 +102,34 @@ public:
Q_INVOKABLE V3f(const Vec3f &vec): QObject(), m_x(vec[0]), m_y(vec[1]), m_z(vec[2]){};
public slots:
- Q_INVOKABLE static V3f fromVec3f(const Vec3f &vec){return V3f(vec[0], vec[1], vec[2]);}
- //! @return a Vec3d object which is not directly accessible by scripts but can be used as arguments to other calls.
- Q_INVOKABLE Vec3d toVec3f() const {return Vec3d(m_x, m_y, m_z);}
+ Q_INVOKABLE Vec3d toVec3d() const {return Vec3d(double(m_x), double(m_y), double(m_z));}
//! @return a Vec3f object which is not directly accessible by scripts but can be used as arguments to other calls.
- Q_INVOKABLE Vec3f toVec3d() const {return Vec3f(double(m_x), double(m_y), double(m_z));}
+ Q_INVOKABLE Vec3f toVec3f() const {return Vec3f(m_x, m_y, m_z);}
//! @return the X component
- Q_INVOKABLE double x() const {return m_x;}
+ Q_INVOKABLE float x() const {return m_x;}
//! @return the Y component
- Q_INVOKABLE double y() const {return m_y;}
+ Q_INVOKABLE float y() const {return m_y;}
//! @return the Z component
- Q_INVOKABLE double z() const {return m_z;}
+ Q_INVOKABLE float z() const {return m_z;}
+ //! Sets the components
+ Q_INVOKABLE void set(const float x, const float y, const float z) {m_x = x; m_y = y; m_z = z;}
//! Sets the X component
- Q_INVOKABLE void setX(double x) {m_x = x;}
+ Q_INVOKABLE void setX(float x) {m_x = x;}
//! Sets the Y component
- Q_INVOKABLE void setY(double y) {m_y = y;}
+ Q_INVOKABLE void setY(float y) {m_y = y;}
//! Sets the Z component
- Q_INVOKABLE void setZ(double z) {m_z = z;}
+ Q_INVOKABLE void setZ(float z) {m_z = z;}
//! Formats a comma-separated string in angle brackets
- Q_INVOKABLE inline QString toString() const {return QString("[%1, %2, %3]").arg(m_x).arg(m_y).arg(m_z);}
+ //! @todo currently this seems to to nothing. JS print output shows "V3f(address)". Use toVec3f() to show the values formatted by Vec3f's method.
+ Q_INVOKABLE QString toString() const {return QString("[%1, %2, %3]").arg(m_x).arg(m_y).arg(m_z);}
private:
float m_x, m_y, m_z;
};
+Q_DECLARE_METATYPE(V3f)
-//! Similar to the direct use of Vec3f in the older (QtScript-based) solution of Stellarium 0.19-0.22, a class similar to V3f can be used for RGB colors.
-//! You can initialize it with a string that encodes HTML color (e.g., "#aaff33")
+#ifdef ENABLE_SCRIPT_QML
+//! In reminiscence of the direct use of Vec3f with a color aspect in the older (QtScript-based) solution of Stellarium 0.19-0.22,
+//! a dedicated class similar to V3f can be used for RGB colors. You can initialize it with 3 components, a Vec3f or a string that encodes HTML color (e.g., "#aaff33")
//!
//! @todo This class would probably not be required if QVector3D or self-made classes that don't derive from QObject could be made scriptable
//! like in the old QtScript module. See https://forum.qt.io/topic/24368/custom-c-types-and-qjsengine for a very early discussion.
@@ -148,43 +138,57 @@ class Color: public QObject
{
Q_OBJECT
public:
- Color() = default; // TODO: Make sure this (only) initializes m_x=m_y=m_z=0;
- Color(const Color &other); // copy constructor
+ Q_INVOKABLE Color(): QObject(), m_r(1), m_g(1), m_b(1){}; // default color is white, like in the old solution
+ Q_INVOKABLE Color(const Color &other); // copy constructor
Color & operator =(const Color &v);
//! The usual constructor to create a 3-dimensional vector that can be manipulated in JavaScript
Q_INVOKABLE Color(const double x, const double y, const double z): QObject(), m_r(x), m_g(y), m_b(z){};
Q_INVOKABLE Color(QString &hexColor);
- // Does not work - ambiguous!
- //Q_INVOKABLE Color(const Vec3f &vec): QObject(), m_r(vec[0]), m_g(vec[1]), m_b(vec[2]){};
+ Q_INVOKABLE Color(const Vec3f &vec): QObject(), m_r(vec[0]), m_g(vec[1]), m_b(vec[2]){};
public slots:
- Q_INVOKABLE static Color fromVec3d(const Vec3d &vec){return Color(vec[0], vec[1], vec[2]);}
- Q_INVOKABLE static Color fromVec3f(const Vec3f &vec){return Color(double(vec[0]), double(vec[1]), double(vec[2]));}
//! @return a Vec3d object which is not directly accessible by scripts but can be used as arguments to other calls.
+ //! @note only available on the Qt6 side of scripting.
Q_INVOKABLE Vec3d toVec3d() const {return Vec3d(m_r, m_g, m_b);}
//! @return a Vec3f object which is not directly accessible by scripts but can be used as arguments to other calls.
Q_INVOKABLE Vec3f toVec3f() const {return Vec3f(float(m_r), float(m_g), float(m_b));}
//! @return the R component
+ //! preferred, as similar syntax is available on Qt5.
+ Q_INVOKABLE double getR() const {return m_r;}
+ //! @note This is only available with scripting on Qt6. For Qt5, color.r (without brackets) does the same.
Q_INVOKABLE double r() const {return m_r;}
//! @return the G component
+ //! preferred, as similar syntax is available on Qt5.
+ Q_INVOKABLE double getG() const {return m_g;}
+ //! @note This is only available with scripting on Qt6. For Qt5, color.g (without brackets) does the same.
Q_INVOKABLE double g() const {return m_g;}
//! @return the B component
+ //! preferred, as similar syntax is available on Qt5.
+ Q_INVOKABLE double getB() const {return m_b;}
+ //! @note This is only available with scripting on Qt6. For Qt5, color.b (without brackets) does the same.
Q_INVOKABLE double b() const {return m_b;}
+ //! Sets the components
+ Q_INVOKABLE void set(const double r, const double g, const double b) {m_r = r; m_g = g; m_b = b;}
//! Sets the R component
+ //! @note Thiy syntax only available on Qt6-based versions. Use Color.r=<value> in Qt5-based scripts.
Q_INVOKABLE void setR(double r) {m_r = r;}
//! Sets the G component
+ //! @note Thiy syntax only available on Qt6-based versions. Use Color.g=<value> in Qt5-based scripts.
Q_INVOKABLE void setG(double g) {m_g = g;}
//! Sets the B component
+ //! @note Thiy syntax only available on Qt6-based versions. Use Color.b=<value> in Qt5-based scripts.
Q_INVOKABLE void setB(double b) {m_b = b;}
+ //! Formats a comma-separated string of unnamed rgb components in angle brackets.
+ //! @todo currently this seems to to nothing. JS print output shows "Color(address)". Use toVec3f() to show the values formatted by Vec3f's method.
+ Q_INVOKABLE QString toString() const {return QString("[%1, %2, %3]").arg(m_r).arg(m_g).arg(m_b);}
//! Formats a comma-separated string of named rgb components in angle brackets
- Q_INVOKABLE inline QString toString() const {return QString("[r:%1, g:%2, b:%3]").arg(m_r).arg(m_g).arg(m_b);}
- //! Formats a comma-separated string in angle brackets
+ Q_INVOKABLE QString toRGBString() const {return QString("[r:%1, g:%2, b:%3]").arg(m_r).arg(m_g).arg(m_b);}
+ //! Formats a hex string usable as HTML color
Q_INVOKABLE QString toHex() const;
private:
double m_r, m_g, m_b;
};
-Q_DECLARE_METATYPE(V3d)
-Q_DECLARE_METATYPE(V3f)
Q_DECLARE_METATYPE(Color)
+#endif
#endif // V3D_HPP
diff --git a/src/tests/testJavaScripting.cpp b/src/tests/testJavaScripting.cpp
index 1c1fb43542..3e4c0620e9 100644
--- a/src/tests/testJavaScripting.cpp
+++ b/src/tests/testJavaScripting.cpp
@@ -66,37 +66,13 @@ void TestJavaScripting::initTestCase()
#endif
StelScriptMgr::defVecClasses(engine);
}
-
+
+#ifndef ENABLE_SCRIPT_QML
+
void TestJavaScripting::testVec3fConstructor()
{
QVariantList data;
- // In ideal cases the new scripting interface works in QtScript:
- data << "var f1 = core.vec3f(0.5, 0.4, 0.3);\n"
- "f1.r().toFixed(1)+','+f1.g().toFixed(1)+','+f1.b().toFixed(1)\n"
- << "0.5,0.4,0.3"
- << "var f3 = core.vec3f('#00ffff');\n"
- "f3.toString()\n"
- << "[r:0, g:1, b:1]"
- << "var f4 = core.vec3f('white');\n"
- "f4.toString()"
- << "[r:1, g:1, b:1]"
- << "var f5 = core.vec3f('lime');\n"
- "f5.toString()\n"
- << "[r:0, g:1, b:0]"
- << "var f6 = core.vec3f();\n"
- "f6.toString()\n"
- << "[r:1, g:1, b:1]"
- << "var f7 = core.vec3f('darkorange');\n"
- "f7.toHex()\n"
- << "#ff8c00"
- << "var f8 = core.color('darkorange');\n"
- "f8.toHex()\n"
- << "#ff8c00"
- << "var f9 = core.color(f4);\n" // still the same QScriptEngine
- "f9.toHex()\n"
- << "#ffffff";
-#ifndef ENABLE_SCRIPT_QML
data << "var f1 = Vec3f(0.5, 0.4, 0.3);\n"
"f1.r.toFixed(1)+','+f1.g.toFixed(1)+','+f1.b.toFixed(1)\n"
<< "0.5,0.4,0.3"
@@ -121,7 +97,6 @@ void TestJavaScripting::testVec3fConstructor()
<< "var f9 = Color(f4);\n" // still the same QScriptEngine
"f9.toHex()\n"
<< "#ffffff";
-#endif
while (data.count() >= 4)
{
@@ -136,21 +111,12 @@ void TestJavaScripting::testVec3fConstructorFail()
{
QVariantList data;
- // In ideal cases the new scripting interface works in QtScript:
- data << "var f2 = new V3d(core.vec3f(1, 2, 3));\n"
- "f2.toString()\n"
- << "error"
- << "var f10 = new V3d(core.color('nosuchcolor'));\n"
- "f10.toString()\n"
- << "error";
-#ifndef ENABLE_SCRIPT_QML
data << "var f2 = Vec3f(1, 2, 3);\n"
"f2.toString()\n"
<< "error"
<< "var f10 = Color('nosuchcolor');\n"
"f10.toString()\n"
<< "error";
-#endif
while (data.count() >= 4)
{
@@ -165,22 +131,7 @@ void TestJavaScripting::testVec3dConstructor()
{
QVariantList data;
- // In ideal cases the new scripting interface works in QtScript:
- data << "var v = new V3d(core.vec3d(4,5,6));\n"
- "v.r() + ',' + v.g() + ',' + v.b()\n"
- << "4,5,6"
- << "v.toString()\n"
- << "[4, 5, 6]"
- << "v.x() + '/' + v.y() + '/' + v.z()\n"
- << "4/5/6"
- << "v.setX(40); v.setY(50); v.setZ(60);\n"
- "v.toString()\n"
- << "[40, 50, 60]";
- // This strictly does no longer work.
- //<< "var w = Vec3d( 90, 90 );\n"
- //"w.x.toFixed(1) + ',' + w.y.toFixed(1) + ',' + w.z.toFixed(1)\n"
- //<< "0.0,0.0,1.0"; // toString shows coordinates off by epsilon
-#ifndef ENABLE_SCRIPT_QML
+
data << "var v = Vec3d(4,5,6);\n"
"v.r + ',' + v.g + ',' + v.b\n"
<< "4,5,6"
@@ -200,8 +151,101 @@ void TestJavaScripting::testVec3dConstructor()
"a.toString()\n"
<< "[?, ?, ?]";
***/
+
+ while (data.count() >= 4)
+ {
+ QString script = data.takeFirst().toString();
+ QString expect = data.takeFirst().toString();
+ QString result = TestJavaScripting::runScript(engine, script);
+ QVERIFY2( result == expect, qPrintable(QString("%1=%2").arg(script, result)) );
+ }
+}
#endif
+// Test V3d glue class. Should work in some way in Qt5 and Qt6 environments.
+void TestJavaScripting::testV3d()
+{
+ QVariantList data;
+
+ data << "var f1 = new V3d(0.5, 0.4, 0.3);\n"
+ "f1.x().toFixed(1)+','+f1.y().toFixed(1)+','+f1.z().toFixed(1)\n"
+ << "0.5,0.4,0.3"
+ << "var f6 = new V3d();\n"
+ "f6.toVec3d()\n"
+#ifdef ENABLE_SCRIPT_QML
+ << "QVariant(Vector3<double>, [0, 0, 0])" // Miracle: In regular scripts this looks like "[0, 0, 0]"
+#else
+ << "[0, 0, 0]"
+#endif
+ << "var f9 = new V3d(f1);\n" // still the same QScriptEngine
+ "f9.toHex()\n"
+ << "#ffffff";
+
+ while (data.count() >= 4)
+ {
+ QString script = data.takeFirst().toString();
+ QString expect = data.takeFirst().toString();
+ QString result = TestJavaScripting::runScript(engine, script);
+ QVERIFY2( result == expect, qPrintable(QString("%1=%2").arg(script, result)) );
+ }
+}
+// Test V3f glue class. Should work in some way in Qt5 and Qt6 environments.
+void TestJavaScripting::testV3f()
+{
+ QVariantList data;
+
+ data << "var f1 = new V3f(0.5, 0.4, 0.3);\n"
+ "f1.x().toFixed(1)+','+f1.y().toFixed(1)+','+f1.z().toFixed(1)\n"
+ << "0.5,0.4,0.3"
+ << "var f6 = new V3f();\n"
+ "f6.toVec3f()\n"
+#ifdef ENABLE_SCRIPT_QML
+ << "QVariant(Vector3<float>, [0, 0, 0])" // Miracle: In regular scripts this looks like "[0, 0, 0]"
+#else
+ << "[r:0, g:0, b:0]" // difference is just the r/g/b labels
+#endif
+ << "var f9 = new V3f(f1);\n" // still the same Engine
+ "f9.toHex()\n"
+ << "#ffffff";
+
+ while (data.count() >= 4)
+ {
+ QString script = data.takeFirst().toString();
+ QString expect = data.takeFirst().toString();
+ QString result = TestJavaScripting::runScript(engine, script);
+ QVERIFY2( result == expect, qPrintable(QString("%1=%2").arg(script, result)) );
+ }
+}
+// Test Color glue class. Should work in same way in Qt5 and Qt6 environments.
+void TestJavaScripting::testColor()
+{
+ QVariantList data;
+
+ data << "var f1 = new Color(0.5, 0.4, 0.3);\n"
+ "f1.getR().toFixed(1)+','+f1.getG().toFixed(1)+','+f1.getB().toFixed(1)\n"
+ << "0.5,0.4,0.3"
+ << "var f3 = new Color('#00ffff');\n"
+ "f3.toRGBString()\n"
+ << "[r:0, g:1, b:1]"
+ << "var f4 = new Color('white');\n"
+ "f4.toRGBString()"
+ << "[r:1, g:1, b:1]"
+ << "var f5 = new Color('lime');\n"
+ "f5.toRGBString()\n"
+ << "[r:0, g:1, b:0]"
+ << "var f6 = new Color();\n"
+ "f6.toRGBString()\n"
+ << "[r:1, g:1, b:1]"
+ << "var f7 = new Color('darkorange');\n"
+ "f7.toHex()\n"
+ << "#ff8c00"
+ << "var f8 = new Color('darkorange');\n"
+ "f8.toHex()\n"
+ << "#ff8c00"
+ << "var f9 = new Color(f4);\n" // still the same Engine
+ "f9.toHex()\n"
+ << "#ffffff";
+
while (data.count() >= 4)
{
QString script = data.takeFirst().toString();
diff --git a/src/tests/testJavaScripting.hpp b/src/tests/testJavaScripting.hpp
index ec589f5567..b563af7ecb 100644
--- a/src/tests/testJavaScripting.hpp
+++ b/src/tests/testJavaScripting.hpp
@@ -34,9 +34,14 @@ class TestJavaScripting : public QObject
Q_OBJECT
private slots:
void initTestCase();
+#ifndef ENABLE_SCRIPT_QML
void testVec3fConstructor();
void testVec3fConstructorFail();
void testVec3dConstructor();
+#endif
+ void testV3d();
+ void testV3f();
+ void testColor();
#ifdef ENABLE_SCRIPT_QML
QString runScript(QJSEngine *engine, QString script);
private: