[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