fix for leak in gpu.export_shader(), wasnt freeing the function.

also change the bmesh iterator so its possible to initialize without stepping.
This commit is contained in:
Campbell Barton 2012-02-20 22:04:29 +00:00
parent d31e1533a3
commit c4e7cc3287
7 changed files with 83 additions and 59 deletions

@ -102,8 +102,8 @@ typedef struct BMIter {
char itype;
} BMIter;
void *BM_iter_at_index(struct BMesh *bm, const char htype, void *data, int index);
int BM_iter_as_array(struct BMesh *bm, const char htype, void *data, void **array, const int len);
void *BM_iter_at_index(struct BMesh *bm, const char itype, void *data, int index);
int BM_iter_as_array(struct BMesh *bm, const char itype, void *data, void **array, const int len);
/* private for bmesh_iterators_inline.c */
void bmiter__vert_of_mesh_begin(struct BMIter *iter);

@ -272,7 +272,7 @@ enum {
DEL_ONLYFACES,
DEL_EDGESFACES,
DEL_FACES,
DEL_ALL ,
DEL_ALL,
DEL_ONLYTAGGED
};
@ -313,10 +313,10 @@ void BMO_slot_from_flag(struct BMesh *bm, struct BMOperator *op, const char *slo
/* tool-flags all elements inside an element slot array with flag flag. */
void BMO_slot_buffer_flag_enable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
const short oflag, const char htype);
const short oflag, const char htype);
/* clears tool-flag flag from all elements inside a slot array. */
void BMO_slot_buffer_flag_disable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
const short oflag, const char htype);
const short oflag, const char htype);
/* tool-flags all elements inside an element slot array with flag flag. */
void BMO_slot_buffer_hflag_enable(struct BMesh *bm, struct BMOperator *op, const char *slotname,

@ -52,11 +52,10 @@ BM_INLINE void *BM_iter_step(BMIter *iter)
*
* Takes a bmesh iterator structure and fills
* it with the appropriate function pointers based
* upon its type and then calls BMeshIter_step()
* to return the first element of the iterator.
* upon its type.
*
*/
BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *data)
BM_INLINE int BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data)
{
/* int argtype; */
iter->itype = itype;
@ -78,7 +77,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_EDGES_OF_VERT:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__edge_of_vert_begin;
iter->step = bmiter__edge_of_vert_step;
@ -86,7 +85,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_FACES_OF_VERT:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__face_of_vert_begin;
iter->step = bmiter__face_of_vert_step;
@ -94,7 +93,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_LOOPS_OF_VERT:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__loop_of_vert_begin;
iter->step = bmiter__loop_of_vert_step;
@ -102,7 +101,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_FACES_OF_EDGE:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__face_of_edge_begin;
iter->step = bmiter__face_of_edge_step;
@ -110,7 +109,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_VERTS_OF_FACE:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__vert_of_face_begin;
iter->step = bmiter__vert_of_face_step;
@ -118,7 +117,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_EDGES_OF_FACE:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__edge_of_face_begin;
iter->step = bmiter__edge_of_face_step;
@ -126,7 +125,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_LOOPS_OF_FACE:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__loop_of_face_begin;
iter->step = bmiter__loop_of_face_step;
@ -134,7 +133,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_LOOPS_OF_LOOP:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__loops_of_loop_begin;
iter->step = bmiter__loops_of_loop_step;
@ -142,7 +141,7 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
break;
case BM_LOOPS_OF_EDGE:
if (!data)
return NULL;
return FALSE;
iter->begin = bmiter__loops_of_edge_begin;
iter->step = bmiter__loops_of_edge_step;
@ -153,8 +152,26 @@ BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *dat
}
iter->begin(iter);
return BM_iter_step(iter);
return TRUE;
}
/*
* BMESH ITERATOR NEW
*
* Takes a bmesh iterator structure and fills
* it with the appropriate function pointers based
* upon its type and then calls BMeshIter_step()
* to return the first element of the iterator.
*
*/
BM_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *data)
{
if (BM_iter_init(iter, bm, itype, data)) {
return BM_iter_step(iter);
}
else {
return NULL;
}
}
#endif /* __BMESH_ITERATORS_INLINE_C__ */

@ -65,7 +65,7 @@ static const char *bmo_error_messages[] = {
/* operator slot type information - size of one element of the type given. */
const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES] = {
0,
sizeof(int),
sizeof(int),
sizeof(int),
sizeof(float),
sizeof(void *),
@ -837,7 +837,7 @@ int BMO_vert_edge_flags_count(BMesh *bm, BMVert *v, const short oflag)
* Flags elements in a slots buffer
*/
void BMO_slot_buffer_flag_enable(BMesh *bm, BMOperator *op, const char *slotname,
const short oflag, const char htype)
const short oflag, const char htype)
{
BMOpSlot *slot = BMO_slot_get(op, slotname);
BMHeader **data = slot->data.p;
@ -860,7 +860,7 @@ void BMO_slot_buffer_flag_enable(BMesh *bm, BMOperator *op, const char *slotname
* Removes flags from elements in a slots buffer
*/
void BMO_slot_buffer_flag_disable(BMesh *bm, BMOperator *op, const char *slotname,
const short oflag, const char htype)
const short oflag, const char htype)
{
BMOpSlot *slot = BMO_slot_get(op, slotname);
BMHeader **data = slot->data.p;

@ -646,3 +646,39 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
PyGILState_Release(gilstate);
}
}
/* generic function to avoid depending on RNA */
void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
{
PyObject* as_pointer;
PyObject* pointer;
if (!strcmp(Py_TYPE(value)->tp_name, type_name) &&
(as_pointer = PyObject_GetAttrString(value, "as_pointer")) != NULL &&
PyCallable_Check(as_pointer))
{
void *result = NULL;
/* must be a 'type_name' object */
pointer = PyObject_CallObject(as_pointer, NULL);
Py_DECREF(as_pointer);
if (!pointer) {
PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed");
return NULL;
}
result = PyLong_AsVoidPtr(pointer);
Py_DECREF(pointer);
if (!result) {
PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed");
}
return result;
}
else {
PyErr_Format(PyExc_TypeError,
"expected '%.200s' type found '%.200s' instead",
type_name, Py_TYPE(value)->tp_name);
return NULL;
}
}

@ -54,4 +54,6 @@ void PyC_SetHomePath(const char *py_path_bundle);
#define PYC_INTERPRETER_ACTIVE (((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL)
void *PyC_RNA_AsPointer(PyObject *value, const char *type_name);
#endif // __PY_CAPI_UTILS_H__

@ -56,6 +56,8 @@
#include "bpy_rna.h"
#include "../generic/py_capi_utils.h"
#include "gpu.h"
#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
@ -157,8 +159,6 @@ static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObj
{
PyObject* pyscene;
PyObject* pymat;
PyObject* as_pointer;
PyObject* pointer;
PyObject* result;
PyObject* dict;
PyObject* val;
@ -177,47 +177,16 @@ static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObj
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:export_shader", (char**)(kwlist), &pyscene, &pymat))
return NULL;
if (!strcmp(Py_TYPE(pyscene)->tp_name, "Scene") &&
(as_pointer = PyObject_GetAttrString(pyscene, "as_pointer")) != NULL &&
PyCallable_Check(as_pointer)) {
// must be a scene object
pointer = PyObject_CallObject(as_pointer, NULL);
if (!pointer) {
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
return NULL;
}
scene = (Scene*)PyLong_AsVoidPtr(pointer);
Py_DECREF(pointer);
if (!scene) {
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
return NULL;
}
}
else {
PyErr_SetString(PyExc_TypeError, "gpu.export_shader() first argument should be of Scene type");
scene = (Scene *)PyC_RNA_AsPointer(pyscene, "Scene");
if (scene == NULL) {
return NULL;
}
if (!strcmp(Py_TYPE(pymat)->tp_name, "Material") &&
(as_pointer = PyObject_GetAttrString(pymat, "as_pointer")) != NULL &&
PyCallable_Check(as_pointer)) {
// must be a material object
pointer = PyObject_CallObject(as_pointer, NULL);
if (!pointer) {
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
return NULL;
}
material = (Material*)PyLong_AsVoidPtr(pointer);
Py_DECREF(pointer);
if (!material) {
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
return NULL;
}
}
else {
PyErr_SetString(PyExc_TypeError, "gpu.export_shader() second argument should be of Material type");
material = (Material *)PyC_RNA_AsPointer(pymat, "Material");
if (material == NULL) {
return NULL;
}
// we can call our internal function at last:
shader = GPU_shader_export(scene, material);
if (!shader) {