diff options
author | Renato Filho <renato.filho@openbossa.org> | 2011-07-21 17:57:17 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:54:38 -0300 |
commit | ec45601aa14400b3d3e13f3f326e57d534da6ad2 (patch) | |
tree | 6ebaa966bc6518e85408a1807e5741690622f87a /libpyside/signalmanager.cpp | |
parent | 9dd8f98e736dc70ae4f1a78f13ee643a63aa2e47 (diff) |
Implemented DynamicMetaObject optiomizations.
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
Lauro Neto <lauro.neto@openbossa.org>
Diffstat (limited to 'libpyside/signalmanager.cpp')
-rw-r--r-- | libpyside/signalmanager.cpp | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index bbbc1d3f0..b24d0b97e 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -25,6 +25,7 @@ #include "pysideproperty.h" #include "pysideproperty_p.h" #include "pyside.h" +#include "dynamicqmetaobject.h" #include <QHash> #include <QStringList> @@ -46,6 +47,14 @@ #define PYTHON_TYPE "PyObject" +namespace { + static PyObject *metaObjectAttr = 0; + static void destroyMetaObject(void* obj) + { + delete reinterpret_cast<PySide::DynamicQMetaObject*>(obj); + } +} + namespace PySide { static int callMethod(QObject* object, int id, void** args); @@ -189,6 +198,9 @@ SignalManager::SignalManager() : m_d(new SignalManagerPrivate) TypeResolver::createValueTypeResolver<PyObjectWrapper>("object"); TypeResolver::createValueTypeResolver<PyObjectWrapper>("PySide::PyObjectWrapper"); PySide::registerCleanupFunction(clearSignalManager); + + if (!metaObjectAttr) + metaObjectAttr = PyString_FromString("__METAOBJECT__"); } void SignalManager::clear() @@ -225,7 +237,12 @@ void SignalManager::globalReceiverDisconnectNotify(QObject* source, int slotInde void SignalManager::addGlobalSlot(const char* slot, PyObject* callback) { - m_d->m_globalReceiver.addSlot(slot, callback); + addGlobalSlotGetIndex(slot, callback); +} + +int SignalManager::addGlobalSlotGetIndex(const char* slot, PyObject* callback) +{ + return m_d->m_globalReceiver.addSlot(slot, callback); } static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* args) @@ -412,9 +429,14 @@ static int PySide::callMethod(QObject* object, int id, void** args) } return -1; } - bool SignalManager::registerMetaMethod(QObject* source, const char* signature, QMetaMethod::MethodType type) { + int ret = registerMetaMethodGetIndex(source, signature, type); + return (ret != -1); +} + +int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type) +{ Q_ASSERT(source); const QMetaObject* metaObject = source->metaObject(); int methodIndex = metaObject->indexOfMethod(signature); @@ -423,19 +445,51 @@ bool SignalManager::registerMetaMethod(QObject* source, const char* signature, Q SbkObject* self = Shiboken::BindingManager::instance().retrieveWrapper(source); if (!Shiboken::Object::hasCppWrapper(self)) { qWarning() << "Invalid Signal signature:" << signature; - return false; + return -1; } else { - PySide::DynamicQMetaObject* dynMetaObj = reinterpret_cast<PySide::DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject)); + DynamicQMetaObject *dmo = 0; + PyObject *pySelf = reinterpret_cast<PyObject*>(self); + PyObject* dict = self->ob_dict; + + // Create a instance meta object + if (!dict || !PyDict_Contains(dict, metaObjectAttr)) { + dmo = new DynamicQMetaObject(pySelf->ob_type, metaObject); + PyObject *pyDmo = PyCObject_FromVoidPtr(dmo, destroyMetaObject); + PyObject_SetAttr(pySelf, metaObjectAttr, pyDmo); + Py_DECREF(pyDmo); + } else { + dmo = reinterpret_cast<DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject)); + } + if (type == QMetaMethod::Signal) - dynMetaObj->addSignal(signature); + return dmo->addSignal(signature); else - dynMetaObj->addSlot(signature); + return dmo->addSlot(signature); } } - return true; + return methodIndex; } bool SignalManager::hasConnectionWith(const QObject *object) { return m_d->m_globalReceiver.hasConnectionWith(object); } + +const QMetaObject* SignalManager::retriveMetaObject(PyObject *self) +{ + Shiboken::GilState gil; + DynamicQMetaObject *mo = 0; + Q_ASSERT(self); + + PyObject* dict = reinterpret_cast<SbkObject*>(self)->ob_dict; + if (dict && PyDict_Contains(dict, metaObjectAttr)) { + PyObject *pyMo = PyDict_GetItem(dict, metaObjectAttr); + mo = reinterpret_cast<DynamicQMetaObject*>(PyCObject_AsVoidPtr(pyMo)); + } else { + mo = reinterpret_cast<DynamicQMetaObject*>(Shiboken::Object::getTypeUserData(reinterpret_cast<SbkObject*>(self))); + } + + mo->update(); + return mo; +} + |