Fixed qt_metacall, now everything works as it should.
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
Lauro Moura <lauro.neto@openbossa.org>
This commit is contained in:
parent
e20a97a480
commit
59b4f2b59d
4 changed files with 59 additions and 65 deletions
|
|
@ -14,26 +14,26 @@ struct Converter<QVariant>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray resolveMetaType(PyTypeObject* type, int &typeId)
|
static const char* resolveMetaType(PyTypeObject* type, int* typeId)
|
||||||
{
|
{
|
||||||
if (PyObject_TypeCheck(type, &SbkObjectType_Type)) {
|
if (PyObject_TypeCheck(type, &SbkObjectType_Type)) {
|
||||||
SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(type);
|
SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(type);
|
||||||
QByteArray typeName(Shiboken::ObjectType::getOriginalName(sbkType));
|
const char* typeName = Shiboken::ObjectType::getOriginalName(sbkType);
|
||||||
bool valueType = !typeName.endsWith("*");
|
bool valueType = '*' != typeName[qstrlen(typeName) - 1];
|
||||||
|
|
||||||
// Do not convert user type of value
|
// Do not convert user type of value
|
||||||
if (valueType && Shiboken::ObjectType::isUserType(type))
|
if (valueType && Shiboken::ObjectType::isUserType(type))
|
||||||
return QByteArray();
|
return 0;
|
||||||
|
|
||||||
int obTypeId = QMetaType::type(typeName);
|
int obTypeId = QMetaType::type(typeName);
|
||||||
if (obTypeId) {
|
if (obTypeId) {
|
||||||
typeId = obTypeId;
|
*typeId = obTypeId;
|
||||||
return QByteArray(typeName);
|
return typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not resolve types to value type
|
// Do not resolve types to value type
|
||||||
if (valueType)
|
if (valueType)
|
||||||
return QByteArray();
|
return 0;
|
||||||
|
|
||||||
// find in base types
|
// find in base types
|
||||||
if (type->tp_base) {
|
if (type->tp_base) {
|
||||||
|
|
@ -41,14 +41,14 @@ struct Converter<QVariant>
|
||||||
} else if (type->tp_bases) {
|
} else if (type->tp_bases) {
|
||||||
int size = PyTuple_GET_SIZE(type->tp_bases);
|
int size = PyTuple_GET_SIZE(type->tp_bases);
|
||||||
for(int i=0; i < size; i++){
|
for(int i=0; i < size; i++){
|
||||||
QByteArray derivedName = resolveMetaType(reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(type->tp_bases, i)), typeId);
|
const char* derivedName = resolveMetaType(reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(type->tp_bases, i)), typeId);
|
||||||
if (!derivedName.isEmpty())
|
if (derivedName)
|
||||||
return derivedName;
|
return derivedName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typeId = 0;
|
*typeId = 0;
|
||||||
return QByteArray();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QVariant toCpp(PyObject* pyObj)
|
static QVariant toCpp(PyObject* pyObj)
|
||||||
|
|
@ -87,22 +87,15 @@ struct Converter<QVariant>
|
||||||
} else {
|
} else {
|
||||||
// a class supported by QVariant?
|
// a class supported by QVariant?
|
||||||
if (Shiboken::Object::checkType(pyObj)) {
|
if (Shiboken::Object::checkType(pyObj)) {
|
||||||
SbkObjectType* objType = reinterpret_cast<SbkObjectType*>(pyObj->ob_type);
|
int typeCode;
|
||||||
int typeCode = 0;
|
const char* typeName = resolveMetaType(pyObj->ob_type, &typeCode);
|
||||||
QByteArray typeName = resolveMetaType(reinterpret_cast<PyTypeObject*>(objType), typeCode);
|
|
||||||
if (typeCode) {
|
if (typeCode && typeName) {
|
||||||
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(typeName);
|
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(typeName);
|
||||||
void* data = 0;
|
QVariant var(typeCode, (void*)0);
|
||||||
data = tr->toCpp(pyObj, &data, true);
|
void* args[] = { var.data() };
|
||||||
if (typeName.endsWith("*")) {
|
tr->toCpp(pyObj, args);
|
||||||
QVariant var(typeCode, &data);
|
return var;
|
||||||
tr->deleteObject(data);
|
|
||||||
return var;
|
|
||||||
} else {
|
|
||||||
QVariant var(typeCode, data);
|
|
||||||
tr->deleteObject(data);
|
|
||||||
return var;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Is a shiboken type not known by Qt
|
// Is a shiboken type not known by Qt
|
||||||
|
|
@ -140,28 +133,25 @@ struct Converter<QVariant>
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
Shiboken::AutoDecRef element(PySequence_GetItem(list, 0));
|
Shiboken::AutoDecRef element(PySequence_GetItem(list, 0));
|
||||||
int typeId = 0;
|
int typeId;
|
||||||
QByteArray typeName = resolveMetaType(element.cast<PyTypeObject*>(), typeId);
|
const char* typeName = resolveMetaType(element.cast<PyTypeObject*>(), &typeId);
|
||||||
if (!typeName.isEmpty()) {
|
if (typeName) {
|
||||||
QByteArray listTypeName = QByteArray("QList<"+typeName+">");
|
QByteArray listTypeName("QList<");
|
||||||
|
listTypeName += typeName;
|
||||||
|
listTypeName += '>';
|
||||||
typeId = QMetaType::type(listTypeName);
|
typeId = QMetaType::type(listTypeName);
|
||||||
if (typeId > 0) {
|
if (typeId > 0) {
|
||||||
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(listTypeName);
|
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(listTypeName);
|
||||||
if (!tr) {
|
if (!tr) {
|
||||||
qWarning() << "TypeResolver for :" << listTypeName << "not registered.";
|
qWarning() << "TypeResolver for :" << listTypeName << "not registered.";
|
||||||
return QVariant();
|
|
||||||
} else {
|
} else {
|
||||||
void *data = 0;
|
QVariant var(typeId, (void*)0);
|
||||||
data = tr->toCpp(list, &data, true);
|
void* args[] = { var.data(), 0 };
|
||||||
QVariant var(typeId, data);
|
tr->toCpp(list, args);
|
||||||
tr->deleteObject(data);
|
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return QVariant();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,29 +98,26 @@ void functionFree(void *self)
|
||||||
|
|
||||||
PyObject* functionCall(PyObject* self, PyObject* args, PyObject* kw)
|
PyObject* functionCall(PyObject* self, PyObject* args, PyObject* kw)
|
||||||
{
|
{
|
||||||
QGenericArgument gArgs[10];
|
static Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get("QVariant");
|
||||||
PySideMetaFunction* function = reinterpret_cast<PySideMetaFunction*>(self);
|
|
||||||
QList<QVariant*> vArgs;
|
|
||||||
QMetaMethod method = function->d->method;
|
|
||||||
QList<QByteArray> pTypes = method.parameterTypes();
|
|
||||||
int numArgs = pTypes.size();
|
|
||||||
|
|
||||||
Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get("QVariant");
|
|
||||||
Q_ASSERT(typeResolver);
|
Q_ASSERT(typeResolver);
|
||||||
for(int i=0; i < numArgs; i++) {
|
|
||||||
QVariant *vArg;
|
QGenericArgument gArgs[10];
|
||||||
|
QVariant vArgs[10];
|
||||||
|
PySideMetaFunction* function = reinterpret_cast<PySideMetaFunction*>(self);
|
||||||
|
QMetaMethod method = function->d->method;
|
||||||
|
int argsGiven = method.parameterTypes().size();
|
||||||
|
|
||||||
|
for (int i = 0; i < argsGiven; ++i) {
|
||||||
Shiboken::AutoDecRef pyArg(PySequence_GetItem(args, i));
|
Shiboken::AutoDecRef pyArg(PySequence_GetItem(args, i));
|
||||||
typeResolver->toCpp(pyArg, (void**)&vArg, true);
|
gArgs[i] = Q_ARG(QVariant, vArgs[i]);
|
||||||
vArgs.append(vArg);
|
void* v[1] = { &vArgs[i] };
|
||||||
gArgs[i] = Q_ARG(QVariant, *vArg);
|
typeResolver->toCpp(pyArg, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant retVariant;
|
QVariant retVariant;
|
||||||
QGenericReturnArgument returnValue = Q_RETURN_ARG(QVariant, retVariant);
|
QGenericReturnArgument returnValue = Q_RETURN_ARG(QVariant, retVariant);
|
||||||
method.invoke(function->d->qobject, returnValue, gArgs[0], gArgs[1], gArgs[2], gArgs[3], gArgs[4], gArgs[5], gArgs[6], gArgs[7], gArgs[8], gArgs[9]);
|
method.invoke(function->d->qobject, returnValue, gArgs[0], gArgs[1], gArgs[2], gArgs[3], gArgs[4], gArgs[5], gArgs[6], gArgs[7], gArgs[8], gArgs[9]);
|
||||||
|
|
||||||
while(!vArgs.isEmpty())
|
|
||||||
delete vArgs.takeFirst();
|
|
||||||
|
|
||||||
if (retVariant.isValid())
|
if (retVariant.isValid())
|
||||||
return typeResolver->toPython(&retVariant);
|
return typeResolver->toPython(&retVariant);
|
||||||
|
|
|
||||||
|
|
@ -70,9 +70,17 @@ PyObjectWrapper::PyObjectWrapper(const PyObjectWrapper &other)
|
||||||
|
|
||||||
PyObjectWrapper::~PyObjectWrapper()
|
PyObjectWrapper::~PyObjectWrapper()
|
||||||
{
|
{
|
||||||
|
Shiboken::GilState gil;
|
||||||
Py_DECREF(m_me);
|
Py_DECREF(m_me);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObjectWrapper& PyObjectWrapper::operator=(const PySide::PyObjectWrapper& other)
|
||||||
|
{
|
||||||
|
Py_INCREF(other.m_me);
|
||||||
|
Py_DECREF(m_me);
|
||||||
|
m_me = other.m_me;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
PyObjectWrapper::operator PyObject*() const
|
PyObjectWrapper::operator PyObject*() const
|
||||||
{
|
{
|
||||||
|
|
@ -179,24 +187,26 @@ static bool emitNormalSignal(QObject* source, int signalIndex, const char* signa
|
||||||
{
|
{
|
||||||
Shiboken::AutoDecRef sequence(PySequence_Fast(args, 0));
|
Shiboken::AutoDecRef sequence(PySequence_Fast(args, 0));
|
||||||
int argsGiven = PySequence_Fast_GET_SIZE(sequence.object());
|
int argsGiven = PySequence_Fast_GET_SIZE(sequence.object());
|
||||||
|
|
||||||
if (argsGiven > argTypes.count()) {
|
if (argsGiven > argTypes.count()) {
|
||||||
PyErr_Format(PyExc_TypeError, "%s only accepts %d arguments, %d given!", signal, argTypes.count(), argsGiven);
|
PyErr_Format(PyExc_TypeError, "%s only accepts %d arguments, %d given!", signal, argTypes.count(), argsGiven);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void** signalArgs = new void*[argsGiven+1];
|
QVariant* signalValues = new QVariant[argsGiven];
|
||||||
void** signalValues = new void*[argsGiven];
|
void** signalArgs = new void*[argsGiven + 1];
|
||||||
signalArgs[0] = 0;
|
signalArgs[0] = 0;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < argsGiven; ++i) {
|
for (i = 0; i < argsGiven; ++i) {
|
||||||
Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(qPrintable(argTypes[i]));
|
const char* typeName = argTypes[i].toAscii().constData();
|
||||||
|
Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(typeName);
|
||||||
if (typeResolver) {
|
if (typeResolver) {
|
||||||
typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i), &signalValues[i], true);
|
int typeId = QMetaType::type(typeName);
|
||||||
if (Shiboken::TypeResolver::getType(qPrintable(argTypes[i])) == Shiboken::TypeResolver::ObjectType)
|
if (Shiboken::TypeResolver::getType(typeName) == Shiboken::TypeResolver::ValueType)
|
||||||
signalArgs[i+1] = &signalValues[i];
|
signalValues[i] = QVariant(typeId, (void*) 0);
|
||||||
else
|
signalArgs[i+1] = signalValues[i].data();
|
||||||
signalArgs[i+1] = signalValues[i];
|
typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i), &signalArgs[i+1]);
|
||||||
} else {
|
} else {
|
||||||
PyErr_Format(PyExc_TypeError, "Unknown type used to emit a signal: %s", qPrintable(argTypes[i]));
|
PyErr_Format(PyExc_TypeError, "Unknown type used to emit a signal: %s", qPrintable(argTypes[i]));
|
||||||
break;
|
break;
|
||||||
|
|
@ -207,10 +217,6 @@ static bool emitNormalSignal(QObject* source, int signalIndex, const char* signa
|
||||||
if (ok)
|
if (ok)
|
||||||
QMetaObject::activate(source, signalIndex, signalArgs);
|
QMetaObject::activate(source, signalIndex, signalArgs);
|
||||||
|
|
||||||
//cleanup memory
|
|
||||||
for (int j = 0; j < i; ++j)
|
|
||||||
Shiboken::TypeResolver::get(qPrintable(argTypes[j]))->deleteObject(signalArgs[j+1]);
|
|
||||||
|
|
||||||
delete[] signalArgs;
|
delete[] signalArgs;
|
||||||
delete[] signalValues;
|
delete[] signalValues;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ public:
|
||||||
PyObjectWrapper(const PyObjectWrapper &other);
|
PyObjectWrapper(const PyObjectWrapper &other);
|
||||||
~PyObjectWrapper();
|
~PyObjectWrapper();
|
||||||
operator PyObject*() const;
|
operator PyObject*() const;
|
||||||
|
PyObjectWrapper& operator=(const PyObjectWrapper &other);
|
||||||
private:
|
private:
|
||||||
PyObject* m_me;
|
PyObject* m_me;
|
||||||
void* m_data; //future
|
void* m_data; //future
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue