diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 99bd79d5d90..88543e4add2 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -193,6 +193,7 @@ void RNA_def_func_duplicate_pointers(FunctionRNA *func); void RNA_def_func_free_pointers(FunctionRNA *func); void RNA_def_property_duplicate_pointers(PropertyRNA *prop); void RNA_def_property_free_pointers(PropertyRNA *prop); +int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier); #ifdef __cplusplus } diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index d0a8763baa7..01684482954 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2722,5 +2722,39 @@ void RNA_def_property_free_pointers(PropertyRNA *prop) } } } + +void RNA_def_property_free(StructOrFunctionRNA *cont_, PropertyRNA *prop) +{ + ContainerRNA *cont= cont_; + + RNA_def_property_free_pointers(prop); + + if(prop->flag & PROP_RUNTIME) { + if(cont->prophash) + BLI_ghash_remove(cont->prophash, (void*)prop->identifier, NULL, NULL); + + rna_freelinkN(&cont->properties, prop); + } +} + +/* note: only intended for removing dynamic props */ +int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier) +{ + ContainerRNA *cont= cont_; + PropertyRNA *prop; + + for(prop= cont->properties.first; prop; prop= prop->next) { + if(strcmp(prop->identifier, identifier)==0) { + if(prop->flag & PROP_RUNTIME) { + RNA_def_property_free(cont_, prop); + return 1; + } + else { + return 0; + } + } + } + return 0; +} #endif diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 85935c05cb1..37fd83e3b9b 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -860,6 +860,42 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; } +static char BPy_RemoveProperty_doc[] = +".. function:: RemoveProperty(attr)\n" +"\n" +" Removes a dynamically defined property.\n" +"\n" +" :arg attr: Property name.\n" +" :type attr: string"; +PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + StructRNA *srna; + + srna= srna_from_self(self, "RemoveProperty(...):"); + if(srna==NULL && PyErr_Occurred()) { + return NULL; /* self's type was compatible but error getting the srna */ + } + else if(srna==NULL) { + PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type."); + return NULL; + } + else { + static const char *kwlist[] = {"attr", NULL}; + + char *id=NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s:RemoveProperty", (char **)kwlist, &id)) + return NULL; + + if(RNA_def_property_free_identifier(srna, id) == 0) { + PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property.", id); + return NULL; + } + + Py_RETURN_NONE; + } +} + static struct PyMethodDef props_methods[] = { {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc}, {"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolVectorProperty_doc}, @@ -871,6 +907,9 @@ static struct PyMethodDef props_methods[] = { {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, BPy_EnumProperty_doc}, {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, BPy_PointerProperty_doc}, {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, BPy_CollectionProperty_doc}, + + /* only useful as a bpy_struct method */ + /* {"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, BPy_RemoveProperty_doc}, */ {NULL, NULL, 0, NULL} }; diff --git a/source/blender/python/intern/bpy_props.h b/source/blender/python/intern/bpy_props.h index 5fb62ac56d3..9382fc8115f 100644 --- a/source/blender/python/intern/bpy_props.h +++ b/source/blender/python/intern/bpy_props.h @@ -41,6 +41,8 @@ PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw); PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw); PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw); +PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw); + #define PYRNA_STACK_ARRAY 32 #endif diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 88f8990eae5..9063e5f9509 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -3794,6 +3794,8 @@ static struct PyMethodDef pyrna_struct_subtype_methods[] = { {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""}, {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""}, {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""}, + + {"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, ""}, // {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""}, {NULL, NULL, 0, NULL}