aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/globalreceiverv2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/libpyside/globalreceiverv2.cpp')
-rw-r--r--sources/pyside6/libpyside/globalreceiverv2.cpp113
1 files changed, 24 insertions, 89 deletions
diff --git a/sources/pyside6/libpyside/globalreceiverv2.cpp b/sources/pyside6/libpyside/globalreceiverv2.cpp
index 4f72d14ce..1342af24e 100644
--- a/sources/pyside6/libpyside/globalreceiverv2.cpp
+++ b/sources/pyside6/libpyside/globalreceiverv2.cpp
@@ -18,11 +18,6 @@
#define RECEIVER_DESTROYED_SLOT_NAME "__receiverDestroyed__(QObject*)"
-namespace
-{
- static int DESTROY_SIGNAL_ID = 0;
- static int DESTROY_SLOT_ID = 0;
-}
namespace PySide
{
@@ -146,7 +141,7 @@ void DynamicSlotDataV2::onCallbackDestroyed(void *data)
auto self = reinterpret_cast<DynamicSlotDataV2 *>(data);
self->m_weakRef = nullptr;
Py_BEGIN_ALLOW_THREADS
- delete self->m_parent;
+ SignalManager::instance().deleteGobalReceiver(self->m_parent);
Py_END_ALLOW_THREADS
}
@@ -160,31 +155,17 @@ DynamicSlotDataV2::~DynamicSlotDataV2()
Py_DECREF(m_callback);
}
-GlobalReceiverV2::GlobalReceiverV2(PyObject *callback, GlobalReceiverV2MapPtr map) :
+GlobalReceiverV2::GlobalReceiverV2(PyObject *callback) :
QObject(nullptr),
- m_metaObject("__GlobalReceiver__", &QObject::staticMetaObject),
- m_sharedMap(std::move(map))
+ m_metaObject("__GlobalReceiver__", &QObject::staticMetaObject)
{
m_data = new DynamicSlotDataV2(callback, this);
- m_metaObject.addSlot(RECEIVER_DESTROYED_SLOT_NAME);
- m_metaObject.update();
- m_refs.append(nullptr);
-
-
- if (DESTROY_SIGNAL_ID == 0)
- DESTROY_SIGNAL_ID = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
-
- if (DESTROY_SLOT_ID == 0)
- DESTROY_SLOT_ID = m_metaObject.indexOfMethod(QMetaMethod::Slot, RECEIVER_DESTROYED_SLOT_NAME);
-
-
}
GlobalReceiverV2::~GlobalReceiverV2()
{
m_refs.clear();
// Remove itself from map.
- m_sharedMap->remove(m_data->key());
// Suppress handling of destroyed() for objects whose last reference is contained inside
// the callback object that will now be deleted. The reference could be a default argument,
// a callback local variable, etc.
@@ -204,69 +185,34 @@ int GlobalReceiverV2::addSlot(const char *signature)
void GlobalReceiverV2::incRef(const QObject *link)
{
- if (link) {
- if (!m_refs.contains(link)) {
- bool connected{};
- Py_BEGIN_ALLOW_THREADS
- connected = QMetaObject::connect(link, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID);
- Py_END_ALLOW_THREADS
- if (connected)
- m_refs.append(link);
- else
- Q_ASSERT(false);
- } else {
- m_refs.append(link);
- }
- } else {
- m_refs.append(nullptr);
- }
+ Q_ASSERT(link);
+ m_refs.append(link);
}
void GlobalReceiverV2::decRef(const QObject *link)
{
- if (m_refs.isEmpty())
- return;
-
-
+ Q_ASSERT(link);
m_refs.removeOne(link);
- if (link) {
- if (!m_refs.contains(link)) {
- bool result{};
- Py_BEGIN_ALLOW_THREADS
- result = QMetaObject::disconnect(link, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID);
- Py_END_ALLOW_THREADS
- Q_ASSERT(result);
- if (!result)
- return;
- }
- }
-
- if (m_refs.isEmpty())
- Py_BEGIN_ALLOW_THREADS
- delete this;
- Py_END_ALLOW_THREADS
+}
+void GlobalReceiverV2::notify()
+{
+ purgeDeletedSenders();
}
-int GlobalReceiverV2::refCount(const QObject *link) const
+static bool isNull(const QPointer<const QObject> &p)
{
- if (link)
- return m_refs.count(link);
+ return p.isNull();
+}
- return m_refs.size();
+void GlobalReceiverV2::purgeDeletedSenders()
+{
+ m_refs.erase(std::remove_if(m_refs.begin(), m_refs.end(), isNull), m_refs.end());
}
-void GlobalReceiverV2::notify()
+bool GlobalReceiverV2::isEmpty() const
{
- const QSet<const QObject *> objSet(m_refs.cbegin(), m_refs.cend());
- Py_BEGIN_ALLOW_THREADS
- for (const QObject *o : objSet) {
- if (o) {
- QMetaObject::disconnect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID);
- QMetaObject::connect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID);
- }
- }
- Py_END_ALLOW_THREADS
+ return std::all_of(m_refs.cbegin(), m_refs.cend(), isNull);
}
GlobalReceiverKey GlobalReceiverV2::key() const
@@ -294,26 +240,15 @@ int GlobalReceiverV2::qt_metacall(QMetaObject::Call call, int id, void **args)
Q_ASSERT(slot.methodType() == QMetaMethod::Slot);
if (!m_data) {
- if (id != DESTROY_SLOT_ID) {
- const QByteArray message = "PySide6 Warning: Skipping callback call "
- + slot.methodSignature() + " because the callback object is being destructed.";
- PyErr_WarnEx(PyExc_RuntimeWarning, message.constData(), 0);
- }
+ const QByteArray message = "PySide6 Warning: Skipping callback call "
+ + slot.methodSignature() + " because the callback object is being destructed.";
+ PyErr_WarnEx(PyExc_RuntimeWarning, message.constData(), 0);
return -1;
}
- if (id == DESTROY_SLOT_ID) {
- if (m_refs.isEmpty())
- return -1;
- auto obj = *reinterpret_cast<QObject **>(args[1]);
- incRef(); //keep the object live (safe ref)
- m_refs.removeAll(obj); // remove all refs to this object
- decRef(); //remove the safe ref
- } else {
- const bool isShortCuit = std::strchr(slot.methodSignature(), '(') == nullptr;
- Shiboken::AutoDecRef callback(m_data->callback());
- SignalManager::callPythonMetaMethod(slot, args, callback, isShortCuit);
- }
+ const bool isShortCuit = std::strchr(slot.methodSignature(), '(') == nullptr;
+ Shiboken::AutoDecRef callback(m_data->callback());
+ SignalManager::callPythonMetaMethod(slot, args, callback, isShortCuit);
// SignalManager::callPythonMetaMethod might have failed, in that case we have to print the
// error so it considered "handled".