From 63f7eceb53085ef40cad4dc2343dbe608be999c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Jul 2021 16:04:08 +1000 Subject: PyAPI: defer freeing existing properties on registration Registering a property could remove the existing property, then fail to parse one of the arguments of the new property - leaving the struct without a property. Now freeing the existing property is deferred until immediately before the new property is registered. --- source/blender/makesrna/intern/rna_define.c | 55 +++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 10 deletions(-) (limited to 'source/blender/makesrna/intern/rna_define.c') diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index fadce9e3c89..bd5ade36eaa 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -4759,25 +4759,60 @@ static void rna_def_property_free(StructOrFunctionRNA *cont_, PropertyRNA *prop) } } +static PropertyRNA *rna_def_property_find_py_id(ContainerRNA *cont, const char *identifier) +{ + for (PropertyRNA *prop = cont->properties.first; prop; prop = prop->next) { + if (STREQ(prop->identifier, identifier)) { + return prop; + } + } + return NULL; +} + /* NOTE: only intended for removing dynamic props. */ int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier) { ContainerRNA *cont = cont_; - PropertyRNA *prop; + PropertyRNA *prop = rna_def_property_find_py_id(cont, identifier); + if (prop != NULL) { + if (prop->flag_internal & PROP_INTERN_RUNTIME) { + rna_def_property_free(cont, prop); + return 1; + } + else { + return -1; + } + } + return 0; +} - for (prop = cont->properties.first; prop; prop = prop->next) { - if (STREQ(prop->identifier, identifier)) { - if (prop->flag_internal & PROP_INTERN_RUNTIME) { - rna_def_property_free(cont_, prop); - return 1; - } - else { - return -1; - } +int RNA_def_property_free_identifier_deferred_prepare(StructOrFunctionRNA *cont_, + const char *identifier, + void **r_handle) +{ + ContainerRNA *cont = cont_; + PropertyRNA *prop = rna_def_property_find_py_id(cont, identifier); + if (prop != NULL) { + if (prop->flag_internal & PROP_INTERN_RUNTIME) { + *r_handle = prop; + return 1; + } + else { + return -1; } } return 0; } + +void RNA_def_property_free_identifier_deferred_finish(StructOrFunctionRNA *cont_, void *handle) +{ + ContainerRNA *cont = cont_; + PropertyRNA *prop = handle; + BLI_assert(BLI_findindex(&cont->properties, prop) != -1); + BLI_assert(prop->flag_internal & PROP_INTERN_RUNTIME); + rna_def_property_free(cont, prop); +} + #endif /* RNA_RUNTIME */ const char *RNA_property_typename(PropertyType type) -- cgit v1.2.3