diff options
author | renatofilho <renato.filho@openbossa.org> | 2010-11-05 16:34:11 -0300 |
---|---|---|
committer | renatofilho <renato.filho@openbossa.org> | 2010-11-05 19:01:07 -0300 |
commit | 257e0cdf188172a9548e652ca5763bb124bb58ea (patch) | |
tree | c80ef9004c247d81c60b32535e3bf847aa0fafea | |
parent | 5371e403ffe741119ba0803077b772ca84f3fce3 (diff) | |
download | pyside-257e0cdf188172a9548e652ca5763bb124bb58ea.tar.gz pyside-257e0cdf188172a9548e652ca5763bb124bb58ea.tar.xz pyside-257e0cdf188172a9548e652ca5763bb124bb58ea.zip |
Implemented PySideMetaFunction class used to call dynamic slots.
Reviewer: Hugo Parente Lima <hugo.pl@gmail.com>
Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r-- | libpyside/CMakeLists.txt | 16 | ||||
-rw-r--r-- | libpyside/pyside.cpp | 2 | ||||
-rw-r--r-- | libpyside/pysidemetafunction.cpp | 162 | ||||
-rw-r--r-- | libpyside/pysidemetafunction.h | 59 | ||||
-rw-r--r-- | libpyside/pysidemetafunction_p.h | 35 |
5 files changed, 267 insertions, 7 deletions
diff --git a/libpyside/CMakeLists.txt b/libpyside/CMakeLists.txt index 939bcc4..04bf0a7 100644 --- a/libpyside/CMakeLists.txt +++ b/libpyside/CMakeLists.txt @@ -1,13 +1,14 @@ project(libpyside) set(libpyside_SRC -dynamicqmetaobject.cpp -signalmanager.cpp -globalreceiver.cpp -pysidesignal.cpp -pysideslot.cpp -pysideproperty.cpp -pyside.cpp + dynamicqmetaobject.cpp + signalmanager.cpp + globalreceiver.cpp + pysidemetafunction.cpp + pysidesignal.cpp + pysideslot.cpp + pysideproperty.cpp + pyside.cpp ) include_directories(${CMAKE_CURRENT_SOURCE_DIR} @@ -37,6 +38,7 @@ set(libpyside_HEADERS pysidemacros.h signalmanager.h pyside.h + pysidemetafunction.h pysidesignal.h pysideproperty.h ) diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp index 833ae9c..7f2e96a 100644 --- a/libpyside/pyside.cpp +++ b/libpyside/pyside.cpp @@ -27,6 +27,7 @@ #include "pysidesignal.h" #include "pysidesignal_p.h" #include "pysideslot_p.h" +#include "pysidemetafunction_p.h" #include <basewrapper.h> #include <conversions.h> @@ -46,6 +47,7 @@ void init(PyObject *module) Signal::init(module); Slot::init(module); Property::init(module); + MetaFunction::init(module); // Init signal manager, so it will register some meta types used by QVariant. SignalManager::instance(); } diff --git a/libpyside/pysidemetafunction.cpp b/libpyside/pysidemetafunction.cpp new file mode 100644 index 0000000..bcccbb8 --- /dev/null +++ b/libpyside/pysidemetafunction.cpp @@ -0,0 +1,162 @@ +/* + * This file is part of the PySide project. + * + * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <Python.h> +#include "pysidemetafunction.h" + +#include <shiboken.h> +#include <QObject> +#include <QMetaMethod> +#include <QDebug> + +extern "C" +{ + +struct PySideMetaFunctionPrivate +{ + QObject* qobject; + QMetaMethod method; +}; + +//methods +static void functionFree(void*); +static PyObject* functionCall(PyObject*, PyObject*, PyObject*); + +PyTypeObject PySideMetaFunctionType = { + PyObject_HEAD_INIT(0) + /*ob_size*/ 0, + /*tp_name*/ "PySide.MetaFunction", + /*tp_basicsize*/ sizeof(PySideMetaFunction), + /*tp_itemsize*/ 0, + /*tp_dealloc*/ 0, + /*tp_print*/ 0, + /*tp_getattr*/ 0, + /*tp_setattr*/ 0, + /*tp_compare*/ 0, + /*tp_repr*/ 0, + /*tp_as_number*/ 0, + /*tp_as_sequence*/ 0, + /*tp_as_mapping*/ 0, + /*tp_hash*/ 0, + /*tp_call*/ functionCall, + /*tp_str*/ 0, + /*tp_getattro*/ 0, + /*tp_setattro*/ 0, + /*tp_as_buffer*/ 0, + /*tp_flags*/ Py_TPFLAGS_DEFAULT, + /*tp_doc*/ "MetaFunction", + /*tp_traverse*/ 0, + /*tp_clear*/ 0, + /*tp_richcompare*/ 0, + /*tp_weaklistoffset*/ 0, + /*tp_iter*/ 0, + /*tp_iternext*/ 0, + /*tp_methods*/ 0, + /*tp_members*/ 0, + /*tp_getset*/ 0, + /*tp_base*/ 0, + /*tp_dict*/ 0, + /*tp_descr_get*/ 0, + /*tp_descr_set*/ 0, + /*tp_dictoffset*/ 0, + /*tp_init*/ 0, + /*tp_alloc*/ 0, + /*tp_new*/ PyType_GenericNew, + /*tp_free*/ functionFree, + /*tp_is_gc*/ 0, + /*tp_bases*/ 0, + /*tp_mro*/ 0, + /*tp_cache*/ 0, + /*tp_subclasses*/ 0, + /*tp_weaklist*/ 0, + /*tp_del*/ 0, +}; + +void functionFree(void *self) +{ + PySideMetaFunction* function = reinterpret_cast<PySideMetaFunction*>(self); + delete function->d; +} + +PyObject* functionCall(PyObject* self, PyObject* args, PyObject* kw) +{ + QGenericArgument gArgs[10]; + 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); + for(int i=0; i < numArgs; i++) { + QVariant *vArg; + Shiboken::AutoDecRef pyArg(PySequence_GetItem(args, i)); + typeResolver->toCpp(pyArg, (void**)&vArg, true); + vArgs.append(vArg); + gArgs[i] = Q_ARG(QVariant, *vArg); + } + + 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); + + Py_RETURN_NONE; +} + +} // 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 + diff --git a/libpyside/pysidemetafunction.h b/libpyside/pysidemetafunction.h new file mode 100644 index 0000000..0d4e16f --- /dev/null +++ b/libpyside/pysidemetafunction.h @@ -0,0 +1,59 @@ +/* + * This file is part of the PySide project. + * + * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PYSIDE_FUNCTION_H +#define PYSIDE_METAFUNCTION_H + +#include <QObject> +#include <QString> +#include <QStringList> + +#include <pysidemacros.h> +#include <Python.h> + +extern "C" +{ + extern PYSIDE_API PyTypeObject PySideMetaFunctionType; + + struct PySideMetaFunctionPrivate; + struct PYSIDE_API PySideMetaFunction + { + PyObject_HEAD + PySideMetaFunctionPrivate* d; + }; +}; //extern "C" + +namespace PySide { namespace MetaFunction { + +/** + * This function creates a MetaFunction object + * + * @param obj the QObject witch this fuction is part of + * @param methodIndex The index of this function on MetaObject + * @return Return a new reference of PySideMetaFunction + **/ +PYSIDE_API PySideMetaFunction* newObject(QObject* obj, int methodIndex); + +} //namespace MetaFunction +} //namespace PySide + +#endif diff --git a/libpyside/pysidemetafunction_p.h b/libpyside/pysidemetafunction_p.h new file mode 100644 index 0000000..808714e --- /dev/null +++ b/libpyside/pysidemetafunction_p.h @@ -0,0 +1,35 @@ +/* + * This file is part of the PySide project. + * + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PYSIDE_METAFUNCTION_P_H +#define PYSIDE_METAFUNCTION_P_H + +#include <Python.h> + +namespace PySide { namespace MetaFunction { + + void init(PyObject* module); + +} //namespace MetaFunction +} //namespace PySide + +#endif |