[Interest] QJSEngine replacement for QScriptEngine misses newFunction

2016-05-18 Thread Walter Stefan
Hi,

I am looking into migrating my code to QJSEngine, because of the deprecation of 
the QScriptEngine (QtScript). As we have used the functionality of newFunction 
very extensive and all related scripts are depending on this, the newFunction 
in QJSEngine is for us mandatory or something that creates and equivalent 
result.

How do I currently map a native C++ class member function to the engine:
QScriptValue func_sqrt = m_engine->newFunction(sqrt, liEngine);
m_engine->globalObject().setProperty("sqrt", func_sqrt, QScriptValue::ReadOnly 
| QScriptValue::Undeletable);

This is an example of a native function:
QScriptValue ScriptModuleMath::sqrt(QScriptContext *context, QScriptEngine 
*engine, void *arg)
{
Q_UNUSED(engine)
Q_UNUSED(arg)
if (context->argumentCount()!=1)
{
return context->throwError( QScriptContext::SyntaxError, "sqrt(...): 
illegal number of arguments.");
} else if (!context->argument(0).isNumber())
{
return context->throwError( QScriptContext::SyntaxError, "sqrt(...): 
argument 1 is not a number.");
}

return qSqrt(context->argument(0).toNumber());
}

And in this way. I can use it then in the script:
value = sqrt(4);

I actually don't want to map a whole QObject, because that would require a call 
like this:
value = MyMath.sqrt(4);

Is there any way to achive in QJSEngine the same result as I do within the 
QScriptEngine?

Best Regards,
Stefan

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] QJSEngine replacement for QScriptEngine misses newFunction

2016-02-23 Thread Walter Stefan
Thanks Stephen!
I found a solution, which is very similar to your approach.

QJSValue myExt = m_engine->newQObject(new ScriptModuleMath());
// mount the whole class ScriptModule to the engine --> Math.sqrt(4)
m_engine->globalObject().setProperty("Math", myExt);
// mount only the sqrt function to the engine --> sqrt(4)
m_engine->globalObject().setProperty("sqrt", myExt.property("sqrt"));

the first mount allows me now to access the whole object and of course my 
sqrt() method.
i.e. Math.sqrt(4);

the second mount allows me to directly access the sqrt() method without the 
instance.
i.e. sqrt(4);

Thanks for your suggestion.

Best Regards,
Stefan

-Original Message-
From: Interest [mailto:interest-bounces+stefan.walter=lisec@qt-project.org] 
On Behalf Of Stephen Bryant
Sent: Dienstag, 23. Februar 2016 15:12
To: interest@qt-project.org
Subject: Re: [Interest] QJSEngine replacement for QScriptEngine misses 
newFunction

Hi Stefan,

On Tuesday 23 February 2016 05:34:03 Walter Stefan wrote:
[...]
> 
> And in this way. I can use it then in the script:
> value = sqrt(4);
> 
> I actually don't want to map a whole QObject, because that would 
> require a call like this: value = MyMath.sqrt(4);
> 
> Is there any way to achive in QJSEngine the same result as I do within 
> the QScriptEngine?


Is far as I know, the only way is to do the thing you don't want to: map the 
whole QObject.  You can, however, add a JS function reference inside the engine 
so you can call the function without the object name.

QJSEngine engine;
engine.globalObject().setProperty(
  "MyMath",
  engine.newQObject( new ScriptModuleMath(  ) ) ); engine.evaluate( "var 
sqrt=MyMath.sqrt;" );  // repeat for other functions

This will now work in JS:  value = sqrt(4);

You'll presumably be aware that all public slots of MyMath will automatically 
be available as JS functions.  That makes things a little easier.

It seems that you also need a QObject instance, event if you only want to 
expose static methods.

BTW: your C++ native function can use this signature: double sqrt(double); 
You'll get NaN if somebody calls it with a non-number.  The return value is 
also automatically converted as there is a QJSValue constructor that takes a 
double.


There's no direct equivalent of read-only/undeletable, unfortunately.  I'm 
missing that too.  The closest you can get is that your MyMath functions can't 
be altered from JS, and you can also make a read-only Q_PROPERTY.

However, there is nothing stopping somebody from reassigning properties of the 
global object - so your 'sqrt' function and 'MyMath' object could be replaced.  
This may be a security concern, depending on what you're doing.


Best regards,

Steve
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] QJSEngine replacement for QScriptEngine misses newFunction

2016-02-23 Thread nikita baryshnikov
As a workaround you can use QQmlContext::setContextObject:

QQmlEngine::rootContext()->setContextObject(myMath);

On Tue, Feb 23, 2016 at 2:11 PM, Stephen Bryant  wrote:
> Hi Stefan,
>
> On Tuesday 23 February 2016 05:34:03 Walter Stefan wrote:
> [...]
>>
>> And in this way. I can use it then in the script:
>> value = sqrt(4);
>>
>> I actually don't want to map a whole QObject, because that would require a
>> call like this: value = MyMath.sqrt(4);
>>
>> Is there any way to achive in QJSEngine the same result as I do within the
>> QScriptEngine?
>
>
> Is far as I know, the only way is to do the thing you don't want to: map the
> whole QObject.  You can, however, add a JS function reference inside the
> engine so you can call the function without the object name.
>
> QJSEngine engine;
> engine.globalObject().setProperty(
>   "MyMath",
>   engine.newQObject( new ScriptModuleMath(  ) )
> );
> engine.evaluate( "var sqrt=MyMath.sqrt;" );  // repeat for other functions
>
> This will now work in JS:  value = sqrt(4);
>
> You'll presumably be aware that all public slots of MyMath will automatically
> be available as JS functions.  That makes things a little easier.
>
> It seems that you also need a QObject instance, event if you only want to
> expose static methods.
>
> BTW: your C++ native function can use this signature: double sqrt(double);
> You'll get NaN if somebody calls it with a non-number.  The return value is
> also automatically converted as there is a QJSValue constructor that takes a
> double.
>
>
> There's no direct equivalent of read-only/undeletable, unfortunately.  I'm
> missing that too.  The closest you can get is that your MyMath functions can't
> be altered from JS, and you can also make a read-only Q_PROPERTY.
>
> However, there is nothing stopping somebody from reassigning properties of the
> global object - so your 'sqrt' function and 'MyMath' object could be replaced.
> This may be a security concern, depending on what you're doing.
>
>
> Best regards,
>
> Steve
> ___
> Interest mailing list
> Interest@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] QJSEngine replacement for QScriptEngine misses newFunction

2016-02-23 Thread Stephen Bryant
Hi Stefan,

On Tuesday 23 February 2016 05:34:03 Walter Stefan wrote:
[...]
> 
> And in this way. I can use it then in the script:
> value = sqrt(4);
> 
> I actually don't want to map a whole QObject, because that would require a
> call like this: value = MyMath.sqrt(4);
> 
> Is there any way to achive in QJSEngine the same result as I do within the
> QScriptEngine?


Is far as I know, the only way is to do the thing you don't want to: map the 
whole QObject.  You can, however, add a JS function reference inside the 
engine so you can call the function without the object name.

QJSEngine engine;
engine.globalObject().setProperty(
  "MyMath",
  engine.newQObject( new ScriptModuleMath(  ) )
);
engine.evaluate( "var sqrt=MyMath.sqrt;" );  // repeat for other functions

This will now work in JS:  value = sqrt(4);

You'll presumably be aware that all public slots of MyMath will automatically 
be available as JS functions.  That makes things a little easier.

It seems that you also need a QObject instance, event if you only want to 
expose static methods.

BTW: your C++ native function can use this signature: double sqrt(double);
You'll get NaN if somebody calls it with a non-number.  The return value is 
also automatically converted as there is a QJSValue constructor that takes a 
double.


There's no direct equivalent of read-only/undeletable, unfortunately.  I'm 
missing that too.  The closest you can get is that your MyMath functions can't 
be altered from JS, and you can also make a read-only Q_PROPERTY.

However, there is nothing stopping somebody from reassigning properties of the 
global object - so your 'sqrt' function and 'MyMath' object could be replaced.  
This may be a security concern, depending on what you're doing.


Best regards,

Steve
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


[Interest] QJSEngine replacement for QScriptEngine misses newFunction

2016-02-22 Thread Walter Stefan
Hi,

I am looking into migrating my code to QJSEngine, because of the deprecation of 
the QScriptEngine (QtScript). As we have used the functionality of newFunction 
very extensive and all related scripts are depending on this, the newFunction 
in QJSEngine is for us mandatory or something that creates and equivalent 
result.

How do I currently map a native C++ class member function to the engine:
QScriptValue func_sqrt = m_engine->newFunction(sqrt, liEngine);
m_engine->globalObject().setProperty("sqrt", func_sqrt, QScriptValue::ReadOnly 
| QScriptValue::Undeletable);

This is an example of a native function:
QScriptValue ScriptModuleMath::sqrt(QScriptContext *context, QScriptEngine 
*engine, void *arg)
{
Q_UNUSED(engine)
Q_UNUSED(arg)
if (context->argumentCount()!=1)
{
return context->throwError( QScriptContext::SyntaxError, "sqrt(...): 
illegal number of arguments.");
} else if (!context->argument(0).isNumber())
{
return context->throwError( QScriptContext::SyntaxError, "sqrt(...): 
argument 1 is not a number.");
}

return qSqrt(context->argument(0).toNumber());
}

And in this way. I can use it then in the script:
value = sqrt(4);

I actually don't want to map a whole QObject, because that would require a call 
like this:
value = MyMath.sqrt(4);

Is there any way to achive in QJSEngine the same result as I do within the 
QScriptEngine?

Best Regards,
Stefan

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest