diff options
-rw-r--r-- | PySide/QtCore/qvariant_conversions.h | 66 | ||||
-rw-r--r-- | libpyside/pysidemetafunction.cpp | 21 | ||||
-rw-r--r-- | libpyside/signalmanager.cpp | 30 | ||||
-rw-r--r-- | libpyside/signalmanager.h | 1 |
4 files changed, 56 insertions, 62 deletions
diff --git a/PySide/QtCore/qvariant_conversions.h b/PySide/QtCore/qvariant_conversions.h index 68b6e8f5a..0b89534bd 100644 --- a/PySide/QtCore/qvariant_conversions.h +++ b/PySide/QtCore/qvariant_conversions.h @@ -14,26 +14,26 @@ struct Converter<QVariant> return true; } - static QByteArray resolveMetaType(PyTypeObject* type, int &typeId) + static const char* resolveMetaType(PyTypeObject* type, int* typeId) { if (PyObject_TypeCheck(type, &SbkObjectType_Type)) { SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(type); - QByteArray typeName(Shiboken::ObjectType::getOriginalName(sbkType)); - bool valueType = !typeName.endsWith("*"); + const char* typeName = Shiboken::ObjectType::getOriginalName(sbkType); + bool valueType = '*' != typeName[qstrlen(typeName) - 1]; // Do not convert user type of value if (valueType && Shiboken::ObjectType::isUserType(type)) - return QByteArray(); + return 0; int obTypeId = QMetaType::type(typeName); if (obTypeId) { - typeId = obTypeId; - return QByteArray(typeName); + *typeId = obTypeId; + return typeName; } // Do not resolve types to value type if (valueType) - return QByteArray(); + return 0; // find in base types if (type->tp_base) { @@ -41,14 +41,14 @@ struct Converter<QVariant> } else if (type->tp_bases) { int size = PyTuple_GET_SIZE(type->tp_bases); for(int i=0; i < size; i++){ - QByteArray derivedName = resolveMetaType(reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(type->tp_bases, i)), typeId); - if (!derivedName.isEmpty()) + const char* derivedName = resolveMetaType(reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(type->tp_bases, i)), typeId); + if (derivedName) return derivedName; } } } - typeId = 0; - return QByteArray(); + *typeId = 0; + return 0; } static QVariant toCpp(PyObject* pyObj) @@ -87,22 +87,15 @@ struct Converter<QVariant> } else { // a class supported by QVariant? if (Shiboken::Object::checkType(pyObj)) { - SbkObjectType* objType = reinterpret_cast<SbkObjectType*>(pyObj->ob_type); - int typeCode = 0; - QByteArray typeName = resolveMetaType(reinterpret_cast<PyTypeObject*>(objType), typeCode); - if (typeCode) { + int typeCode; + const char* typeName = resolveMetaType(pyObj->ob_type, &typeCode); + + if (typeCode && typeName) { Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(typeName); - void* data = 0; - data = tr->toCpp(pyObj, &data, true); - if (typeName.endsWith("*")) { - QVariant var(typeCode, &data); - tr->deleteObject(data); - return var; - } else { - QVariant var(typeCode, data); - tr->deleteObject(data); - return var; - } + QVariant var(typeCode, (void*)0); + void* args[] = { var.data() }; + tr->toCpp(pyObj, args); + return var; } } // Is a shiboken type not known by Qt @@ -140,28 +133,25 @@ struct Converter<QVariant> return QVariant(); Shiboken::AutoDecRef element(PySequence_GetItem(list, 0)); - int typeId = 0; - QByteArray typeName = resolveMetaType(element.cast<PyTypeObject*>(), typeId); - if (!typeName.isEmpty()) { - QByteArray listTypeName = QByteArray("QList<"+typeName+">"); + int typeId; + const char* typeName = resolveMetaType(element.cast<PyTypeObject*>(), &typeId); + if (typeName) { + QByteArray listTypeName("QList<"); + listTypeName += typeName; + listTypeName += '>'; typeId = QMetaType::type(listTypeName); if (typeId > 0) { Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(listTypeName); if (!tr) { qWarning() << "TypeResolver for :" << listTypeName << "not registered."; - return QVariant(); } else { - void *data = 0; - data = tr->toCpp(list, &data, true); - QVariant var(typeId, data); - tr->deleteObject(data); + QVariant var(typeId, (void*)0); + void* args[] = { var.data(), 0 }; + tr->toCpp(list, args); return var; } - } else { - return QVariant(); } } - return QVariant(); } diff --git a/libpyside/pysidemetafunction.cpp b/libpyside/pysidemetafunction.cpp index bcccbb82a..bee793cc6 100644 --- a/libpyside/pysidemetafunction.cpp +++ b/libpyside/pysidemetafunction.cpp @@ -98,29 +98,26 @@ void functionFree(void *self) PyObject* functionCall(PyObject* self, PyObject* args, PyObject* kw) { + static Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get("QVariant"); + Q_ASSERT(typeResolver); + QGenericArgument gArgs[10]; + QVariant vArgs[10]; PySideMetaFunction* function = reinterpret_cast<PySideMetaFunction*>(self); - QList<QVariant*> vArgs; QMetaMethod method = function->d->method; - QList<QByteArray> pTypes = method.parameterTypes(); - int numArgs = pTypes.size(); + int argsGiven = method.parameterTypes().size(); - Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get("QVariant"); - Q_ASSERT(typeResolver); - for(int i=0; i < numArgs; i++) { - QVariant *vArg; + for (int i = 0; i < argsGiven; ++i) { Shiboken::AutoDecRef pyArg(PySequence_GetItem(args, i)); - typeResolver->toCpp(pyArg, (void**)&vArg, true); - vArgs.append(vArg); - gArgs[i] = Q_ARG(QVariant, *vArg); + gArgs[i] = Q_ARG(QVariant, vArgs[i]); + void* v[1] = { &vArgs[i] }; + typeResolver->toCpp(pyArg, v); } 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]); - while(!vArgs.isEmpty()) - delete vArgs.takeFirst(); if (retVariant.isValid()) return typeResolver->toPython(&retVariant); diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index d4b0cb716..5ff62bedf 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -70,9 +70,17 @@ PyObjectWrapper::PyObjectWrapper(const PyObjectWrapper &other) PyObjectWrapper::~PyObjectWrapper() { + Shiboken::GilState gil; 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 { @@ -179,24 +187,26 @@ static bool emitNormalSignal(QObject* source, int signalIndex, const char* signa { Shiboken::AutoDecRef sequence(PySequence_Fast(args, 0)); int argsGiven = PySequence_Fast_GET_SIZE(sequence.object()); + if (argsGiven > argTypes.count()) { PyErr_Format(PyExc_TypeError, "%s only accepts %d arguments, %d given!", signal, argTypes.count(), argsGiven); return false; } - void** signalArgs = new void*[argsGiven+1]; - void** signalValues = new void*[argsGiven]; + QVariant* signalValues = new QVariant[argsGiven]; + void** signalArgs = new void*[argsGiven + 1]; signalArgs[0] = 0; int 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) { - typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i), &signalValues[i], true); - if (Shiboken::TypeResolver::getType(qPrintable(argTypes[i])) == Shiboken::TypeResolver::ObjectType) - signalArgs[i+1] = &signalValues[i]; - else - signalArgs[i+1] = signalValues[i]; + int typeId = QMetaType::type(typeName); + if (Shiboken::TypeResolver::getType(typeName) == Shiboken::TypeResolver::ValueType) + signalValues[i] = QVariant(typeId, (void*) 0); + signalArgs[i+1] = signalValues[i].data(); + typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i), &signalArgs[i+1]); } else { PyErr_Format(PyExc_TypeError, "Unknown type used to emit a signal: %s", qPrintable(argTypes[i])); break; @@ -207,10 +217,6 @@ static bool emitNormalSignal(QObject* source, int signalIndex, const char* signa if (ok) 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[] signalValues; diff --git a/libpyside/signalmanager.h b/libpyside/signalmanager.h index 91c86e02e..f6ce1fb0c 100644 --- a/libpyside/signalmanager.h +++ b/libpyside/signalmanager.h @@ -43,6 +43,7 @@ public: PyObjectWrapper(const PyObjectWrapper &other); ~PyObjectWrapper(); operator PyObject*() const; + PyObjectWrapper& operator=(const PyObjectWrapper &other); private: PyObject* m_me; void* m_data; //future |