Custom Script Class Parameterübergabe

Alles rund um die Programmierung mit Qt
Antworten
Viceinator
Beiträge: 1
Registriert: 22. August 2013 14:42

Custom Script Class Parameterübergabe

Beitrag von Viceinator »

Hallo allerseits,

dies ist mein erster Thread in dem Forum hier und damit seien erstmal alle gegrüßt.

Nun zu meinem kleinen Problem.
Ich möchte mir einige Klasse entwickeln, welche mithilfe der QScriptEngine verarbeitet und ausgeführt werden sollen.
Angefangen habe ich mit einer einfachen String-Klasse (Ich weiß die String-Class ist schon von Haus aus eingebaut). Das funktioniert soweit auch schon ganz gut.

Hier der JavaScript-Code (funktioniert):

Code: Alles auswählen

var string1 = new QdbString();
var string2 = new QdbString();
var msgBox = new QdbMessageBox();

string1.assign("Hallo Welt!");
string2.assign(string1.getString());

msgBox.setTitle(string1.getString());
msgBox.setText(string2.getString());

msgBox.exec();
Dieser hier funktioniert nicht:

Code: Alles auswählen

var string1 = new QdbString();
var string2 = new QdbString();
var msgBox = new QdbMessageBox();

string1.assign("Hallo Welt!");
string2.assign(string1);

msgBox.setTitle(string1.getString());
msgBox.setText(string2.getString());

msgBox.exec();
Der Unterschied der beiden Quelltexte ist nur, dass in Zeile 6 die Methode "getString()" von Objekt "string1" nicht mehr aufgerufen wird.
Es wird die Referenz auf das Objekt übergeben. Und genau dass scheint in meiner Implementierung zu fehlen oder fehlerhaft zu sein.
Die Ausführung des Skriptes wird jedenfalls an dieser Stelle abgebrochen.
Habe ich in der QdbStringScriptPrototype oder der QdbStringScriptClass-Klasse etwas übersehen?
Ich würde die "getString"-Methoden gerne vermeiden, da das Objekt selber ja den String repräsentiert.

Hier der C++ Source:

QdbString.h

Code: Alles auswählen

#ifndef QDBSTRING_H
#define QDBSTRING_H

// Qt includes
#include <QObject>
#include <QString>

// Class
class QdbString : public QObject
{
	Q_OBJECT

	private:
		// private: fields
		QString	m_String;

	public:
		// public: methods (constructors)
		explicit QdbString(QObject *parent = 0);
		QdbString(const QdbString &_Object);

	public Q_SLOTS:
		// public: methods
		void	assign(const char* _String);
		void	assign(const QString &_String);
		void	assign(const QdbString &_String);
		bool	isEqual(const char* _String) const;
		bool	isEqual(const QString& _String) const;
		bool	isEqual(const QdbString& _String) const;

	public Q_SLOTS:
		// public: methods (getters)
		QString toQString() const;

	public:
		// public: methods (operators)
		QdbString&	operator =(const QdbString &_Object);
		bool		operator ==(const QdbString &_Object) const;
};

#endif // QDBSTRING_H
QdbString.cpp

Code: Alles auswählen

#include "QdbString.h"

QdbString::QdbString(QObject *parent) :
	QObject(parent)
{
}

QdbString::QdbString(const QdbString &_Object)
{
	this->assign(_Object);
}

// public: methods
void	QdbString::assign(const char* _String)
{
	this->m_String	= _String;
}

void	QdbString::assign(const QString &_String)
{
	this->m_String	= _String;
}

void	QdbString::assign(const QdbString &_String)
{
	this->m_String	= _String.m_String;
}

bool	QdbString::isEqual(const char* _String) const
{
	if(this->m_String == _String)
		return true;

	return false;
}

bool	QdbString::isEqual(const QString& _String) const
{
	if(this->m_String == _String)
		return true;

	return false;
}

bool	QdbString::isEqual(const QdbString& _String) const
{
	if(this->m_String == _String.m_String)
		return true;

	return false;
}

// public: methods (getters)
QString QdbString::toQString() const
{
	return this->m_String;
}

// public: methods (operators)
QdbString&	QdbString::operator =(const QdbString &_Object)
{
	this->assign(_Object);
	return *this;
}

bool	QdbString::operator ==(const QdbString &_Object) const
{
	return this->isEqual(_Object);
}
QdbStringScriptClass.h

Code: Alles auswählen

#ifndef QDBSTRINGSCRIPTCLASS_H
#define QDBSTRINGSCRIPTCLASS_H

// Qt includes
#include <QtCore/QObject>
#include <QtScript/QScriptContext>
#include <QtScript/QScriptClass>
#include <QtScript/QScriptString>

// Project includes
#include "QdbString.h"

// Class
class QdbStringScriptClass : public QObject, public QScriptClass
{
	Q_OBJECT

	private:
		// private: fields
		QScriptValue	m_Prototype;
		QScriptValue	m_Constructor;

	public:
		// public: methods (constructors)
		explicit QdbStringScriptClass(QScriptEngine *_ScriptEngine);

		// public: methods (destructor)
		virtual ~QdbStringScriptClass();

	private:
		// private: methods (static)
		static QScriptValue		construct(QScriptContext *ctx, QScriptEngine *eng);
		static QScriptValue		toScriptValue(QScriptEngine *_ScriptEngine, const QdbString &_Object);
		static void				fromScriptValue(const QScriptValue &_ScriptValue, QdbString &_Object);

	public:
		// public: methods
		QScriptValue					constructor();
		QScriptValue					newInstance();
		QScriptValue					newInstance(const QdbString &_Object);
		QueryFlags						queryProperty(const QScriptValue &_Object, const QScriptString &_Name, QueryFlags _Flags, uint *_Id);
		QScriptValue					property(const QScriptValue &_Object, const QScriptString &_Name, uint _Id);
		QScriptValue::PropertyFlags		propertyFlags(const QScriptValue &_Object, const QScriptString &_Name, uint _Id);
		QString							name() const;
		QScriptValue					prototype() const;

	public:
		// public: methods (setters)
		void							setProperty(QScriptValue &_Object, const QScriptString &_Name, uint _Id, const QScriptValue &_Value);
};

#endif // QDBSTRINGSCRIPTCLASS_H
QdbStringScriptClass.cpp

Code: Alles auswählen

// Qt includes
#include <QtScript/QScriptContext>
#include <QtScript/QScriptEngine>

// Project includes
#include "QdbStringScriptClass.h"
#include "QdbStringScriptPrototype.h"

// Declare metatypes
Q_DECLARE_METATYPE(QdbString)
Q_DECLARE_METATYPE(QdbString*)
Q_DECLARE_METATYPE(QdbStringScriptClass*)

// public: methods (constructors)
QdbStringScriptClass::QdbStringScriptClass(QScriptEngine *_ScriptEngine) :
	QObject(_ScriptEngine),
	QScriptClass(_ScriptEngine)
{
	// fields
	QScriptValue	global;

	qScriptRegisterMetaType<QdbString>(_ScriptEngine, toScriptValue, fromScriptValue);

	this->m_Prototype	= _ScriptEngine->newQObject(
				new QdbStringScriptPrototype(this),
				QScriptEngine::QtOwnership,
				QScriptEngine::SkipMethodsInEnumeration |
				QScriptEngine::ExcludeSuperClassMethods |
				QScriptEngine::ExcludeSuperClassProperties
	);

	global	= _ScriptEngine->globalObject();
	this->m_Prototype.setPrototype(global.property("Object").property("prototype"));

	this->m_Constructor		= _ScriptEngine->newFunction(construct, this->m_Prototype);
	this->m_Constructor.setData(_ScriptEngine->toScriptValue(this));
}

// public: methods (destructor)
QdbStringScriptClass::~QdbStringScriptClass() {

}

// private: methods (static)
QScriptValue	QdbStringScriptClass::construct(QScriptContext *ctx, QScriptEngine *eng)
{
	QdbStringScriptClass	*cls	= qscriptvalue_cast<QdbStringScriptClass*>(ctx->callee().data());

	if(!cls)
		return QScriptValue();

	QScriptValue arg = ctx->argument(0);
	if(arg.instanceOf(ctx->callee()))
		return cls->newInstance(qscriptvalue_cast<QdbString>(arg));

	return cls->newInstance();
}

QScriptValue	QdbStringScriptClass::toScriptValue(QScriptEngine *_ScriptEngine, const QdbString &_Object)
{
	// fields
	QScriptValue			constructor	= _ScriptEngine->globalObject().property("QdbString");
	QdbStringScriptClass	*cls		= qscriptvalue_cast<QdbStringScriptClass*>(constructor.data());

	if (!cls)
		return _ScriptEngine->newVariant(QVariant::fromValue(_Object));

	return cls->newInstance(_Object);
}

void	QdbStringScriptClass::fromScriptValue(const QScriptValue &_ScriptValue, QdbString &_Object)
{
	_Object		= qvariant_cast<QdbString>(_ScriptValue.data().toVariant());
}

// public: methods
QScriptValue	QdbStringScriptClass::constructor()
{
	return m_Constructor;
}

QScriptValue	QdbStringScriptClass::newInstance()
{
	return newInstance(QdbString());
}

QScriptValue	QdbStringScriptClass::newInstance(const QdbString &_Object)
{
	QScriptValue	data	= this->engine()->newVariant(QVariant::fromValue(_Object));

	return this->engine()->newObject(this, data);
}

QScriptClass::QueryFlags	QdbStringScriptClass::queryProperty(const QScriptValue &_Object, const QScriptString &_Name, QueryFlags _Flags, uint *_Id)
{
	QdbString	*object			= qscriptvalue_cast<QdbString*>(_Object.data());
	bool			isArrayIndex	= false;

	if(!object)
		return 0;

	if(!isArrayIndex)
		return 0;

	return _Flags;
}

QScriptValue	QdbStringScriptClass::property(const QScriptValue &_Object, const QScriptString &_Name, uint _Id)
{
	// fields
	QdbString	*object		= qscriptvalue_cast<QdbString*>(_Object.data());

	if(!object)
		return QScriptValue();

	return QScriptValue();
}

QScriptValue::PropertyFlags	QdbStringScriptClass::propertyFlags(const QScriptValue &_Object, const QScriptString &_Name, uint _Id)
{
	return QScriptValue::Undeletable;
}

QString	QdbStringScriptClass::name() const
{
	return QLatin1String("QdbString");
}

QScriptValue	QdbStringScriptClass::prototype() const
{
	return m_Prototype;
}

// public: methods (setters)
void	QdbStringScriptClass::setProperty(QScriptValue &_Object, const QScriptString &_Name, uint _Id, const QScriptValue &_Value)
{
	// fields
	QdbString	*object		= qscriptvalue_cast<QdbString*>(_Object.data());

	//
	if(!object)
		return;
}
QdbStringScriptPrototype.h

Code: Alles auswählen

#ifndef QDBSTRINGSCRIPTPROTOTYPE_H
#define QDBSTRINGSCRIPTPROTOTYPE_H

// Qt includes
#include <QObject>
#include <QtScript/QScriptable>
#include <QtScript/QScriptValue>

// Project includes
#include "QdbString.h"

// Class
class QdbStringScriptPrototype : public QObject, public QScriptable
{
	Q_OBJECT

	public:
		// public: methods (constructors)
		explicit QdbStringScriptPrototype(QObject *parent = 0);

		// public: methods (destructor)
		virtual ~QdbStringScriptPrototype();

	private:
		// private: methods
		QScriptValue	valueOf() const;
		QdbString*		nativeObject() const;

	public Q_SLOTS:
		// public: methods
		void	assign(const char* _String);
		void	assign(const QString& _String);
		void	assign(const QdbString& _String);

	public Q_SLOTS:
		// public: methods (setters)

	public Q_SLOTS:
		// public: methods (getters)
		QScriptValue	getString() const;
};

#endif // QDBSTRINGSCRIPTPROTOTYPE_H
QdbStringScriptPrototype.cpp

Code: Alles auswählen

// Qt includes
#include <QtScript/QScriptEngine>

// Project includes
#include "QdbStringScriptPrototype.h"

// Declare as metatype
Q_DECLARE_METATYPE(QdbString*)

// public: methods (constructors)
QdbStringScriptPrototype::QdbStringScriptPrototype(QObject *parent) :
	QObject(parent)
{
}

// public: methods (destructor)
QdbStringScriptPrototype::~QdbStringScriptPrototype()
{

}

// private: methods
QScriptValue	QdbStringScriptPrototype::valueOf() const
{
	return this->thisObject().data();
}

QdbString*	QdbStringScriptPrototype::nativeObject() const
{
	return qscriptvalue_cast<QdbString*>(this->thisObject().data());
}

// public: methods
void	QdbStringScriptPrototype::assign(const char* _String) {
	this->nativeObject()->assign(_String);
}

void	QdbStringScriptPrototype::assign(const QString& _String)
{
	this->nativeObject()->assign(_String);
}

void	QdbStringScriptPrototype::assign(const QdbString &_String)
{
	this->nativeObject()->assign(_String);
}

// public: methods (setters)


// public: methods (getters)
QScriptValue	QdbStringScriptPrototype::getString() const
{
	return this->nativeObject()->toQString();
}
Ich bedanke mich im Voraus für die Hilfe!


Gruß
Manuel
Antworten