aboutsummaryrefslogtreecommitdiffstats
path: root/libpyside
diff options
context:
space:
mode:
authorJohn Ehresman <jpe@wingware.com>2012-12-20 17:26:29 -0500
committerHugo Parente Lima <hugo.lima@openbossa.org>2012-12-21 15:29:41 +0100
commitb3669dca4e4321b204d10b06018d35900b1847ee (patch)
tree3578aa3a0250c1a90599b54262b0b911c95b71ca /libpyside
parentaeccd2a05bba8c94a3a338370f16af1d545e8abd (diff)
Use QObject property to invalidate wrapper before deletion.
Define a getWrapperForQObject function to create / find wrappers for QObject derived objects. It sets a property so that an invalidate function can be called when the QObject property is cleared in the QObject destructor after all destroyed signal handlers have been called. Requires a change to shiboken to generate calls to the getWrapperForQObject function. Change-Id: I4ed548af114bf7176e8e8255a3ea70549c35d74c Reviewed-by: Hugo Parente Lima <hugo.lima@openbossa.org>
Diffstat (limited to 'libpyside')
-rw-r--r--libpyside/pyside.cpp52
-rw-r--r--libpyside/pyside.h2
2 files changed, 54 insertions, 0 deletions
diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp
index 0d96f9530..a71b139a1 100644
--- a/libpyside/pyside.cpp
+++ b/libpyside/pyside.cpp
@@ -36,6 +36,7 @@
#include <basewrapper.h>
#include <conversions.h>
#include <sbkconverter.h>
+#include <gilstate.h>
#include <typeresolver.h>
#include <bindingmanager.h>
#include <algorithm>
@@ -44,6 +45,7 @@
#include <QStack>
#include <QCoreApplication>
#include <QDebug>
+#include <QSharedPointer>
static QStack<PySide::CleanupFunction> cleanupFunctionList;
static void* qobjectNextAddr;
@@ -293,5 +295,55 @@ void setNextQObjectMemoryAddr(void* addr)
qobjectNextAddr = addr;
}
+} // namespace PySide
+
+// A QSharedPointer is used with a deletion function to invalidate a pointer
+// when the property value is cleared. This should be a QSharedPointer with
+// a void* pointer, but that isn't allowed
+typedef char any_t;
+Q_DECLARE_METATYPE(QSharedPointer<any_t>);
+
+namespace PySide
+{
+
+static void invalidatePtr(any_t* object)
+{
+ Shiboken::GilState state;
+
+ SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(object);
+ if (wrapper != NULL)
+ Shiboken::BindingManager::instance().releaseWrapper(wrapper);
+}
+
+static const char invalidatePropertyName[] = "_PySideInvalidatePtr";
+
+PyObject* getWrapperForQObject(QObject* cppSelf, SbkObjectType* sbk_type)
+{
+ PyObject* pyOut = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(cppSelf);
+ if (pyOut) {
+ Py_INCREF(pyOut);
+ return pyOut;
+ }
+
+ // Setting the property will trigger an QEvent notification, which may call into
+ // code that creates the wrapper so only set the property if it isn't already
+ // set and check if it's created after the set call
+ QVariant existing = cppSelf->property(invalidatePropertyName);
+ if (!existing.isValid()) {
+ QSharedPointer<any_t> shared_with_del((any_t*)cppSelf, invalidatePtr);
+ cppSelf->setProperty(invalidatePropertyName, QVariant::fromValue(shared_with_del));
+ pyOut = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(cppSelf);
+ if (pyOut) {
+ Py_INCREF(pyOut);
+ return pyOut;
+ }
+ }
+
+ const char* typeName = typeid(*cppSelf).name();
+ pyOut = Shiboken::Object::newObject(sbk_type, cppSelf, false, false, typeName);
+
+ return pyOut;
+}
+
} //namespace PySide
diff --git a/libpyside/pyside.h b/libpyside/pyside.h
index 779c630a9..35cd36459 100644
--- a/libpyside/pyside.h
+++ b/libpyside/pyside.h
@@ -117,6 +117,8 @@ PYSIDE_API bool inherits(PyTypeObject* self, const char* class_name);
PYSIDE_API void* nextQObjectMemoryAddr();
PYSIDE_API void setNextQObjectMemoryAddr(void* addr);
+PYSIDE_API PyObject* getWrapperForQObject(QObject* cppSelf, SbkObjectType* sbk_type);
+
} //namespace PySide