aboutsummaryrefslogtreecommitdiffstats
path: root/PySide/QtCore
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2011-08-18 17:51:13 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:54:46 -0300
commit7b2c4242ad1d86bcc2da43a8482dbd39b3ac988e (patch)
treeaffbe074d73898afb10de5ae4685d698c5fb2f70 /PySide/QtCore
parentd00af325c696acc390dd3565be82cd22b3b94658 (diff)
Implemented GlobalReceiverV2.
A new implementation of GlobalRecever that optmize the signal connection. Fixes bug #928. Reviewer: Marcelo Lira <marcelo.lira@openbossa.org> Luciano Wolf <luciano.wolf@openbossa.org>
Diffstat (limited to 'PySide/QtCore')
-rw-r--r--PySide/QtCore/glue/qobject_connect.cpp44
-rw-r--r--PySide/QtCore/typesystem_core.xml20
2 files changed, 45 insertions, 19 deletions
diff --git a/PySide/QtCore/glue/qobject_connect.cpp b/PySide/QtCore/glue/qobject_connect.cpp
index 3296c2e89..30e0b9aa3 100644
--- a/PySide/QtCore/glue/qobject_connect.cpp
+++ b/PySide/QtCore/glue/qobject_connect.cpp
@@ -8,7 +8,7 @@ static bool isDecorator(PyObject* method, PyObject* self)
reinterpret_cast<PyMethodObject*>(method)->im_func;
}
-static bool getReceiver(PyObject* callback, QObject** receiver, PyObject** self)
+static bool getReceiver(QObject *source, PyObject* callback, QObject** receiver, PyObject** self)
{
bool forceGlobalReceiver = false;
if (PyMethod_Check(callback)) {
@@ -29,7 +29,7 @@ static bool getReceiver(PyObject* callback, QObject** receiver, PyObject** self)
bool usingGlobalReceiver = !*receiver || forceGlobalReceiver;
if (usingGlobalReceiver) {
PySide::SignalManager& signalManager = PySide::SignalManager::instance();
- *receiver = signalManager.globalReceiver();
+ *receiver = signalManager.globalReceiver(source, callback);
}
return usingGlobalReceiver;
@@ -68,7 +68,7 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
// Extract receiver from callback
QObject* receiver = 0;
PyObject* self = 0;
- bool usingGlobalReceiver = getReceiver(callback, &receiver, &self);
+ bool usingGlobalReceiver = getReceiver(source, callback, &receiver, &self);
if (receiver == 0 && self == 0)
return false;
@@ -79,20 +79,27 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
if (slotIndex == -1) {
if (!usingGlobalReceiver && self && !Shiboken::Object::hasCppWrapper((SbkObject*)self)) {
qWarning() << "You can't add dynamic slots on an object originated from C++.";
+ if (usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver);
+
return false;
}
if (usingGlobalReceiver)
- slotIndex = signalManager.addGlobalSlotGetIndex(slot, callback);
+ slotIndex = signalManager.globalReceiverSlotIndex(receiver, slot);
else
slotIndex = PySide::SignalManager::registerMetaMethodGetIndex(receiver, slot, QMetaMethod::Slot);
- if (slotIndex == -1)
+ if (slotIndex == -1) {
+ if (usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver);
+
return false;
+ }
}
if (QMetaObject::connect(source, signalIndex, receiver, slotIndex, type)) {
if (usingGlobalReceiver)
- signalManager.globalReceiverConnectNotify(source, slotIndex);
+ signalManager.notifyGlobalReceiver(receiver);
#ifndef AVOID_PROTECTED_HACK
source->connectNotify(signal - 1);
#else
@@ -103,6 +110,10 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
return true;
}
+
+ if (usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver);
+
return false;
}
@@ -117,27 +128,30 @@ static bool qobjectDisconnectCallback(QObject* source, const char* signal, PyObj
// Extract receiver from callback
QObject* receiver = 0;
PyObject* self = 0;
- bool usingGlobalReceiver = getReceiver(callback, &receiver, &self);
+ bool usingGlobalReceiver = getReceiver(NULL, callback, &receiver, &self);
if (receiver == 0 && self == 0)
return false;
const QMetaObject* metaObject = receiver->metaObject();
+ int signalIndex = source->metaObject()->indexOfSignal(++signal);
+ int slotIndex = -1;
+
const QByteArray callbackSig = PySide::Signal::getCallbackSignature(signal, receiver, callback, usingGlobalReceiver).toAscii();
QByteArray qtSlotName(callbackSig);
- qtSlotName = qtSlotName.prepend('1');
- if (QObject::disconnect(source, signal, receiver, qtSlotName.constData())) {
- if (usingGlobalReceiver) {
- int slotIndex = metaObject->indexOfSlot(callbackSig.constData());
- signalManager.globalReceiverDisconnectNotify(source, slotIndex);
+ slotIndex = metaObject->indexOfSlot(qtSlotName);
+
+ if (QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex)) {
+ if (usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver);
+
#ifndef AVOID_PROTECTED_HACK
- source->disconnectNotify(signal - 1);
+ source->disconnectNotify(qtSlotName);
#else
// Need to cast to QObjectWrapper* and call the public version of
// connectNotify when avoiding the protected hack.
- reinterpret_cast<QObjectWrapper*>(source)->disconnectNotify(signal - 1);
+ reinterpret_cast<QObjectWrapper*>(source)->disconnectNotify(qtSlotName);
#endif
- }
return true;
}
return false;
diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml
index ecbe25059..83f69dffc 100644
--- a/PySide/QtCore/typesystem_core.xml
+++ b/PySide/QtCore/typesystem_core.xml
@@ -1489,10 +1489,9 @@
<inject-code class="target" position="beginning">
// Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife
int ret = %CPPSELF.%FUNCTION_NAME(%1);
- if (ret > 0 &amp;&amp; ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(destroyed(QObject*))) == 0))) {
- if (PySide::SignalManager::instance().hasConnectionWith(%CPPSELF))
- ret--;
- }
+ if (ret > 0 &amp;&amp; ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(destroyed(QObject*))) == 0)))
+ ret -= PySide::SignalManager::instance().countConnectionsWith(%CPPSELF);
+
%PYARG_0 = %CONVERTTOPYTHON[int](ret);
</inject-code>
</modify-function>
@@ -1507,6 +1506,19 @@
<modify-argument index="return">
<define-ownership owner="default"/>
</modify-argument>
+ </modify-function>
+
+ <!-- This is not supported due the lack of information durring the call with no arguments, this can cause a memory leak -->
+ <modify-function signature="disconnect(const char*, const QObject *, const char *)">
+ <modify-argument index="1">
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-default-expression />
+ </modify-argument>
</modify-function>
</object-type>
<object-type name="QAbstractListModel" polymorphic-id-expression="qobject_cast&lt;QAbstractListModel*&gt;(%1)">