diff options
author | Renato Filho <renato.filho@openbossa.org> | 2011-05-18 15:27:41 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:54:24 -0300 |
commit | 923d007ab947b5e20ee0dbabb94564372649367f (patch) | |
tree | 9f11419ec68c94c4b15e0153aa80b9773b12824b /libpyside | |
parent | 21b5e6f05a02c834835dac846e9919aa75aad06b (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.txt | 2 | ||||
-rw-r--r-- | libpyside/pysideweakref.cpp | 80 | ||||
-rw-r--r-- | libpyside/pysideweakref.h | 17 |
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 |