aboutsummaryrefslogtreecommitdiffstats
path: root/libpyside/globalreceiver.cpp
diff options
context:
space:
mode:
authorrenato <renato.filho@openbossa.org>2009-12-30 11:45:09 -0300
committerHugo Lima <hugo.lima@openbossa.org>2010-01-04 18:59:39 -0200
commit359c973b425db0c27675add1a330734bbd7d8dbd (patch)
treef94fb1b9d80cc2596dc911be006ba0c2584769c9 /libpyside/globalreceiver.cpp
parent0d6a8f3978188f3e343c364806e0bb6e6ac1e643 (diff)
Implement disconnect function for Python callback.
Reviewed by Hugo Parente <hugo.lima@openbossa.org>
Diffstat (limited to 'libpyside/globalreceiver.cpp')
-rw-r--r--libpyside/globalreceiver.cpp92
1 files changed, 83 insertions, 9 deletions
diff --git a/libpyside/globalreceiver.cpp b/libpyside/globalreceiver.cpp
index 0d6ce7cf2..333268081 100644
--- a/libpyside/globalreceiver.cpp
+++ b/libpyside/globalreceiver.cpp
@@ -39,16 +39,87 @@
#include <autodecref.h>
#include "typeresolver.h"
+
+namespace PySide
+{
+
+class DynamicSlotData
+{
+ public:
+ DynamicSlotData(PyObject *callback);
+ void incRef();
+ void decRef();
+ int refCount() const;
+ PyObject *callback() const;
+ ~DynamicSlotData();
+
+ private:
+ int m_refCount;
+ PyObject *m_callback;
+};
+
+}
+
using namespace PySide;
-GlobalReceiver::GlobalReceiver() : m_metaObject("GlobalReceiver", &QObject::staticMetaObject)
+DynamicSlotData::DynamicSlotData(PyObject *callback)
+ : m_refCount(0)
+{
+ m_callback = callback;
+ Py_INCREF(callback);
+}
+
+void DynamicSlotData::incRef()
+{
+ m_refCount++;
+}
+
+void DynamicSlotData::decRef()
+{
+ m_refCount--;
+}
+
+int DynamicSlotData::refCount() const
+{
+ return m_refCount;
+}
+
+PyObject *DynamicSlotData::callback() const
+{
+ return m_callback;
+}
+
+DynamicSlotData::~DynamicSlotData()
+{
+ Py_XDECREF(m_callback);
+}
+
+
+GlobalReceiver::GlobalReceiver()
+ : m_metaObject("GlobalReceiver", &QObject::staticMetaObject)
{
}
GlobalReceiver::~GlobalReceiver()
{
- foreach(PyObject* obj, m_slotReceivers)
- Py_DECREF(obj);
+ foreach(DynamicSlotData* data, m_slotReceivers)
+ delete data;
+}
+
+void GlobalReceiver::connectNotify(int slotId)
+{
+ if (m_slotReceivers.contains(slotId))
+ m_slotReceivers[slotId]->incRef();
+}
+
+void GlobalReceiver::disconnectNotify(int slotId)
+{
+ if (m_slotReceivers.contains(slotId)) {
+ DynamicSlotData *data = m_slotReceivers[slotId];
+ data->decRef();
+ if (data->refCount() == 0)
+ removeSlot(slotId);
+ }
}
const QMetaObject* GlobalReceiver::metaObject() const
@@ -60,8 +131,9 @@ void GlobalReceiver::addSlot(const char* slot, PyObject* callback)
{
m_metaObject.addSlot(slot);
int slotId = m_metaObject.indexOfSlot(slot);
- Py_INCREF(callback);
- m_slotReceivers[slotId] = callback;
+ if (!m_slotReceivers.contains(slotId)) {
+ m_slotReceivers[slotId] = new DynamicSlotData(callback);
+ }
bool isShortCircuit = true;
for (int i = 0; slot[i]; ++i) {
@@ -78,8 +150,9 @@ void GlobalReceiver::addSlot(const char* slot, PyObject* callback)
void GlobalReceiver::removeSlot(int slotId)
{
- PyObject* obj = m_slotReceivers.take(slotId);
- Py_XDECREF(obj);
+ delete m_slotReceivers.take(slotId);
+ m_metaObject.removeSlot(slotId);
+ m_shortCircuitSlots.remove(slotId);
}
int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args)
@@ -89,14 +162,15 @@ int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args)
QMetaMethod slot = m_metaObject.method(id);
Q_ASSERT(slot.methodType() == QMetaMethod::Slot);
- PyObject* callback = m_slotReceivers.value(id);
- if (!callback) {
+ DynamicSlotData* data = m_slotReceivers.value(id);
+ if (!data) {
qWarning() << "Unknown global slot, id:" << id;
return -1;
}
int numArgs;
PyObject* retval = 0;
+ PyObject* callback = data->callback();
if (m_shortCircuitSlots.contains(id)) {
retval = PyObject_CallObject(callback, reinterpret_cast<PyObject*>(args[1]));
} else {