[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35117] trunk/blender/source/blender/ python/generic: support pythons cyclic garbage collector for mathutils types.
Campbell Barton
ideasman42 at gmail.com
Thu Feb 24 05:58:52 CET 2011
Revision: 35117
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35117
Author: campbellbarton
Date: 2011-02-24 04:58:51 +0000 (Thu, 24 Feb 2011)
Log Message:
-----------
support pythons cyclic garbage collector for mathutils types.
Modified Paths:
--------------
trunk/blender/source/blender/python/generic/mathutils.c
trunk/blender/source/blender/python/generic/mathutils.h
trunk/blender/source/blender/python/generic/mathutils_Color.c
trunk/blender/source/blender/python/generic/mathutils_Euler.c
trunk/blender/source/blender/python/generic/mathutils_Matrix.c
trunk/blender/source/blender/python/generic/mathutils_Quaternion.c
trunk/blender/source/blender/python/generic/mathutils_Vector.c
trunk/blender/source/blender/python/generic/mathutils_Vector.h
Modified: trunk/blender/source/blender/python/generic/mathutils.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils.c 2011-02-23 23:22:25 UTC (rev 35116)
+++ trunk/blender/source/blender/python/generic/mathutils.c 2011-02-24 04:58:51 UTC (rev 35117)
@@ -325,13 +325,30 @@
return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0);
}
-void BaseMathObject_dealloc(BaseMathObject * self)
+int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
{
+ Py_VISIT(self->cb_user);
+ return 0;
+}
+
+int BaseMathObject_clear(BaseMathObject *self)
+{
+ Py_CLEAR(self->cb_user);
+ return 0;
+}
+
+void BaseMathObject_dealloc(BaseMathObject *self)
+{
/* only free non wrapped */
- if(self->wrapped != Py_WRAP)
- PyMem_Free(self->data);
+ if(self->wrapped != Py_WRAP) {
+ /* the ONLY time this should be NULL is when the value failed to initialize */
+ if(self->data) {
+ PyMem_Free(self->data);
+ }
+ }
- Py_XDECREF(self->cb_user);
+ BaseMathObject_clear(self);
+
Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
}
Modified: trunk/blender/source/blender/python/generic/mathutils.h
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils.h 2011-02-23 23:22:25 UTC (rev 35116)
+++ trunk/blender/source/blender/python/generic/mathutils.h 2011-02-24 04:58:51 UTC (rev 35117)
@@ -57,6 +57,10 @@
PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * );
PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * );
+
+
+int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg);
+int BaseMathObject_clear(BaseMathObject *self);
void BaseMathObject_dealloc(BaseMathObject * self);
PyMODINIT_FUNC BPyInit_mathutils(void);
Modified: trunk/blender/source/blender/python/generic/mathutils_Color.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_Color.c 2011-02-23 23:22:25 UTC (rev 35116)
+++ trunk/blender/source/blender/python/generic/mathutils_Color.c 2011-02-24 04:58:51 UTC (rev 35117)
@@ -475,10 +475,10 @@
NULL, //tp_getattro
NULL, //tp_setattro
NULL, //tp_as_buffer
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
color_doc, //tp_doc
- NULL, //tp_traverse
- NULL, //tp_clear
+ (traverseproc)BaseMathObject_traverse, //tp_traverse
+ (inquiry)BaseMathObject_clear, //tp_clear
(richcmpfunc)Color_richcmpr, //tp_richcompare
0, //tp_weaklistoffset
NULL, //tp_iter
@@ -509,31 +509,45 @@
(i.e. it was allocated elsewhere by MEM_mallocN())
pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
(i.e. it must be created here with PyMEM_malloc())*/
-PyObject *newColorObject(float *col, int type, PyTypeObject *base_type)
+static int newColorObject_init(ColorObject *self, float *col, int type)
{
- ColorObject *self;
-
- if(base_type) self = (ColorObject *)base_type->tp_alloc(base_type, 0);
- else self = PyObject_NEW(ColorObject, &color_Type);
-
- /* init callbacks as NULL */
- self->cb_user= NULL;
- self->cb_type= self->cb_subtype= 0;
-
- if(type == Py_WRAP){
+ if(type == Py_WRAP) {
self->col = col;
self->wrapped = Py_WRAP;
}
- else if (type == Py_NEW){
+ else if (type == Py_NEW) {
self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float));
- if(col)
+ if(col) {
copy_v3_v3(self->col, col);
- else
+ }
+ else {
zero_v3(self->col);
+ }
self->wrapped = Py_NEW;
}
else {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+PyObject *newColorObject(float *col, int type, PyTypeObject *base_type)
+{
+ ColorObject *self;
+
+ self= base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) :
+ (ColorObject *)PyObject_GC_New(ColorObject, &color_Type);
+
+ /* init callbacks as NULL */
+ self->cb_user= NULL;
+ self->cb_type= self->cb_subtype= 0;
+ ((BaseMathObject *)self)->data= NULL; /* incase of error */
+
+ if(newColorObject_init(self, col, type) == -1) {
+ Py_DECREF(self);
return NULL;
}
@@ -542,12 +556,19 @@
PyObject *newColorObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
{
- ColorObject *self= (ColorObject *)newColorObject(NULL, Py_NEW, NULL);
- if(self) {
- Py_INCREF(cb_user);
- self->cb_user= cb_user;
- self->cb_type= (unsigned char)cb_type;
- self->cb_subtype= (unsigned char)cb_subtype;
+ ColorObject *self;
+
+ self= (ColorObject *)PyObject_GC_New(ColorObject, &color_Type);
+
+ Py_INCREF(cb_user);
+ self->cb_user= cb_user;
+ self->cb_type= (unsigned char)cb_type;
+ self->cb_subtype= (unsigned char)cb_subtype;
+ ((BaseMathObject *)self)->data= NULL; /* incase of error */
+
+ if(newColorObject_init(self, NULL, Py_NEW) == -1) {
+ Py_DECREF(self);
+ return NULL;
}
return (PyObject *)self;
Modified: trunk/blender/source/blender/python/generic/mathutils_Euler.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_Euler.c 2011-02-23 23:22:25 UTC (rev 35116)
+++ trunk/blender/source/blender/python/generic/mathutils_Euler.c 2011-02-24 04:58:51 UTC (rev 35117)
@@ -608,10 +608,10 @@
NULL, //tp_getattro
NULL, //tp_setattro
NULL, //tp_as_buffer
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
euler_doc, //tp_doc
- NULL, //tp_traverse
- NULL, //tp_clear
+ (traverseproc)BaseMathObject_traverse, //tp_traverse
+ (inquiry)BaseMathObject_clear, //tp_clear
(richcmpfunc)Euler_richcmpr, //tp_richcompare
0, //tp_weaklistoffset
NULL, //tp_iter
@@ -642,46 +642,67 @@
(i.e. it was allocated elsewhere by MEM_mallocN())
pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
(i.e. it must be created here with PyMEM_malloc())*/
-PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_type)
+static int newEulerObject_init(EulerObject *self, float *eul, short order, int type)
{
- EulerObject *self;
-
- if(base_type) self = (EulerObject *)base_type->tp_alloc(base_type, 0);
- else self = PyObject_NEW(EulerObject, &euler_Type);
-
- /* init callbacks as NULL */
- self->cb_user= NULL;
- self->cb_type= self->cb_subtype= 0;
-
if(type == Py_WRAP) {
self->eul = eul;
self->wrapped = Py_WRAP;
}
else if (type == Py_NEW){
self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float));
- if(eul)
+ if(eul) {
copy_v3_v3(self->eul, eul);
- else
+ }
+ else {
zero_v3(self->eul);
-
+ }
self->wrapped = Py_NEW;
}
else{
+ PyErr_SetString(PyExc_RuntimeError, "invalid type");
+ return -1;
+ }
+
+ self->order= order;
+
+ return 0;
+}
+
+PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_type)
+{
+ EulerObject *self;
+
+ self= base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) :
+ (EulerObject *)PyObject_GC_New(EulerObject, &euler_Type);
+
+ /* init callbacks as NULL */
+ self->cb_user= NULL;
+ self->cb_type= self->cb_subtype= 0;
+ ((BaseMathObject *)self)->data= NULL; /* incase of error */
+
+ if(newEulerObject_init(self, eul, order, type) == -1) {
+ Py_DECREF(self);
return NULL;
}
- self->order= order;
return (PyObject *)self;
}
PyObject *newEulerObject_cb(PyObject *cb_user, short order, int cb_type, int cb_subtype)
{
- EulerObject *self= (EulerObject *)newEulerObject(NULL, order, Py_NEW, NULL);
- if(self) {
- Py_INCREF(cb_user);
- self->cb_user= cb_user;
- self->cb_type= (unsigned char)cb_type;
- self->cb_subtype= (unsigned char)cb_subtype;
+ EulerObject *self;
+
+ self= (EulerObject *)PyObject_GC_New(VectorObject, &vector_Type);
+
+ Py_INCREF(cb_user);
+ self->cb_user= cb_user;
+ self->cb_type= (unsigned char)cb_type;
+ self->cb_subtype= (unsigned char)cb_subtype;
+ ((BaseMathObject *)self)->data= NULL; /* incase of error */
+
+ if(newEulerObject_init(self, NULL, order, Py_NEW) == -1) {
+ Py_DECREF(self);
+ return NULL;
}
return (PyObject *)self;
Modified: trunk/blender/source/blender/python/generic/mathutils_Matrix.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_Matrix.c 2011-02-23 23:22:25 UTC (rev 35116)
+++ trunk/blender/source/blender/python/generic/mathutils_Matrix.c 2011-02-24 04:58:51 UTC (rev 35117)
@@ -1775,10 +1775,10 @@
NULL, /*tp_getattro*/
NULL, /*tp_setattro*/
NULL, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
matrix_doc, /*tp_doc*/
- NULL, /*tp_traverse*/
- NULL, /*tp_clear*/
+ (traverseproc)BaseMathObject_traverse, //tp_traverse
+ (inquiry)BaseMathObject_clear, //tp_clear
(richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
NULL, /*tp_iter*/
@@ -1820,27 +1820,19 @@
(i.e. it was allocated elsewhere by MEM_mallocN())
pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
(i.e. it must be created here with PyMEM_malloc())*/
-PyObject *newMatrixObject(float *mat, const unsigned short rowSize, const unsigned short colSize, int type, PyTypeObject *base_type)
+static int newMatrixObject_init(MatrixObject *self, float *mat, const unsigned short rowSize, const unsigned short colSize, int type)
{
- MatrixObject *self;
int x, row, col;
/*matrix objects can be any 2-4row x 2-4col matrix*/
- if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4){
+ if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4) {
PyErr_SetString(PyExc_RuntimeError, "matrix(): row and column sizes must be between 2 and 4");
- return NULL;
+ return -1;
}
- if(base_type) self = (MatrixObject *)base_type->tp_alloc(base_type, 0);
- else self = PyObject_NEW(MatrixObject, &matrix_Type);
-
self->row_size = rowSize;
self->col_size = colSize;
- /* init callbacks as NULL */
- self->cb_user= NULL;
- self->cb_type= self->cb_subtype= 0;
-
if(type == Py_WRAP){
self->contigPtr = mat;
/*pointer array points to contigous memory*/
@@ -1848,11 +1840,12 @@
self->matrix[x] = self->contigPtr + (x * colSize);
}
self->wrapped = Py_WRAP;
- }else if (type == Py_NEW){
+ }
+ else if (type == Py_NEW){
self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float));
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list