[Development] Copying QJSValue arrays

Sean Harmer sean.harmer at kdab.com
Mon Sep 29 10:13:43 CEST 2014


Hi Simon,

On Monday 29 Sep 2014 09:20:00 Simon Hausmann wrote:
> On Sunday 28. September 2014 15.17.34 Paul Lemire wrote:
> > We're working on being able to set GLSL uniform arrays from QML.
> > 
> > Basically what we have is a QParameter QObject exposed to QML as
> > Parameter.
> > 
> > It contains a QString name property and a QVariant value property.
> > 
> > Here's how it can be used for scalar types.
> > 
> > Parameter { name : "uniformName"; value : 1.0; }
> > 
> > What we want is to send a copy of value to our backend renderer, so that
> > we
> > won't have any problem with threading. For scalar types, the copy is done
> > implicitly.
> > 
> > For array types, we'd like to be able to do something like that:
> > 
> > property var myArray : [1.0, 1.0, 1.0]
> > 
> > Parameter { name : "uniformArray"; value : myArray }
> > 
> > However in that case, value is a QJSValue containing a JS Array object.
> > 
> > We need a way to be able to copy that object.
> > 
> > The tricky part there is that we can't check the QVariant to to see if it
> > contains a QJSValue directly as we don't want to introduce a dependency to
> > the QML module.
> > 
> > We're thinking of maybe introducing a Qt.array helper function that would
> > return us a copy of the array directly or retrieve a QVector<QVariant>.
> > 
> > If you've got ideas around that issue, please step in.
> 
> If you don't want to depend on QtQml (which seems odd for a library that
> offers Qml bindings), then what you could do is utilize the conversion
> functions.

Yeah it sounds odd. The reason is that we hope to offer both C++ and QML apis 
for Qt3D where the plain C++ interface doesn't depend upon QtQml.

> So after checking your QVariant for all other types you're
> interested in supporting, you can try
> 
>     canConvert<QVariantList>()
> 
> and afterwards convert to that. This will trigger a registered conversion
> function that will convert the JavaScript array object, that the QJSValue
> wraps, into a QVariant list that is not dependent on the JS engine anymore.
> 
> A QJSValue wrapped in a QVariant is (through QVariant) API always
> convertible to a QVariantList and a QVariantMap - it's a shortcut to
> writing
> 
>     qvariant_cast<QJSValue>(variant).toVariant().value<TypeYouWant>();
> 
> without using QJSValue. Due to the custom conversion functions being
> unconditional you can however not distinguish between a regular JavaScript
> object or an array. Therefore if the property contains an object the
> conversion to an array will cause a loss of data.
> 
> If you don't want to loose any data, you're going to have to support the
> types the QVariant can contain, and that includes direct support for
> QJSValue.

Right. We're also considering having the property setter function call a 
helper virtual which in C++ lib does nothing but in the QML dependent lib 
takes care of extracting and copying the data.

Thank you for your ideas.

Sean




More information about the Development mailing list