Studying QtScript examples and using my own code (see my previous post regarding QtScript ) I can't quite understand how QtScript instantiate C++ classes where constructor has arguments.
Tracing the code (shown below) I can see that default constructor with no arguments get called, then my factory code get called and correct test(int) is called with agrument (10, in my case), but at the end of it my script receives an instance constructed with prototype where default constructor is invoked (_i == 0) . So, when following script is evaluated, returned value is 1 and not 11 as I expect.
Any comments, suggestions are very much appreciated.
//Script that is evaluated
var t = new test(10)
t.val + 1
//Script that is evaluated
var t = new test(10)
t.val + 1
To copy to clipboard, switch view to plain text mode
// part of the code that evaluates script
QString script
= scriptText;
// above script QScriptEngine interpreter;
test::registerWithScript("test", interpreter);
QScriptValue result = interpreter.evaluate(script);
// part of the code that evaluates script
QString script = scriptText; // above script
QScriptEngine interpreter;
test::registerWithScript("test", interpreter);
QScriptValue result = interpreter.evaluate(script);
To copy to clipboard, switch view to plain text mode
// support class to help with default constructor and registering
template <typename T> class Scriptable
{
public:
Scriptable()
{
}
static void registerWithScript(const char* scriptObjName, QScriptEngine& scriptengine)
{
T* t = new T();
QScriptValue obj = scriptengine.newQObject(t, QScriptEngine::ScriptOwnership);
scriptengine.setDefaultPrototype(qMetaTypeId<T>(),obj);
QScriptValue objCtor = scriptengine.newFunction(objectConst, obj);
scriptengine.globalObject().setProperty(scriptObjName, objCtor);
}
private:
static QScriptValue objectConst (QScriptContext* context, QScriptEngine* scriptengine)
{
boost::scoped_ptr<T> t(T::factory (context));
return scriptengine->toScriptValue(*t);
}
};
//test class; to study QtScript
class test
: public QObject,
public QScriptable,
public Scriptable<test>
{
Q_OBJECT
Q_PROPERTY(int val READ val WRITE set)
public:
test (int i = 0) : _i(i)
{
}
test (const test& another) : _i(another._i)
{
int i = _i;
}
virtual ~test ()
{
int i = _i;
}
test& operator = (const test& another)
{
_i = another._i;
return *this;
}
void set(int i)
{
_i = i;
}
int val()
{
return _i;
}
static test* factory (QScriptContext* context)
{
if (context->argumentCount() == 0)
return new test();
else
{
int i = context->argument(0).toInt32();
return new test(i);
}
}
private:
int _i;
};
Q_DECLARE_METATYPE(test)
Q_DECLARE_METATYPE(test*)
// support class to help with default constructor and registering
template <typename T> class Scriptable
{
public:
Scriptable()
{
}
static void registerWithScript(const char* scriptObjName, QScriptEngine& scriptengine)
{
T* t = new T();
QScriptValue obj = scriptengine.newQObject(t, QScriptEngine::ScriptOwnership);
scriptengine.setDefaultPrototype(qMetaTypeId<T>(),obj);
QScriptValue objCtor = scriptengine.newFunction(objectConst, obj);
scriptengine.globalObject().setProperty(scriptObjName, objCtor);
}
private:
static QScriptValue objectConst (QScriptContext* context, QScriptEngine* scriptengine)
{
boost::scoped_ptr<T> t(T::factory (context));
return scriptengine->toScriptValue(*t);
}
};
//test class; to study QtScript
class test : public QObject, public QScriptable, public Scriptable<test>
{
Q_OBJECT
Q_PROPERTY(int val READ val WRITE set)
public:
test (int i = 0) : _i(i)
{
}
test (const test& another) : _i(another._i)
{
int i = _i;
}
virtual ~test ()
{
int i = _i;
}
test& operator = (const test& another)
{
_i = another._i;
return *this;
}
void set(int i)
{
_i = i;
}
int val()
{
return _i;
}
static test* factory (QScriptContext* context)
{
if (context->argumentCount() == 0)
return new test();
else
{
int i = context->argument(0).toInt32();
return new test(i);
}
}
private:
int _i;
};
Q_DECLARE_METATYPE(test)
Q_DECLARE_METATYPE(test*)
To copy to clipboard, switch view to plain text mode
Bookmarks