From 67d6455fa52921d631001e7938aa7b9fa40b45aa Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 26 Oct 2011 20:17:56 -0200 Subject: Unify the code used to do QObject meta calls. --- libpyside/pysidemetafunction.cpp | 106 +++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 42 deletions(-) (limited to 'libpyside/pysidemetafunction.cpp') diff --git a/libpyside/pysidemetafunction.cpp b/libpyside/pysidemetafunction.cpp index de4d3244a..cb6b8612e 100644 --- a/libpyside/pysidemetafunction.cpp +++ b/libpyside/pysidemetafunction.cpp @@ -21,6 +21,7 @@ */ #include #include "pysidemetafunction.h" +#include "pysidemetafunction_p.h" #include #include @@ -98,15 +99,55 @@ void functionFree(void *self) PyObject* functionCall(PyObject* self, PyObject* args, PyObject* kw) { PySideMetaFunction* function = reinterpret_cast(self); - QMetaMethod method = function->d->method; + + PyObject* retVal; + if (!PySide::MetaFunction::call(function->d->qobject, function->d->method.methodIndex(), args, &retVal)) + return 0; + return retVal; +} + +} // extern "C" + +namespace PySide { namespace MetaFunction { + +void init(PyObject* module) +{ + if (PyType_Ready(&PySideMetaFunctionType) < 0) + return; + + PyModule_AddObject(module, "MetaFunction", ((PyObject*)&PySideMetaFunctionType)); +} + +PySideMetaFunction* newObject(QObject* source, int methodIndex) +{ + if (methodIndex >= source->metaObject()->methodCount()) + return 0; + + QMetaMethod method = source->metaObject()->method(methodIndex); + if ((method.methodType() == QMetaMethod::Slot) || + (method.methodType() == QMetaMethod::Method)) { + PySideMetaFunction* function = PyObject_New(PySideMetaFunction, &PySideMetaFunctionType); + function->d = new PySideMetaFunctionPrivate(); + function->d->qobject = source; + function->d->method = method; + return function; + } + return 0; +} + +bool call(QObject* self, int methodIndex, PyObject* args, PyObject** retVal) +{ + + QMetaMethod method = self->metaObject()->method(methodIndex); QList argTypes = method.parameterTypes(); // args given plus return type - int numArgs = PyTuple_GET_SIZE(args) + 1; + Shiboken::AutoDecRef sequence(PySequence_Fast(args, 0)); + int numArgs = PySequence_Fast_GET_SIZE(sequence.object()) + 1; if (numArgs - 1 != argTypes.count()) { PyErr_Format(PyExc_TypeError, "%s only accepts %d arguments, %d given!", method.signature(), argTypes.count(), numArgs); - return 0; + return false; } QVariant* methValues = new QVariant[numArgs]; @@ -133,63 +174,44 @@ PyObject* functionCall(PyObject* self, PyObject* args, PyObject* kw) if (Shiboken::TypeResolver::getType(typeName) == Shiboken::TypeResolver::ValueType) { int typeId = QMetaType::type(typeName); if (!typeId) { - PyErr_Format(PyExc_TypeError, "Value type used on signal needs to be registered on meta type: %s", typeName.data()); + PyErr_Format(PyExc_TypeError, "Value types used on meta functions (including signals) need to be " + "registered on meta type: %s", typeName.data()); break; } methValues[i] = QVariant(typeId, (void*) 0); } methArgs[i] = methValues[i].data(); if (i != 0) // Don't do this for return type - typeResolver->toCpp(PyTuple_GET_ITEM(args, i - 1), &methArgs[i]); + typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i - 1), &methArgs[i]); } else { - PyErr_Format(PyExc_TypeError, "Unknown type used to emit a signal: %s", argTypes[i].constData()); + PyErr_Format(PyExc_TypeError, "Unknown type used to call meta function (that may be a signal): %s", argTypes[i].constData()); break; } } bool ok = i == numArgs; - if (ok) - QMetaObject::metacall(function->d->qobject, QMetaObject::InvokeMetaMethod, method.methodIndex(), methArgs); - - static Shiboken::TypeResolver* qVariantTypeResolver = Shiboken::TypeResolver::get("QVariant"); - Q_ASSERT(qVariantTypeResolver); - - PyObject* retVal = qVariantTypeResolver->toPython(&methValues[0]); + if (ok) { + QMetaObject::metacall(self, QMetaObject::InvokeMetaMethod, method.methodIndex(), methArgs); + + if (retVal) { + if (methArgs[0]) { + static Shiboken::TypeResolver* qVariantTypeResolver = Shiboken::TypeResolver::get("QVariant"); + Q_ASSERT(qVariantTypeResolver); + + *retVal = qVariantTypeResolver->toPython(&methValues[0]); + } else { + *retVal = Py_None; + Py_INCREF(*retVal); + } + } + } delete[] methArgs; delete[] methValues; - return retVal; + return ok; } -} // extern "C" - -namespace PySide { namespace MetaFunction { - -void init(PyObject* module) -{ - if (PyType_Ready(&PySideMetaFunctionType) < 0) - return; - - PyModule_AddObject(module, "MetaFunction", ((PyObject*)&PySideMetaFunctionType)); -} - -PySideMetaFunction* newObject(QObject* source, int methodIndex) -{ - if (methodIndex >= source->metaObject()->methodCount()) - return 0; - - QMetaMethod method = source->metaObject()->method(methodIndex); - if ((method.methodType() == QMetaMethod::Slot) || - (method.methodType() == QMetaMethod::Method)) { - PySideMetaFunction* function = PyObject_New(PySideMetaFunction, &PySideMetaFunctionType); - function->d = new PySideMetaFunctionPrivate(); - function->d->qobject = source; - function->d->method = method; - return function; - } - return 0; -} } //namespace MetaFunction } //namespace PySide -- cgit v1.2.3