diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 60ab231ffc9..a9dbbe4273f 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -1032,6 +1032,13 @@ short RNA_type_to_ID_code(StructRNA *type); StructRNA *ID_code_to_RNA_type(short idcode); +#define RNA_POINTER_INVALIDATE(ptr) { \ + /* this is checked for validity */ \ + (ptr)->type = \ + /* should not be needed but prevent bad pointer access, just in case */ \ + (ptr)->id.data = NULL; \ +} (void)0 + /* macro which inserts the function name */ #if defined __GNUC__ || defined __sun # define RNA_warning(format, args ...) _RNA_warning("%s: " format "\n", __func__, ##args) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 2d0b64f8df5..8c7e4a53163 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -2095,6 +2095,8 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA /* fixed size arrays and RNA pointers are pre-allocated on the ParameterList stack, pass a pointer to it */ else if (type == PROP_POINTER || dparm->prop->arraydimension) ptrstr = "*"; + else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP)) + ptrstr = "*"; /* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack, * but type name for string props is already char*, so leave empty */ else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) @@ -2146,6 +2148,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA ptrstr = "**"; valstr = "*"; } + else if ((type == PROP_POINTER) && !(flag & PROP_THICK_WRAP)) { + ptrstr = "**"; + valstr = "*"; + } else if (type == PROP_POINTER || dparm->prop->arraydimension) { ptrstr = "*"; valstr = ""; diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index ffeb221a847..bb1ecea6a24 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -981,8 +981,10 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier sprop->defaultvalue = ""; break; } - case PROP_ENUM: case PROP_POINTER: + prop->flag |= PROP_THICK_WRAP; /* needed for default behavior when PROP_RNAPTR is set */ + break; + case PROP_ENUM: case PROP_COLLECTION: break; default: @@ -2810,14 +2812,26 @@ int rna_parameter_size(PropertyRNA *parm) { #ifdef RNA_RUNTIME if (parm->flag & PROP_RNAPTR) - return sizeof(PointerRNA); + if (parm->flag & PROP_THICK_WRAP) { + return sizeof(PointerRNA); + } + else { + return sizeof(PointerRNA *); + } else return sizeof(void *); #else - if (parm->flag & PROP_RNAPTR) - return sizeof(PointerRNA); - else + if (parm->flag & PROP_RNAPTR) { + if (parm->flag & PROP_THICK_WRAP) { + return sizeof(PointerRNA); + } + else { + return sizeof(PointerRNA *); + } + } + else { return sizeof(void *); + } #endif } case PROP_COLLECTION: diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index eaa1149b3b4..0f4ca7e044a 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -296,15 +296,17 @@ static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, con return ima; } -static void rna_Main_images_remove(Main *bmain, ReportList *reports, Image *image) +static void rna_Main_images_remove(Main *bmain, ReportList *reports, struct PointerRNA *image_ptr) { - if (ID_REAL_USERS(image) <= 0) + Image *image = image_ptr->data; + if (ID_REAL_USERS(image) <= 0) { BKE_libblock_free(&bmain->image, image); - else + RNA_POINTER_INVALIDATE(image_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Image '%s' must have zero users to be removed, found %d", image->id.name + 2, ID_REAL_USERS(image)); - - /* XXX python now has invalid pointer? */ + } } static Lattice *rna_Main_lattices_new(Main *UNUSED(bmain), const char *name) @@ -1015,7 +1017,8 @@ void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove an image from the current blendfile"); parm = RNA_def_pointer(func, "image", "Image", "", "Image to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* pass the pointer direct */ func = RNA_def_function(srna, "tag", "rna_Main_images_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index db9ff2e1a32..3b57e550c28 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -121,8 +121,7 @@ int pyrna_prop_validity_check(BPy_PropertyRNA *self) void pyrna_invalidate(BPy_DummyPointerRNA *self) { - self->ptr.type = NULL; /* this is checked for validity */ - self->ptr.id.data = NULL; /* should not be needed but prevent bad pointer access, just in case */ + RNA_POINTER_INVALIDATE(&self->ptr); } #ifdef USE_PYRNA_INVALIDATE_GC @@ -1776,10 +1775,21 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb if (data) { if (flag & PROP_RNAPTR) { - if (value == Py_None) - memset(data, 0, sizeof(PointerRNA)); - else - *((PointerRNA *)data) = param->ptr; + if (flag & PROP_THICK_WRAP) { + if (value == Py_None) + memset(data, 0, sizeof(PointerRNA)); + else + *((PointerRNA *)data) = param->ptr; + } + else { + /* for function calls, we sometimes want to pass the 'ptr' directly, + * watch out that it remains valid!, possibly we could support this later if needed */ + BLI_assert(value_new == NULL); + if (value == Py_None) + *((void **)data) = NULL; + else + *((PointerRNA **)data) = ¶m->ptr; + } } else if (value == Py_None) { *((void **)data) = NULL;