From 6b8dae0874d774888374992fc3923affb451c45a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 21 Jul 2009 20:05:16 +0000 Subject: RNA * ID blocks can now get RNA properties defined from python, e.g.: bpy.types.Scene.BoolProperty(..) * RNA structs/functions/properties can now get pointers duplicated (mostly strings), since we can't point to some static string then. * Added ExtensionRNA struct to add into *Type structs for subclassing, is a bit more compact than defining the 4 variables each time. Only disadvantage is it requires including RNA in more places. --- source/blender/blenkernel/BKE_screen.h | 27 ++--- source/blender/blenkernel/intern/screen.c | 12 +- source/blender/blenloader/CMakeLists.txt | 2 +- source/blender/blenloader/SConscript | 2 +- source/blender/blenloader/intern/Makefile | 1 + source/blender/makesrna/RNA_define.h | 9 ++ source/blender/makesrna/RNA_types.h | 20 +++- source/blender/makesrna/intern/rna_define.c | 152 ++++++++++++++++++++++++- source/blender/makesrna/intern/rna_ui.c | 78 ++++++------- source/blender/nodes/CMakeLists.txt | 2 +- source/blender/nodes/SConscript | 2 +- source/blender/nodes/intern/CMP_nodes/Makefile | 1 + source/blender/nodes/intern/Makefile | 1 + source/blender/nodes/intern/SHD_nodes/Makefile | 1 + source/blender/nodes/intern/TEX_nodes/Makefile | 1 + source/blender/python/intern/bpy_rna.c | 108 +++++++++++++++++- 16 files changed, 341 insertions(+), 78 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 5a12c04780a..4fcb7c881be 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -46,10 +46,8 @@ struct wmWindow; struct wmWindowManager; struct uiLayout; struct uiMenuItem; -struct StructRNA; -struct PointerRNA; -struct FunctionRNA; -struct ParameterList; + +#include "RNA_types.h" /* spacetype has everything stored to get an editor working, it gets initialized via ED_spacetypes_init() in editors/area/spacetypes.c */ @@ -169,11 +167,8 @@ typedef struct PanelType { /* draw entirely, view changes should be handled here */ void (*draw)(const struct bContext *, struct Panel *); - /* python integration */ - void *py_data; - struct StructRNA *py_srna; - int (*py_call)(struct PointerRNA *, struct FunctionRNA *, struct ParameterList *); - void (*py_free)(void *py_data); + /* RNA integration */ + ExtensionRNA ext; } PanelType; /* header types */ @@ -187,11 +182,8 @@ typedef struct HeaderType { /* draw entirely, view changes should be handled here */ void (*draw)(const struct bContext *, struct Header *); - /* python integration */ - void *py_data; - struct StructRNA *py_srna; - int (*py_call)(struct PointerRNA *, struct FunctionRNA *, struct ParameterList *); - void (*py_free)(void *py_data); + /* RNA integration */ + ExtensionRNA ext; } HeaderType; typedef struct Header { @@ -214,11 +206,8 @@ typedef struct MenuType { /* draw entirely, view changes should be handled here */ void (*draw)(const struct bContext *, struct Menu *); - /* python integration */ - void *py_data; - struct StructRNA *py_srna; - int (*py_call)(struct PointerRNA *, struct FunctionRNA *, struct ParameterList *); - void (*py_free)(void *py_data); + /* RNA integration */ + ExtensionRNA ext; } MenuType; typedef struct Menu { diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 4b6eddf60d0..d7aa38d5d03 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -61,16 +61,16 @@ static void spacetype_free(SpaceType *st) BLI_freelistN(&art->drawcalls); for(pt= art->paneltypes.first; pt; pt= pt->next) - if(pt->py_free) - pt->py_free(pt->py_data); + if(pt->ext.free) + pt->ext.free(pt->ext.data); for(ht= art->headertypes.first; ht; ht= ht->next) - if(ht->py_free) - ht->py_free(ht->py_data); + if(ht->ext.free) + ht->ext.free(ht->ext.data); for(mt= art->menutypes.first; mt; mt= mt->next) - if(mt->py_free) - mt->py_free(mt->py_data); + if(mt->ext.free) + mt->ext.free(mt->ext.data); BLI_freelistN(&art->paneltypes); BLI_freelistN(&art->headertypes); diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 1b9c5647702..7bdffdedc05 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -28,7 +28,7 @@ FILE(GLOB SRC intern/*.c) SET(INC . ../../../intern/guardedalloc ../blenlib ../blenkernel - ../makesdna ../readblenfile ../include + ../makesdna ../readblenfile ../include ../makesrna ../python ../../kernel/gen_messaging ../render/extern/include ${ZLIB_INC} diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 1aeb6bd9b83..19a89b7e604 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('intern/*.c') incs = '. #/intern/guardedalloc ../blenlib ../blenkernel' incs += ' ../makesdna ../readblenfile ../editors/include' -incs += ' ../render/extern/include' +incs += ' ../render/extern/include ../makesrna' incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenloader/intern/Makefile b/source/blender/blenloader/intern/Makefile index 7382dd655b2..f4690fcc066 100644 --- a/source/blender/blenloader/intern/Makefile +++ b/source/blender/blenloader/intern/Makefile @@ -54,6 +54,7 @@ CPPFLAGS += -I../../readblenfile # This mod uses the GEN, DNA, BLI and BKE modules CPPFLAGS += -I../../../kernel/gen_messaging CPPFLAGS += -I../../makesdna +CPPFLAGS += -I../../makesrna CPPFLAGS += -I../../blenlib # path to the guarded memory allocator CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index f76423ea846..ae9eaba8646 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -170,6 +170,15 @@ void RNA_enum_items_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item, int value); void RNA_enum_item_end(EnumPropertyItem **items, int *totitem); +/* Memory management */ + +void RNA_def_struct_duplicate_pointers(StructRNA *srna); +void RNA_def_struct_free_pointers(StructRNA *srna); +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); + #ifdef __cplusplus } #endif diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index bf4fa97b6fe..243551b527e 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -113,6 +113,7 @@ typedef enum PropertyFlag { PROP_IDPROPERTY = 1024, PROP_RAW_ACCESS = 8192, PROP_RAW_ARRAY = 16384, + PROP_FREE_POINTERS = 32768 } PropertyFlag; typedef struct CollectionPropertyIterator { @@ -198,7 +199,8 @@ typedef enum FunctionFlag { /* internal flags */ FUNC_BUILTIN = 128, FUNC_EXPORT = 256, - FUNC_RUNTIME = 512 + FUNC_RUNTIME = 512, + FUNC_FREE_POINTERS = 1024 } FunctionFlag; typedef void (*CallFunc)(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, ParameterList *parms); @@ -214,7 +216,8 @@ typedef enum StructFlag { /* internal flags */ STRUCT_RUNTIME = 4, - STRUCT_GENERATED = 8 + STRUCT_GENERATED = 8, + STRUCT_FREE_POINTERS = 16 } StructFlag; typedef int (*StructValidateFunc)(struct PointerRNA *ptr, void *data, int *have_function); @@ -232,6 +235,19 @@ typedef struct StructRNA StructRNA; typedef struct BlenderRNA BlenderRNA; +/* Extending + * + * This struct must be embedded in *Type structs in + * order to make then definable through RNA. */ + +typedef struct ExtensionRNA { + void *data; + StructRNA *srna; + + int (*call)(PointerRNA *, FunctionRNA *, ParameterList *); + void (*free)(void *data); +} ExtensionRNA; + #ifdef __cplusplus } #endif diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 491095a0bd6..2530f452393 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -39,6 +39,7 @@ #include "RNA_types.h" #include "BLI_ghash.h" +#include "BLI_string.h" #include "rna_internal.h" @@ -445,6 +446,7 @@ void RNA_define_verify_sdna(int verify) void RNA_struct_free(BlenderRNA *brna, StructRNA *srna) { +#ifdef RNA_RUNTIME FunctionRNA *func, *nextfunc; PropertyRNA *prop, *nextprop; PropertyRNA *parm, *nextparm; @@ -452,6 +454,8 @@ void RNA_struct_free(BlenderRNA *brna, StructRNA *srna) for(prop=srna->cont.properties.first; prop; prop=nextprop) { nextprop= prop->next; + RNA_def_property_free_pointers(prop); + if(prop->flag & PROP_RUNTIME) rna_freelinkN(&srna->cont.properties, prop); } @@ -462,17 +466,23 @@ void RNA_struct_free(BlenderRNA *brna, StructRNA *srna) for(parm=func->cont.properties.first; parm; parm=nextparm) { nextparm= parm->next; + RNA_def_property_free_pointers(parm); + if(parm->flag & PROP_RUNTIME) rna_freelinkN(&func->cont.properties, parm); } - if(func->flag & FUNC_RUNTIME) { + RNA_def_func_free_pointers(func); + + if(func->flag & FUNC_RUNTIME) rna_freelinkN(&srna->functions, func); - } } + RNA_def_struct_free_pointers(srna); + if(srna->flag & STRUCT_RUNTIME) rna_freelinkN(&brna->structs, srna); +#endif } void RNA_free(BlenderRNA *brna) @@ -2327,3 +2337,141 @@ void RNA_enum_item_end(EnumPropertyItem **items, int *totitem) RNA_enum_item_add(items, totitem, &empty); } +/* Memory management */ + +#ifdef RNA_RUNTIME +void RNA_def_struct_duplicate_pointers(StructRNA *srna) +{ + if(srna->identifier) srna->identifier= BLI_strdup(srna->identifier); + if(srna->name) srna->name= BLI_strdup(srna->name); + if(srna->description) srna->description= BLI_strdup(srna->description); + + srna->flag |= STRUCT_FREE_POINTERS; +} + +void RNA_def_struct_free_pointers(StructRNA *srna) +{ + if(srna->flag & STRUCT_FREE_POINTERS) { + if(srna->identifier) MEM_freeN((void*)srna->identifier); + if(srna->name) MEM_freeN((void*)srna->name); + if(srna->description) MEM_freeN((void*)srna->description); + } +} + +void RNA_def_func_duplicate_pointers(FunctionRNA *func) +{ + if(func->identifier) func->identifier= BLI_strdup(func->identifier); + if(func->description) func->description= BLI_strdup(func->description); + + func->flag |= FUNC_FREE_POINTERS; +} + +void RNA_def_func_free_pointers(FunctionRNA *func) +{ + if(func->flag & FUNC_FREE_POINTERS) { + if(func->identifier) MEM_freeN((void*)func->identifier); + if(func->description) MEM_freeN((void*)func->description); + } +} + +void RNA_def_property_duplicate_pointers(PropertyRNA *prop) +{ + EnumPropertyItem *earray; + float *farray; + int *iarray; + + if(prop->identifier) prop->identifier= BLI_strdup(prop->identifier); + if(prop->name) prop->name= BLI_strdup(prop->name); + if(prop->description) prop->description= BLI_strdup(prop->description); + + switch(prop->type) { + case PROP_BOOLEAN: { + BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; + + if(bprop->defaultarray) { + iarray= MEM_callocN(sizeof(int)*prop->arraylength, "RNA_def_property_store"); + memcpy(iarray, bprop->defaultarray, sizeof(int)*prop->arraylength); + bprop->defaultarray= iarray; + } + break; + } + case PROP_INT: { + IntPropertyRNA *iprop= (IntPropertyRNA*)prop; + + if(iprop->defaultarray) { + iarray= MEM_callocN(sizeof(int)*prop->arraylength, "RNA_def_property_store"); + memcpy(iarray, iprop->defaultarray, sizeof(int)*prop->arraylength); + iprop->defaultarray= iarray; + } + break; + } + case PROP_ENUM: { + EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop; + + if(eprop->item) { + earray= MEM_callocN(sizeof(EnumPropertyItem)*(eprop->totitem+1), "RNA_def_property_store"), + memcpy(earray, eprop->item, sizeof(EnumPropertyItem)*(eprop->totitem+1)); + eprop->item= earray; + } + } + case PROP_FLOAT: { + FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; + + if(fprop->defaultarray) { + farray= MEM_callocN(sizeof(float)*prop->arraylength, "RNA_def_property_store"); + memcpy(farray, fprop->defaultarray, sizeof(float)*prop->arraylength); + fprop->defaultarray= farray; + } + break; + } + case PROP_STRING: { + StringPropertyRNA *sprop= (StringPropertyRNA*)prop; + if(sprop->defaultvalue) sprop->defaultvalue= BLI_strdup(sprop->defaultvalue); + break; + } + default: + break; + } + + prop->flag |= PROP_FREE_POINTERS; +} + +void RNA_def_property_free_pointers(PropertyRNA *prop) +{ + if(prop->flag & PROP_FREE_POINTERS) { + if(prop->identifier) MEM_freeN((void*)prop->identifier); + if(prop->name) MEM_freeN((void*)prop->name); + if(prop->description) MEM_freeN((void*)prop->description); + + switch(prop->type) { + case PROP_BOOLEAN: { + BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; + if(bprop->defaultarray) MEM_freeN((void*)bprop->defaultarray); + break; + } + case PROP_INT: { + IntPropertyRNA *iprop= (IntPropertyRNA*)prop; + if(iprop->defaultarray) MEM_freeN((void*)iprop->defaultarray); + break; + } + case PROP_FLOAT: { + FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; + if(fprop->defaultarray) MEM_freeN((void*)fprop->defaultarray); + break; + } + case PROP_ENUM: { + EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop; + if(eprop->item) MEM_freeN((void*)eprop->item); + } + case PROP_STRING: { + StringPropertyRNA *sprop= (StringPropertyRNA*)prop; + if(sprop->defaultvalue) MEM_freeN((void*)sprop->defaultvalue); + break; + } + default: + break; + } + } +} +#endif + diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 8a51a5f4142..21bacc76a8c 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -81,12 +81,12 @@ static int panel_poll(const bContext *C, PanelType *pt) void *ret; int visible; - RNA_pointer_create(NULL, pt->py_srna, NULL, &ptr); /* dummy */ + RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */ func= RNA_struct_find_function(&ptr, "poll"); RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - pt->py_call(&ptr, func, &list); + pt->ext.call(&ptr, func, &list); RNA_parameter_get_lookup(&list, "visible", &ret); visible= *(int*)ret; @@ -102,12 +102,12 @@ static void panel_draw(const bContext *C, Panel *pnl) ParameterList list; FunctionRNA *func; - RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr); + RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->ext.srna, pnl, &ptr); func= RNA_struct_find_function(&ptr, "draw"); RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - pnl->type->py_call(&ptr, func, &list); + pnl->type->ext.call(&ptr, func, &list); RNA_parameter_list_free(&list); } @@ -118,12 +118,12 @@ static void panel_draw_header(const bContext *C, Panel *pnl) ParameterList list; FunctionRNA *func; - RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr); + RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->ext.srna, pnl, &ptr); func= RNA_struct_find_function(&ptr, "draw_header"); RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - pnl->type->py_call(&ptr, func, &list); + pnl->type->ext.call(&ptr, func, &list); RNA_parameter_list_free(&list); } @@ -168,8 +168,8 @@ static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, voi /* check if we have registered this panel type before, and remove it */ for(pt=art->paneltypes.first; pt; pt=pt->next) { if(strcmp(pt->idname, dummypt.idname) == 0) { - if(pt->py_srna) - rna_Panel_unregister(C, pt->py_srna); + if(pt->ext.srna) + rna_Panel_unregister(C, pt->ext.srna); else BLI_freelinkN(&art->paneltypes, pt); break; @@ -180,11 +180,11 @@ static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, voi pt= MEM_callocN(sizeof(PanelType), "python buttons panel"); memcpy(pt, &dummypt, sizeof(dummypt)); - pt->py_srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); - pt->py_data= data; - pt->py_call= call; - pt->py_free= free; - RNA_struct_blender_type_set(pt->py_srna, pt); + pt->ext.srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); + pt->ext.data= data; + pt->ext.call= call; + pt->ext.free= free; + RNA_struct_blender_type_set(pt->ext.srna, pt); pt->poll= (have_function[0])? panel_poll: NULL; pt->draw= (have_function[1])? panel_draw: NULL; @@ -196,13 +196,13 @@ static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, voi if(C) WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); - return pt->py_srna; + return pt->ext.srna; } static StructRNA* rna_Panel_refine(PointerRNA *ptr) { Panel *hdr= (Panel*)ptr->data; - return (hdr->type && hdr->type->py_srna)? hdr->type->py_srna: &RNA_Panel; + return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Panel; } /* Header */ @@ -213,12 +213,12 @@ static void header_draw(const bContext *C, Header *hdr) ParameterList list; FunctionRNA *func; - RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->py_srna, hdr, &htr); + RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &htr); func= RNA_struct_find_function(&htr, "draw"); RNA_parameter_list_create(&list, &htr, func); RNA_parameter_set_lookup(&list, "context", &C); - hdr->type->py_call(&htr, func, &list); + hdr->type->ext.call(&htr, func, &list); RNA_parameter_list_free(&list); } @@ -263,8 +263,8 @@ static StructRNA *rna_Header_register(const bContext *C, ReportList *reports, vo /* check if we have registered this header type before, and remove it */ for(ht=art->headertypes.first; ht; ht=ht->next) { if(strcmp(ht->idname, dummyht.idname) == 0) { - if(ht->py_srna) - rna_Header_unregister(C, ht->py_srna); + if(ht->ext.srna) + rna_Header_unregister(C, ht->ext.srna); break; } } @@ -273,11 +273,11 @@ static StructRNA *rna_Header_register(const bContext *C, ReportList *reports, vo ht= MEM_callocN(sizeof(HeaderType), "python buttons header"); memcpy(ht, &dummyht, sizeof(dummyht)); - ht->py_srna= RNA_def_struct(&BLENDER_RNA, ht->idname, "Header"); - ht->py_data= data; - ht->py_call= call; - ht->py_free= free; - RNA_struct_blender_type_set(ht->py_srna, ht); + ht->ext.srna= RNA_def_struct(&BLENDER_RNA, ht->idname, "Header"); + ht->ext.data= data; + ht->ext.call= call; + ht->ext.free= free; + RNA_struct_blender_type_set(ht->ext.srna, ht); ht->draw= (have_function[0])? header_draw: NULL; @@ -287,13 +287,13 @@ static StructRNA *rna_Header_register(const bContext *C, ReportList *reports, vo if(C) WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); - return ht->py_srna; + return ht->ext.srna; } static StructRNA* rna_Header_refine(PointerRNA *htr) { Header *hdr= (Header*)htr->data; - return (hdr->type && hdr->type->py_srna)? hdr->type->py_srna: &RNA_Header; + return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Header; } /* Menu */ @@ -306,12 +306,12 @@ static int menu_poll(const bContext *C, MenuType *pt) void *ret; int visible; - RNA_pointer_create(NULL, pt->py_srna, NULL, &ptr); /* dummy */ + RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */ func= RNA_struct_find_function(&ptr, "poll"); RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - pt->py_call(&ptr, func, &list); + pt->ext.call(&ptr, func, &list); RNA_parameter_get_lookup(&list, "visible", &ret); visible= *(int*)ret; @@ -327,12 +327,12 @@ static void menu_draw(const bContext *C, Menu *hdr) ParameterList list; FunctionRNA *func; - RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->py_srna, hdr, &mtr); + RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &mtr); func= RNA_struct_find_function(&mtr, "draw"); RNA_parameter_list_create(&list, &mtr, func); RNA_parameter_set_lookup(&list, "context", &C); - hdr->type->py_call(&mtr, func, &list); + hdr->type->ext.call(&mtr, func, &list); RNA_parameter_list_free(&list); } @@ -377,8 +377,8 @@ static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void /* check if we have registered this menu type before, and remove it */ for(mt=art->menutypes.first; mt; mt=mt->next) { if(strcmp(mt->idname, dummymt.idname) == 0) { - if(mt->py_srna) - rna_Menu_unregister(C, mt->py_srna); + if(mt->ext.srna) + rna_Menu_unregister(C, mt->ext.srna); break; } } @@ -387,11 +387,11 @@ static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void mt= MEM_callocN(sizeof(MenuType), "python buttons menu"); memcpy(mt, &dummymt, sizeof(dummymt)); - mt->py_srna= RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); - mt->py_data= data; - mt->py_call= call; - mt->py_free= free; - RNA_struct_blender_type_set(mt->py_srna, mt); + mt->ext.srna= RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); + mt->ext.data= data; + mt->ext.call= call; + mt->ext.free= free; + RNA_struct_blender_type_set(mt->ext.srna, mt); mt->poll= (have_function[0])? menu_poll: NULL; mt->draw= (have_function[1])? menu_draw: NULL; @@ -402,13 +402,13 @@ static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void if(C) WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); - return mt->py_srna; + return mt->ext.srna; } static StructRNA* rna_Menu_refine(PointerRNA *mtr) { Menu *hdr= (Menu*)mtr->data; - return (hdr->type && hdr->type->py_srna)? hdr->type->py_srna: &RNA_Menu; + return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Menu; } static int rna_UILayout_active_get(PointerRNA *ptr) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index a4d5b0f0ed2..664aacf11ab 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -27,7 +27,7 @@ FILE(GLOB SRC intern/*.c intern/CMP_nodes/*.c intern/SHD_nodes/*.c intern/TEX_no SET(INC . ../../../intern/guardedalloc ../editors/include ../blenlib ../makesdna - ../render/extern/include ../../../intern/decimation/extern + ../render/extern/include ../../../intern/decimation/extern ../makesrna ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/iksolver/extern ../blenloader ../quicktime ../blenkernel ../../../extern/glew/include ../gpu diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 164e30c7d05..0b35db3b4b7 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -8,7 +8,7 @@ texsources = env.Glob('intern/TEX_nodes/*.c') incs = '. ./intern ' incs += '#/intern/guardedalloc ../editors/include ../blenlib ../makesdna' -incs += ' ../render/extern/include ' +incs += ' ../render/extern/include ../makesrna ' incs += ' ../imbuf ../avi ' incs += ' ../blenloader' incs += ' ../blenkernel ../renderconverter ' diff --git a/source/blender/nodes/intern/CMP_nodes/Makefile b/source/blender/nodes/intern/CMP_nodes/Makefile index b70b591a588..5e8753570af 100644 --- a/source/blender/nodes/intern/CMP_nodes/Makefile +++ b/source/blender/nodes/intern/CMP_nodes/Makefile @@ -38,6 +38,7 @@ CFLAGS += $(LEVEL_1_C_WARNINGS) CPPFLAGS += -I../../../blenkernel CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../../makesdna +CPPFLAGS += -I../../../makesrna CPPFLAGS += -I../../../blenlib CPPFLAGS += -I../../../editors/include CPPFLAGS += -I../../../imbuf diff --git a/source/blender/nodes/intern/Makefile b/source/blender/nodes/intern/Makefile index 04a00c1ac9a..08f4b936c76 100644 --- a/source/blender/nodes/intern/Makefile +++ b/source/blender/nodes/intern/Makefile @@ -38,6 +38,7 @@ CFLAGS += $(LEVEL_1_C_WARNINGS) CPPFLAGS += -I../../blenkernel CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../makesdna +CPPFLAGS += -I../../makesrna CPPFLAGS += -I../../blenlib CPPFLAGS += -I../../editors/include CPPFLAGS += -I../../imbuf diff --git a/source/blender/nodes/intern/SHD_nodes/Makefile b/source/blender/nodes/intern/SHD_nodes/Makefile index 1369d346fc6..b6b21d5f5f8 100644 --- a/source/blender/nodes/intern/SHD_nodes/Makefile +++ b/source/blender/nodes/intern/SHD_nodes/Makefile @@ -40,6 +40,7 @@ CPPFLAGS += -I../../../python CPPFLAGS += -I../../../blenkernel CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../../makesdna +CPPFLAGS += -I../../../makesrna CPPFLAGS += -I../../../blenlib CPPFLAGS += -I../../../editors/include CPPFLAGS += -I../../../imbuf diff --git a/source/blender/nodes/intern/TEX_nodes/Makefile b/source/blender/nodes/intern/TEX_nodes/Makefile index ac741280478..f42660bd562 100644 --- a/source/blender/nodes/intern/TEX_nodes/Makefile +++ b/source/blender/nodes/intern/TEX_nodes/Makefile @@ -41,6 +41,7 @@ CFLAGS += $(LEVEL_1_C_WARNINGS) CPPFLAGS += -I../../../blenkernel CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../../makesdna +CPPFLAGS += -I../../../makesrna CPPFLAGS += -I../../../blenlib CPPFLAGS += -I../../../include CPPFLAGS += -I../../../imbuf diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index bebb745a27e..7319a269ffb 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2282,6 +2282,15 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) /* done with rna instance */ } +static struct PyMethodDef pyrna_struct_subtype_methods[] = { + {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {NULL, NULL, 0, NULL} +}; + + PyObject* pyrna_srna_Subtype(StructRNA *srna) { PyObject *newclass = NULL; @@ -2358,6 +2367,17 @@ PyObject* pyrna_srna_Subtype(StructRNA *srna) if (newclass) { pyrna_subtype_set_rna(newclass, srna); // PyObSpit("NewStructRNA Type: ", (PyObject *)newclass); + + /* attach functions into the class + * so you can do... bpy.types.Scene.SomeFunction() + */ + { + PyMethodDef *ml; + for(ml= pyrna_struct_subtype_methods; ml->ml_name; ml++){ + PyObject_SetAttrString(newclass, ml->ml_name, PyCFunction_New(ml, newclass)); + } + } + } else { /* this should not happen */ @@ -2560,7 +2580,7 @@ static struct PyModuleDef props_module = { PyObject *BPY_rna_props( void ) { - PyObject *submodule, *mod; + PyObject *submodule; #if PY_VERSION_HEX >= 0x03000000 submodule= PyModule_Create(&props_module); #else /* Py2.x */ @@ -2584,6 +2604,7 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; char *id, *name="", *description=""; float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f; + PropertyRNA *prop; if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def)) return NULL; @@ -2595,8 +2616,26 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) if (self && PyCObject_Check(self)) { StructRNA *srna = PyCObject_AsVoidPtr(self); - RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max); + prop= RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max); + RNA_def_property_duplicate_pointers(prop); Py_RETURN_NONE; + } else if(self && PyType_Check(self)) { + PyObject *pyob= PyObject_GetAttrString(self, "__rna__"); + + if(pyob && BPy_StructRNA_Check(pyob)) { + BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob; + + if(py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) { + if(RNA_struct_is_ID(py_srna->ptr.data)) { + prop= RNA_def_float(py_srna->ptr.data, id, def, min, max, name, description, soft_min, soft_max); + RNA_def_property_duplicate_pointers(prop); + Py_RETURN_NONE; + } + } + } + + PyErr_SetString(PyExc_ValueError, "only works on ID types"); + return NULL; } else { PyObject *ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_FloatProperty, NULL)); @@ -2611,6 +2650,7 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; char *id, *name="", *description=""; int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, def=0; + PropertyRNA *prop; if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def)) return NULL; @@ -2622,8 +2662,26 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) if (self && PyCObject_Check(self)) { StructRNA *srna = PyCObject_AsVoidPtr(self); - RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max); + prop= RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max); + RNA_def_property_duplicate_pointers(prop); Py_RETURN_NONE; + } else if(self && PyType_Check(self)) { + PyObject *pyob= PyObject_GetAttrString(self, "__rna__"); + + if(pyob && BPy_StructRNA_Check(pyob)) { + BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob; + + if(py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) { + if(RNA_struct_is_ID(py_srna->ptr.data)) { + prop= RNA_def_int(py_srna->ptr.data, id, def, min, max, name, description, soft_min, soft_max); + RNA_def_property_duplicate_pointers(prop); + Py_RETURN_NONE; + } + } + } + + PyErr_SetString(PyExc_ValueError, "only works on ID types"); + return NULL; } else { PyObject *ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_IntProperty, NULL)); @@ -2638,6 +2696,7 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) static char *kwlist[] = {"attr", "name", "description", "default", NULL}; char *id, *name="", *description=""; int def=0; + PropertyRNA *prop; if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def)) return NULL; @@ -2646,11 +2705,29 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. return NULL; } - + if (self && PyCObject_Check(self)) { StructRNA *srna = PyCObject_AsVoidPtr(self); - RNA_def_boolean(srna, id, def, name, description); + prop= RNA_def_boolean(srna, id, def, name, description); + RNA_def_property_duplicate_pointers(prop); Py_RETURN_NONE; + } else if(self && PyType_Check(self)) { + PyObject *pyob= PyObject_GetAttrString(self, "__rna__"); + + if(pyob && BPy_StructRNA_Check(pyob)) { + BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob; + + if(py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) { + if(RNA_struct_is_ID(py_srna->ptr.data)) { + prop= RNA_def_boolean(py_srna->ptr.data, id, def, name, description); + RNA_def_property_duplicate_pointers(prop); + Py_RETURN_NONE; + } + } + } + + PyErr_SetString(PyExc_ValueError, "only works on ID types"); + return NULL; } else { PyObject *ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_BoolProperty, NULL)); @@ -2665,6 +2742,7 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) static char *kwlist[] = {"attr", "name", "description", "maxlen", "default", NULL}; char *id, *name="", *description="", *def=""; int maxlen=0; + PropertyRNA *prop; if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssis:StringProperty", kwlist, &id, &name, &description, &maxlen, &def)) return NULL; @@ -2676,8 +2754,26 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) if (self && PyCObject_Check(self)) { StructRNA *srna = PyCObject_AsVoidPtr(self); - RNA_def_string(srna, id, def, maxlen, name, description); + prop= RNA_def_string(srna, id, def, maxlen, name, description); + RNA_def_property_duplicate_pointers(prop); Py_RETURN_NONE; + } else if(self && PyType_Check(self)) { + PyObject *pyob= PyObject_GetAttrString(self, "__rna__"); + + if(pyob && BPy_StructRNA_Check(pyob)) { + BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob; + + if(py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) { + if(RNA_struct_is_ID(py_srna->ptr.data)) { + prop= RNA_def_string(py_srna->ptr.data, id, def, maxlen, name, description); + RNA_def_property_duplicate_pointers(prop); + Py_RETURN_NONE; + } + } + } + + PyErr_SetString(PyExc_ValueError, "only works on ID types"); + return NULL; } else { PyObject *ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_StringProperty, NULL)); -- cgit v1.2.3