Fixed connection cleanup function.

Reviewer: Hugo Parente Lima <hugo.pl@gmail.com>
          Luciano Wolf <luciano.wolf@openbossa.org>
This commit is contained in:
renatofilho 2010-09-16 14:14:45 -03:00
commit 551f6b9c72
4 changed files with 30 additions and 21 deletions

View file

@ -75,6 +75,8 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
slotIndex = metaObject->indexOfSlot(slot); slotIndex = metaObject->indexOfSlot(slot);
} }
if (QMetaObject::connect(source, signalIndex, receiver, slotIndex, type)) { if (QMetaObject::connect(source, signalIndex, receiver, slotIndex, type)) {
if (usingGlobalReceiver)
signalManager.globalReceiverConnectNotify(source, slotIndex);
#ifndef AVOID_PROTECTED_HACK #ifndef AVOID_PROTECTED_HACK
source->connectNotify(signal - 1); source->connectNotify(signal - 1);
#else #else
@ -82,8 +84,6 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
// connectNotify when avoiding the protected hack. // connectNotify when avoiding the protected hack.
reinterpret_cast<QObjectWrapper*>(source)->connectNotify(signal - 1); reinterpret_cast<QObjectWrapper*>(source)->connectNotify(signal - 1);
#endif #endif
if (usingGlobalReceiver)
signalManager.globalReceiverConnectNotify(source, slotIndex);
return true; return true;
} }
@ -114,6 +114,13 @@ static bool qobjectDisconnectCallback(QObject* source, const char* signal, PyObj
if (usingGlobalReceiver) { if (usingGlobalReceiver) {
int slotIndex = metaObject->indexOfSlot(callbackSig.constData()); int slotIndex = metaObject->indexOfSlot(callbackSig.constData());
signalManager.globalReceiverDisconnectNotify(source, slotIndex); signalManager.globalReceiverDisconnectNotify(source, slotIndex);
#ifndef AVOID_PROTECTED_HACK
source->disconnectNotify(signal - 1);
#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);
#endif
} }
return true; return true;
} }

View file

@ -1230,8 +1230,10 @@
<inject-code class="target" position="beginning"> <inject-code class="target" position="beginning">
// Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife // Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife
int ret = %CPPSELF.%FUNCTION_NAME(%1); int ret = %CPPSELF.%FUNCTION_NAME(%1);
if (ret > 0 &amp;&amp; strcmp(%1, SIGNAL(destroyed())) == 0 &amp;&amp; PySide::SignalManager::instance().hasConnectionWith(%CPPSELF)) if (ret > 0 &amp;&amp; ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(destroyed(QObject*))) == 0))) {
ret--; if (PySide::SignalManager::instance().hasConnectionWith(%CPPSELF))
ret--;
}
%PYARG_0 = %CONVERTTOPYTHON[int](ret); %PYARG_0 = %CONVERTTOPYTHON[int](ret);
</inject-code> </inject-code>
</modify-function> </modify-function>

View file

@ -322,11 +322,10 @@ void DynamicQMetaObject::addSlot(const char* slot, const char* type)
//search for a empty space //search for a empty space
MethodData blank; MethodData blank;
i = qFind(m_slots.begin(), m_slots.end(), blank); i = qFind(m_slots.begin(), m_slots.end(), blank);
if (i != m_slots.end()) { if (i != m_slots.end())
*i = MethodData(slot, type); *i = MethodData(slot, type);
} else { else
m_slots << MethodData(slot, type); m_slots << MethodData(slot, type);
}
updateMetaObject(); updateMetaObject();
} }
@ -438,7 +437,6 @@ void DynamicQMetaObject::writeMethodsData(QLinkedList<MethodData>& methods,
if (iMethod != methods.end() && ((*iMethod).signature().size() > 0) ) { if (iMethod != methods.end() && ((*iMethod).signature().size() > 0) ) {
(*data)[index++] = registerString((*iMethod).signature(), strings); // func name (*data)[index++] = registerString((*iMethod).signature(), strings); // func name
mType = (*iMethod).type(); mType = (*iMethod).type();
iMethod++;
} else { } else {
(*data)[index++] = null_index; // func name (*data)[index++] = null_index; // func name
} }
@ -446,6 +444,8 @@ void DynamicQMetaObject::writeMethodsData(QLinkedList<MethodData>& methods,
(*data)[index++] = (mType.size() > 0 ? registerString(mType, strings) : null_index); // normalized type (*data)[index++] = (mType.size() > 0 ? registerString(mType, strings) : null_index); // normalized type
(*data)[index++] = null_index; // tags (*data)[index++] = null_index; // tags
(*data)[index++] = flags; (*data)[index++] = flags;
if (iMethod != methods.end())
iMethod++;
} }
*prtIndex = index; *prtIndex = index;

View file

@ -107,7 +107,6 @@ DynamicSlotData::~DynamicSlotData()
Py_DECREF(m_callback); Py_DECREF(m_callback);
} }
GlobalReceiver::GlobalReceiver() GlobalReceiver::GlobalReceiver()
: m_metaObject(GLOBAL_RECEIVER_CLASS_NAME, &QObject::staticMetaObject) : m_metaObject(GLOBAL_RECEIVER_CLASS_NAME, &QObject::staticMetaObject)
{ {
@ -126,20 +125,23 @@ GlobalReceiver::~GlobalReceiver()
void GlobalReceiver::connectNotify(QObject* source, int slotId) void GlobalReceiver::connectNotify(QObject* source, int slotId)
{ {
if (m_slotReceivers.contains(slotId)) { if (m_slotReceivers.contains(slotId)) {
m_slotReceivers[slotId]->addRef(source); DynamicSlotData* data = m_slotReceivers[slotId];
if (!data->hasRefTo(source))
QObject::connect(source, SIGNAL(destroyed(QObject*)), this, "1"RECEIVER_DESTROYED_SLOT_NAME);
data->addRef(source);
} }
} }
void GlobalReceiver::disconnectNotify(QObject* source, int slotId) void GlobalReceiver::disconnectNotify(QObject* source, int slotId)
{ {
if (m_slotReceivers.contains(slotId)) { if (m_slotReceivers.contains(slotId)) {
QObject::disconnect(source, SIGNAL(destroyed(QObject*)), this, "1"RECEIVER_DESTROYED_SLOT_NAME);
DynamicSlotData *data = m_slotReceivers[slotId]; DynamicSlotData *data = m_slotReceivers[slotId];
data->decRef(source); data->decRef(source);
if (data->refCount() == 0) { if (data->refCount() == 0)
removeSlot(slotId); removeSlot(slotId);
}
if (!hasConnectionWith(source))
QObject::disconnect(source, SIGNAL(destroyed(QObject*)), this, "1"RECEIVER_DESTROYED_SLOT_NAME);
} }
} }
@ -152,9 +154,8 @@ void GlobalReceiver::addSlot(const char* slot, PyObject* callback)
{ {
m_metaObject.addSlot(slot); m_metaObject.addSlot(slot);
int slotId = m_metaObject.indexOfSlot(slot); int slotId = m_metaObject.indexOfSlot(slot);
if (!m_slotReceivers.contains(slotId)) { if (!m_slotReceivers.contains(slotId))
m_slotReceivers[slotId] = new DynamicSlotData(slotId, callback); m_slotReceivers[slotId] = new DynamicSlotData(slotId, callback);
}
bool isShortCircuit = true; bool isShortCircuit = true;
for (int i = 0; slot[i]; ++i) { for (int i = 0; slot[i]; ++i) {
@ -167,6 +168,7 @@ void GlobalReceiver::addSlot(const char* slot, PyObject* callback)
if (isShortCircuit) if (isShortCircuit)
m_shortCircuitSlots << slotId; m_shortCircuitSlots << slotId;
Q_ASSERT(slotId >= QObject::staticMetaObject.methodCount()); Q_ASSERT(slotId >= QObject::staticMetaObject.methodCount());
} }
@ -236,12 +238,10 @@ int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args)
retval = PyObject_CallObject(callback, preparedArgs); retval = PyObject_CallObject(callback, preparedArgs);
} }
if (!retval) { if (!retval)
qDebug() << "Error calling slot" << m_metaObject.method(id).signature();
PyErr_Print(); PyErr_Print();
} else { else
Py_DECREF(retval); Py_DECREF(retval);
}
return -1; return -1;
} }