diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2010-10-07 17:25:56 -0300 |
---|---|---|
committer | Marcelo Lira <marcelo.lira@openbossa.org> | 2010-10-11 17:47:03 -0300 |
commit | 7fab5c03a94a24f6496ad129485244f7d6f4f994 (patch) | |
tree | a2acc73a45ad9595cfff1726600c257785b6a8a7 /libpyside | |
parent | 4b3b56acd7caaa7ff0d9c7b913cfe73db12afd4a (diff) |
Signal objects redirect calls for homonymous methods.
Diffstat (limited to 'libpyside')
-rw-r--r-- | libpyside/qsignal.cpp | 242 | ||||
-rw-r--r-- | libpyside/qsignal.h | 7 |
2 files changed, 156 insertions, 93 deletions
diff --git a/libpyside/qsignal.cpp b/libpyside/qsignal.cpp index 46cb1b694..a3e1c94fb 100644 --- a/libpyside/qsignal.cpp +++ b/libpyside/qsignal.cpp @@ -52,6 +52,7 @@ struct SignalData { char* signalName; char** signatures; int signaturesSize; + PyObject* homonymousMethod; }; static int signalTpInit(PyObject*, PyObject*, PyObject*); @@ -64,54 +65,57 @@ static PyObject* signalInstanceDisconnect(PyObject*, PyObject*); static PyObject* signalInstanceEmit(PyObject*, PyObject*); static PyObject* signalInstanceGetItem(PyObject*, PyObject*); +static PyObject* signalInstanceCall(PyObject* self, PyObject* args, PyObject* kw); +static PyObject* signalCall(PyObject*, PyObject*, PyObject*); + PyTypeObject PySideSignalType = { PyObject_HEAD_INIT(0) - 0, /*ob_size*/ - "PySide.QtCore."SIGNAL_CLASS_NAME, /*tp_name*/ - sizeof(SignalData), /*tp_basicsize*/ - 0, /*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*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - SIGNAL_CLASS_NAME, /*tp_doc */ - 0, /*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 */ - signalTpInit, /*tp_init */ - 0, /*tp_alloc */ - PyType_GenericNew, /*tp_new */ - signalFree, /*tp_free */ - 0, /*tp_is_gc */ - 0, /*tp_bases */ - 0, /*tp_mro */ - 0, /*tp_cache */ - 0, /*tp_subclasses */ - 0, /*tp_weaklist */ - 0, /*tp_del */ + /*ob_size*/ 0, + /*tp_name*/ "PySide.QtCore."SIGNAL_CLASS_NAME, + /*tp_basicsize*/ sizeof(SignalData), + /*tp_itemsize*/ 0, + /*tp_dealloc*/ &Shiboken::deallocWrapper, + /*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*/ signalCall, + /*tp_str*/ 0, + /*tp_getattro*/ 0, + /*tp_setattro*/ 0, + /*tp_as_buffer*/ 0, + /*tp_flags*/ Py_TPFLAGS_DEFAULT, + /*tp_doc*/ SIGNAL_CLASS_NAME, + /*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*/ signalTpInit, + /*tp_alloc*/ 0, + /*tp_new*/ PyType_GenericNew, + /*tp_free*/ signalFree, + /*tp_is_gc*/ 0, + /*tp_bases*/ 0, + /*tp_mro*/ 0, + /*tp_cache*/ 0, + /*tp_subclasses*/ 0, + /*tp_weaklist*/ 0, + /*tp_del*/ 0, }; static PyMethodDef SignalInstance_methods[] = { @@ -129,52 +133,52 @@ static PyMappingMethods SignalInstance_as_mapping = { PyTypeObject PySideSignalInstanceType = { PyObject_HEAD_INIT(0) - 0, /*ob_size*/ - "PySide.QtCore."SIGNAL_CLASS_NAME, /*tp_name*/ - sizeof(PySideSignalInstanceData),/*tp_basicsize*/ - 0, /*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*/ - &SignalInstance_as_mapping,/*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - SIGNAL_CLASS_NAME, /*tp_doc */ - 0, /*tp_traverse */ - 0, /*tp_clear */ - 0, /*tp_richcompare */ - 0, /*tp_weaklistoffset */ - 0, /*tp_iter */ - 0, /*tp_iternext */ - SignalInstance_methods, /*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 */ - PyType_GenericNew, /*tp_new */ - signalInstanceFree, /*tp_free */ - 0, /*tp_is_gc */ - 0, /*tp_bases */ - 0, /*tp_mro */ - 0, /*tp_cache */ - 0, /*tp_subclasses */ - 0, /*tp_weaklist */ - 0, /*tp_del */ + /*ob_size*/ 0, + /*tp_name*/ "PySide.QtCore."SIGNAL_CLASS_NAME, + /*tp_basicsize*/ sizeof(PySideSignalInstanceData), + /*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*/ &SignalInstance_as_mapping, + /*tp_hash*/ 0, + /*tp_call*/ signalInstanceCall, + /*tp_str*/ 0, + /*tp_getattro*/ 0, + /*tp_setattro*/ 0, + /*tp_as_buffer*/ 0, + /*tp_flags*/ Py_TPFLAGS_DEFAULT, + /*tp_doc*/ SIGNAL_CLASS_NAME, + /*tp_traverse*/ 0, + /*tp_clear*/ 0, + /*tp_richcompare*/ 0, + /*tp_weaklistoffset*/ 0, + /*tp_iter*/ 0, + /*tp_iternext*/ 0, + /*tp_methods*/ SignalInstance_methods, + /*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*/ signalInstanceFree, + /*tp_is_gc*/ 0, + /*tp_bases*/ 0, + /*tp_mro*/ 0, + /*tp_cache*/ 0, + /*tp_subclasses*/ 0, + /*tp_weaklist*/ 0, + /*tp_del*/ 0, }; int signalTpInit(PyObject* self, PyObject* args, PyObject* kwds) @@ -224,6 +228,8 @@ void signalFree(void *self) free(data->signalName); data->initialized = 0; data->signaturesSize = 0; + Py_XDECREF(data->homonymousMethod); + data->homonymousMethod = 0; pySelf->ob_type->tp_base->tp_free(self); } @@ -236,8 +242,10 @@ void signalInstanceFree(void* self) free(data->signalName); free(data->signature); + Py_XDECREF(data->homonymousMethod); + if (data->next) { - Py_XDECREF(data->next); + Py_DECREF(data->next); data->next = 0; } pySelf->ob_type->tp_base->tp_free(self); @@ -385,6 +393,38 @@ PyObject* signalInstanceDisconnect(PyObject* self, PyObject* args) return 0; } +PyObject* signalCall(PyObject* self, PyObject* args, PyObject* kw) +{ + SignalData* signalData = reinterpret_cast<SignalData*>(self); + + if (!signalData->homonymousMethod) { + PyErr_SetString(PyExc_TypeError, "native Qt signal is not callable"); + return 0; + } + + descrgetfunc getDescriptor = signalData->homonymousMethod->ob_type->tp_descr_get; + Shiboken::AutoDecRef homonymousMethod(getDescriptor(signalData->homonymousMethod, 0, 0)); + + if (PyCFunction_GET_FLAGS(homonymousMethod.object()) & METH_STATIC) + return PyCFunction_Call(homonymousMethod, args, kw); + + ternaryfunc callFunc = signalData->homonymousMethod->ob_type->tp_call; + return callFunc(homonymousMethod, args, kw); +} + +PyObject* signalInstanceCall(PyObject* self, PyObject* args, PyObject* kw) +{ + PySideSignalInstanceData* signalData = reinterpret_cast<PySideSignalInstanceData*>(self); + if (!signalData->homonymousMethod) { + PyErr_SetString(PyExc_TypeError, "native Qt signal is not callable"); + return 0; + } + + descrgetfunc getDescriptor = signalData->homonymousMethod->ob_type->tp_descr_get; + Shiboken::AutoDecRef homonymousMethod(getDescriptor(signalData->homonymousMethod, signalData->source, 0)); + return PyCFunction_Call(homonymousMethod, args, kw); +} + } // extern "C" namespace PySide @@ -503,6 +543,11 @@ void signalInstanceInitialize(PyObject* instance, PyObject* name, SignalData* da self->source = source; self->signature = signalBuildSignature(self->signalName, data->signatures[index]); + self->homonymousMethod = 0; + if (data->homonymousMethod) { + self->homonymousMethod = data->homonymousMethod; + Py_INCREF(self->homonymousMethod); + } index++; if (index < data->signaturesSize) { @@ -531,6 +576,7 @@ PyObject* signalNew(const char* name, ...) self->signaturesSize = 0; self->signatures = 0; self->initialized = 0; + self->homonymousMethod = 0; va_start(listSignatures, name); sig = va_arg(listSignatures, char*); @@ -556,5 +602,15 @@ PyObject* signalBuildQtCompatible(const char* signature) return ret; } +void addSignalToWrapper(Shiboken::SbkBaseWrapperType* wrapperType, const char* signalName, PyObject* signal) +{ + PyObject* typeDict = wrapperType->super.ht_type.tp_dict; + PyObject* homonymousMethod; + if ((homonymousMethod = PyDict_GetItemString(typeDict, signalName))) { + Py_INCREF(homonymousMethod); + reinterpret_cast<SignalData*>(signal)->homonymousMethod = homonymousMethod; + } + PyDict_SetItemString(typeDict, signalName, signal); +} } //namespace PySide diff --git a/libpyside/qsignal.h b/libpyside/qsignal.h index 617749608..7a8a34900 100644 --- a/libpyside/qsignal.h +++ b/libpyside/qsignal.h @@ -27,6 +27,11 @@ #include <Python.h> #include <QObject> +namespace Shiboken +{ + struct SbkBaseWrapperType; +} + extern "C" { extern PYSIDE_API PyTypeObject PySideSignalInstanceType; @@ -37,6 +42,7 @@ extern "C" char* signalName; char* signature; PyObject* source; + PyObject* homonymousMethod; PyObject* next; }; }; //extern "C" @@ -46,6 +52,7 @@ namespace PySide PYSIDE_API PyObject* signalNew(const char* name, ...); PYSIDE_API void signalUpdateSource(PyObject* source); +PYSIDE_API void addSignalToWrapper(Shiboken::SbkBaseWrapperType* wrapperType, const char* signalName, PyObject* signal); } //namespace PySide |