aboutsummaryrefslogtreecommitdiffstats
path: root/libpyside
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2011-05-18 15:27:41 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:54:24 -0300
commit923d007ab947b5e20ee0dbabb94564372649367f (patch)
tree9f11419ec68c94c4b15e0153aa80b9773b12824b /libpyside
parent21b5e6f05a02c834835dac846e9919aa75aad06b (diff)
Create PySideWeakRef class.
With this class you can use a c function as a callback on PyObject destruction. Reviewer: Marcelo Lira <marcelo.lira@openbossa.org> Hugo Parente Lima <hugo.pl@gmail.com>
Diffstat (limited to 'libpyside')
-rw-r--r--libpyside/CMakeLists.txt2
-rw-r--r--libpyside/pysideweakref.cpp80
-rw-r--r--libpyside/pysideweakref.h17
3 files changed, 99 insertions, 0 deletions
diff --git a/libpyside/CMakeLists.txt b/libpyside/CMakeLists.txt
index 6450045de..c3d3f8611 100644
--- a/libpyside/CMakeLists.txt
+++ b/libpyside/CMakeLists.txt
@@ -8,6 +8,7 @@ set(libpyside_SRC
pysidesignal.cpp
pysideslot.cpp
pysideproperty.cpp
+ pysideweakref.cpp
pyside.cpp
)
@@ -41,6 +42,7 @@ set(libpyside_HEADERS
pysidemetafunction.h
pysidesignal.h
pysideproperty.h
+ pysideweakref.h
)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
diff --git a/libpyside/pysideweakref.cpp b/libpyside/pysideweakref.cpp
new file mode 100644
index 000000000..ddb426edf
--- /dev/null
+++ b/libpyside/pysideweakref.cpp
@@ -0,0 +1,80 @@
+#include "pysideweakref.h"
+
+#include <Python.h>
+
+typedef struct {
+ PyObject_HEAD
+ /* Type-specific fields go here. */
+ PySideWeakRefFunction weakref_func;
+ void *user_data;
+} PySideCallableObject;
+
+static PyObject* CallableObject_call(PyObject* callable_object, PyObject* args, PyObject* kw);
+
+static PyTypeObject PySideCallableObjectType = {
+ PyObject_HEAD_INIT(0)
+ 0,
+ const_cast<char*>("PySide.Callable"),
+ sizeof(PySideCallableObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ CallableObject_call, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /* tp_doc */
+};
+
+
+static PyObject* CallableObject_call(PyObject* callable_object, PyObject* args, PyObject* kw)
+{
+ PySideCallableObject* obj = (PySideCallableObject*)(callable_object);
+ obj->weakref_func(obj->user_data);
+
+ Py_XDECREF(PyTuple_GET_ITEM(args, 0)); //kill weak ref
+ Py_RETURN_NONE;
+}
+
+namespace PySide { namespace WeakRef {
+
+PyObject* create(PyObject* obj, PySideWeakRefFunction func, void* userData)
+{
+ if (obj == Py_None)
+ return 0;
+
+ if (PySideCallableObjectType.ob_type == 0)
+ {
+ PySideCallableObjectType.ob_type = &PyType_Type;
+ PyType_Ready(&PySideCallableObjectType);
+ }
+
+ PySideCallableObject* callable = PyObject_New(PySideCallableObject, &PySideCallableObjectType);
+ if (!callable || PyErr_Occurred())
+ return 0;
+
+ PyObject* weak = PyWeakref_NewRef(obj, (PyObject*)callable);
+ if (!weak || PyErr_Occurred())
+ return 0;
+
+ Py_DECREF(callable);
+ if (!weak)
+ return 0;
+
+ callable->weakref_func = func;
+ callable->user_data = userData;
+ return (PyObject*)callable;
+}
+
+} } //namespace
+
diff --git a/libpyside/pysideweakref.h b/libpyside/pysideweakref.h
new file mode 100644
index 000000000..7bc4ddfc0
--- /dev/null
+++ b/libpyside/pysideweakref.h
@@ -0,0 +1,17 @@
+#ifndef __PYSIDEWEAKREF__
+#define __PYSIDEWEAKREF__
+
+#include <pysidemacros.h>
+#include <Python.h>
+
+typedef void (*PySideWeakRefFunction)(void* userData);
+
+namespace PySide { namespace WeakRef {
+
+PYSIDE_API PyObject* create(PyObject* ob, PySideWeakRefFunction func, void* userData);
+
+} //PySide
+} //WeakRef
+
+
+#endif