From 0dc80266913432eff4a6c6328af1e85bec4c5fc1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Feb 2010 21:58:08 +0000 Subject: mostly fixed [#21172] Reloading scripts leaks memory (F8) the same properties were being registered many times with built in structs. blender memory at least is not leaking, but it seems python is still not freeing some memory. For the moment dont allow existing properties to be registered again, will need to have a way to unregister rna properties. --- source/blender/python/intern/bpy_props.c | 82 +++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 7 deletions(-) (limited to 'source') diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 7355fa2a0c9..68d89c06e70 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -87,6 +87,14 @@ static PyObject *bpy_prop_deferred_return(void *func, PyObject *kw) return ret; } +static int bpy_struct_id_used(StructRNA *srna, char *identifier) +{ + PointerRNA ptr; + RNA_pointer_create(NULL, srna, NULL, &ptr); + return (RNA_struct_find_property(&ptr, identifier) != NULL); +} + + /* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna allong * This isnt incorrect since its a python object - but be careful */ static char BPy_BoolProperty_doc[] = @@ -125,11 +133,17 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiO!s:BoolProperty", (char **)kwlist, &id, &name, &description, &def, &PySet_Type, &pyopts, &pysubtype)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "BoolProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "BoolProperty(options={...}):")) return NULL; if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "BoolProperty(subtype='%s'): invalid subtype."); + PyErr_Format(PyExc_TypeError, "BoolProperty(subtype='%s'): invalid subtype.", pysubtype); return NULL; } @@ -187,11 +201,17 @@ PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOO!si:BoolVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &PySet_Type, &pyopts, &pysubtype, &size)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "BoolVectorProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "BoolVectorProperty(options={...}):")) return NULL; if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "BoolVectorProperty(subtype='%s'): invalid subtype."); + PyErr_Format(PyExc_TypeError, "BoolVectorProperty(subtype='%s'): invalid subtype.", pysubtype); return NULL; } @@ -256,11 +276,17 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiiiiO!s:IntProperty", (char **)kwlist, &id, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "IntProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "IntProperty(options={...}):")) return NULL; if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "IntProperty(subtype='%s'): invalid subtype."); + PyErr_Format(PyExc_TypeError, "IntProperty(subtype='%s'): invalid subtype.", pysubtype); return NULL; } @@ -319,11 +345,17 @@ PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOiiiiO!si:IntVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &PySet_Type, &pyopts, &pysubtype, &size)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "IntVectorProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "IntVectorProperty(options={...}):")) return NULL; if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "IntVectorProperty(subtype='%s'): invalid subtype."); + PyErr_Format(PyExc_TypeError, "IntVectorProperty(subtype='%s'): invalid subtype.", pysubtype); return NULL; } @@ -395,11 +427,17 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssffffffiO!ss:FloatProperty", (char **)kwlist, &id, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "FloatProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "FloatProperty(options={...}):")) return NULL; if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "FloatProperty(subtype='%s'): invalid subtype."); + PyErr_Format(PyExc_TypeError, "FloatProperty(subtype='%s'): invalid subtype.", pysubtype); return NULL; } @@ -463,11 +501,17 @@ PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOfffffiO!si:FloatVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &size)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "FloatVectorProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "FloatVectorProperty(options={...}):")) return NULL; if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "FloatVectorProperty(subtype='%s'): invalid subtype."); + PyErr_Format(PyExc_TypeError, "FloatVectorProperty(subtype='%s'): invalid subtype.", pysubtype); return NULL; } @@ -533,11 +577,17 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|sssiO!s:StringProperty", (char **)kwlist, &id, &name, &description, &def, &maxlen, &PySet_Type, &pyopts, &pysubtype)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "StringProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "StringProperty(options={...}):")) return NULL; if(pysubtype && RNA_enum_value_from_id(property_subtype_string_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "StringProperty(subtype='%s'): invalid subtype."); + PyErr_Format(PyExc_TypeError, "StringProperty(subtype='%s'): invalid subtype.", pysubtype); return NULL; } @@ -639,6 +689,12 @@ PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sssO!:EnumProperty", (char **)kwlist, &id, &items, &name, &description, &def, &PySet_Type, &pyopts)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "EnumProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "EnumProperty(options={...}):")) return NULL; @@ -713,6 +769,12 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ssO!:PointerProperty", (char **)kwlist, &id, &type, &name, &description, &PySet_Type, &pyopts)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "PointerProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "PointerProperty(options={...}):")) return NULL; @@ -768,6 +830,12 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ssO!:CollectionProperty", (char **)kwlist, &id, &type, &name, &description, &PySet_Type, &pyopts)) return NULL; + if(bpy_struct_id_used(srna, id)) { + // PyErr_Format(PyExc_TypeError, "CollectionProperty(): '%s' already defined.", id); + // return NULL; + Py_RETURN_NONE; + } + if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "CollectionProperty(options={...}):")) return NULL; -- cgit v1.2.3