diff --git a/source/blender/makesrna/RNA_types.hh b/source/blender/makesrna/RNA_types.hh index 358c07592df..7c14949ca22 100644 --- a/source/blender/makesrna/RNA_types.hh +++ b/source/blender/makesrna/RNA_types.hh @@ -791,9 +791,21 @@ enum FunctionFlag { */ FUNC_USE_SELF_ID = (1 << 11), + /** + * Pass 'self' data as a PointerRNA (by value), rather than as a pointer of the relevant DNA + * type. + * + * Mutually exclusive with #FUNC_NO_SELF and #FUNC_USE_SELF_TYPE. + * + * Useful for functions that need to access `self` as RNA data, not as DNA data (e.g. when doing + * 'generic', type-agnostic processing). + */ + FUNC_SELF_AS_RNA = (1 << 13), /** * Do not pass the object (DNA struct pointer) from which it is called, * used to define static or class functions. + * + * Mutually exclusive with #FUNC_SELF_AS_RNA. */ FUNC_NO_SELF = (1 << 0), /** Pass RNA type, used to define class functions, only valid when #FUNC_NO_SELF is set. */ diff --git a/source/blender/makesrna/intern/makesrna.cc b/source/blender/makesrna/intern/makesrna.cc index 0c58717d73f..8f8cdb252ad 100644 --- a/source/blender/makesrna/intern/makesrna.cc +++ b/source/blender/makesrna/intern/makesrna.cc @@ -2916,7 +2916,10 @@ static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, Func if ((func->flag & FUNC_NO_SELF) == 0) { WRITE_COMMA; - if (dsrna->dnafromprop) { + if ((func->flag & FUNC_SELF_AS_RNA) != 0) { + fprintf(f, "this->ptr"); + } + else if (dsrna->dnafromprop) { fprintf(f, "(::%s *) this->ptr.data", dsrna->dnafromname); } else if (dsrna->dnaname) { @@ -3170,7 +3173,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA } if ((func->flag & FUNC_NO_SELF) == 0) { - if (dsrna->dnafromprop) { + if ((func->flag & FUNC_SELF_AS_RNA) != 0) { + fprintf(f, "\tstruct PointerRNA _self;\n"); + } + else if (dsrna->dnafromprop) { fprintf(f, "\tstruct %s *_self;\n", dsrna->dnafromname); } else if (dsrna->dnaname) { @@ -3251,7 +3257,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA } if ((func->flag & FUNC_NO_SELF) == 0) { - if (dsrna->dnafromprop) { + if ((func->flag & FUNC_SELF_AS_RNA) != 0) { + fprintf(f, "\t_self = *_ptr;\n"); + } + else if (dsrna->dnafromprop) { fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", dsrna->dnafromname); } else if (dsrna->dnaname) { @@ -3904,7 +3913,10 @@ static void rna_generate_static_parameter_prototypes(FILE *f, if (!first) { fprintf(f, ", "); } - if (dsrna->dnafromprop) { + if ((func->flag & FUNC_SELF_AS_RNA) != 0) { + fprintf(f, "struct PointerRNA _self"); + } + else if (dsrna->dnafromprop) { fprintf(f, "struct %s *_self", dsrna->dnafromname); } else if (dsrna->dnaname) { diff --git a/source/blender/makesrna/intern/rna_define.cc b/source/blender/makesrna/intern/rna_define.cc index fff759b862c..1e34c440de9 100644 --- a/source/blender/makesrna/intern/rna_define.cc +++ b/source/blender/makesrna/intern/rna_define.cc @@ -4691,6 +4691,14 @@ void RNA_def_function_output(FunctionRNA * /*func*/, PropertyRNA *ret) void RNA_def_function_flag(FunctionRNA *func, int flag) { func->flag |= flag; + + if (func->flag & FUNC_USE_SELF_TYPE) { + BLI_assert_msg((func->flag & FUNC_NO_SELF) != 0, "FUNC_USE_SELF_TYPE requires FUNC_NO_SELF"); + } + if (func->flag & FUNC_SELF_AS_RNA) { + BLI_assert_msg((func->flag & FUNC_NO_SELF) == 0, + "FUNC_SELF_AS_RNA and FUNC_NO_SELF are mutually exclusive"); + } } void RNA_def_function_ui_description(FunctionRNA *func, const char *description)