aboutsummaryrefslogtreecommitdiffstats
path: root/libpyside/signalmanager.cpp
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2011-07-21 17:57:17 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:54:38 -0300
commitec45601aa14400b3d3e13f3f326e57d534da6ad2 (patch)
tree6ebaa966bc6518e85408a1807e5741690622f87a /libpyside/signalmanager.cpp
parent9dd8f98e736dc70ae4f1a78f13ee643a63aa2e47 (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.cpp68
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;
+}
+