StructRNA *rna_PropertyGroup_register(Main *UNUSED(bmain), ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc UNUSED(call), StructFreeFunc UNUSED(free)) { PointerRNA dummyptr; /* create dummy pointer */ RNA_pointer_create(NULL, &RNA_PropertyGroup, NULL, &dummyptr); /* validate the python class */ if (validate(&dummyptr, data, NULL) != 0) return NULL; /* note: it looks like there is no length limit on the srna id since its * just a char pointer, but take care here, also be careful that python * owns the string pointer which it could potentially free while blender * is running. */ if (BLI_strnlen(identifier, MAX_IDPROP_NAME) == MAX_IDPROP_NAME) { BKE_reportf(reports, RPT_ERROR, "Registering id property class: '%s' is too long, maximum length is %d", identifier, MAX_IDPROP_NAME); return NULL; } return RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_PropertyGroup); /* XXX */ }
static StructRNA *rna_UIList_register( Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { uiListType *ult, dummyult = {NULL}; uiList dummyuilist = {NULL}; PointerRNA dummyul_ptr; int have_function[3]; size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */ /* setup dummy menu & menu type to store static properties in */ dummyuilist.type = &dummyult; RNA_pointer_create(NULL, &RNA_UIList, &dummyuilist, &dummyul_ptr); /* validate the python class */ if (validate(&dummyul_ptr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummyult.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering uilist class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyult.idname)); return NULL; } /* check if we have registered this uilist type before, and remove it */ ult = WM_uilisttype_find(dummyult.idname, true); if (ult && ult->ext.srna) { rna_UIList_unregister(bmain, ult->ext.srna); } if (!RNA_struct_available_or_report(reports, dummyult.idname)) { return NULL; } if (!RNA_struct_bl_idname_ok_or_report(reports, dummyult.idname, "_UL_")) { return NULL; } /* create a new menu type */ ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist"); memcpy(ult, &dummyult, sizeof(dummyult)); ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList); ult->ext.data = data; ult->ext.call = call; ult->ext.free = free; RNA_struct_blender_type_set(ult->ext.srna, ult); ult->draw_item = (have_function[0]) ? uilist_draw_item : NULL; ult->draw_filter = (have_function[1]) ? uilist_draw_filter : NULL; ult->filter_items = (have_function[2]) ? uilist_filter_items : NULL; WM_uilisttype_add(ult); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); return ult->ext.srna; }
static StructRNA *rna_RenderEngine_register( Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { RenderEngineType *et, dummyet = {NULL}; RenderEngine dummyengine = {NULL}; PointerRNA dummyptr; int have_function[7]; /* setup dummy engine & engine type to store static properties in */ dummyengine.type = &dummyet; dummyet.flag |= RE_USE_SHADING_NODES_CUSTOM; RNA_pointer_create(NULL, &RNA_RenderEngine, &dummyengine, &dummyptr); /* validate the python class */ if (validate(&dummyptr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummyet.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering render engine class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyet.idname)); return NULL; } /* check if we have registered this engine type before, and remove it */ for (et = R_engines.first; et; et = et->next) { if (STREQ(et->idname, dummyet.idname)) { if (et->ext.srna) rna_RenderEngine_unregister(bmain, et->ext.srna); break; } } /* create a new engine type */ et = MEM_callocN(sizeof(RenderEngineType), "python render engine"); memcpy(et, &dummyet, sizeof(dummyet)); et->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, et->idname, &RNA_RenderEngine); et->ext.data = data; et->ext.call = call; et->ext.free = free; RNA_struct_blender_type_set(et->ext.srna, et); et->update = (have_function[0]) ? engine_update : NULL; et->render = (have_function[1]) ? engine_render : NULL; et->bake = (have_function[2]) ? engine_bake : NULL; et->view_update = (have_function[3]) ? engine_view_update : NULL; et->view_draw = (have_function[4]) ? engine_view_draw : NULL; et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL; et->update_render_passes = (have_function[6]) ? engine_update_render_passes : NULL; BLI_addtail(&R_engines, et); return et->ext.srna; }
static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { ARegionType *art; HeaderType *ht, dummyht = {NULL}; Header dummyheader = {NULL}; PointerRNA dummyhtr; int have_function[1]; /* setup dummy header & header type to store static properties in */ dummyheader.type = &dummyht; RNA_pointer_create(NULL, &RNA_Header, &dummyheader, &dummyhtr); /* validate the python class */ if (validate(&dummyhtr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummyht.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering header class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyht.idname)); return NULL; } if (!(art = region_type_find(reports, dummyht.space_type, RGN_TYPE_HEADER))) return NULL; /* 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->ext.srna) rna_Header_unregister(bmain, ht->ext.srna); break; } } /* create a new header type */ ht = MEM_callocN(sizeof(HeaderType), "python buttons header"); memcpy(ht, &dummyht, sizeof(dummyht)); ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_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; BLI_addtail(&art->headertypes, ht); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); return ht->ext.srna; }
static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { KeyingSetInfo dummyksi = {NULL}; KeyingSetInfo *ksi; PointerRNA dummyptr = {{NULL}}; int have_function[3]; /* setup dummy type info to store static properties in */ /* TODO: perhaps we want to get users to register as if they're using 'KeyingSet' directly instead? */ RNA_pointer_create(NULL, &RNA_KeyingSetInfo, &dummyksi, &dummyptr); /* validate the python class */ if (validate(&dummyptr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummyksi.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering keying set info class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyksi.idname)); return NULL; } /* check if we have registered this info before, and remove it */ ksi = ANIM_keyingset_info_find_name(dummyksi.idname); if (ksi && ksi->ext.srna) rna_KeyingSetInfo_unregister(bmain, ksi->ext.srna); /* create a new KeyingSetInfo type */ ksi = MEM_callocN(sizeof(KeyingSetInfo), "python keying set info"); memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo)); /* set RNA-extensions info */ ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo); ksi->ext.data = data; ksi->ext.call = call; ksi->ext.free = free; RNA_struct_blender_type_set(ksi->ext.srna, ksi); /* set callbacks */ /* NOTE: we really should have all of these... */ ksi->poll = (have_function[0]) ? RKS_POLL_rna_internal : NULL; ksi->iter = (have_function[1]) ? RKS_ITER_rna_internal : NULL; ksi->generate = (have_function[2]) ? RKS_GEN_rna_internal : NULL; /* add and register with other info as needed */ ANIM_keyingset_info_register(ksi); WM_main_add_notifier(NC_WINDOW, NULL); /* return the struct-rna added */ return ksi->ext.srna; }
static StructRNA *rna_Menu_register( Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { MenuType *mt, dummymt = {NULL}; Menu dummymenu = {NULL}; PointerRNA dummymtr; int have_function[2]; size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */ size_t description_size = 0; char _menu_descr[RNA_DYN_DESCR_MAX]; /* setup dummy menu & menu type to store static properties in */ dummymenu.type = &dummymt; _menu_descr[0] = '\0'; dummymenu.type->description = _menu_descr; RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr); /* We have to set default context! Else we get a void string... */ strcpy(dummymt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); /* validate the python class */ if (validate(&dummymtr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummymt.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering menu class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummymt.idname)); return NULL; } /* check if we have registered this menu type before, and remove it */ mt = WM_menutype_find(dummymt.idname, true); if (mt && mt->ext.srna) { rna_Menu_unregister(bmain, mt->ext.srna); } if (!RNA_struct_available_or_report(reports, dummymt.idname)) { return NULL; } if (!RNA_struct_bl_idname_ok_or_report(reports, dummymt.idname, "_MT_")) { return NULL; } /* create a new menu type */ if (_menu_descr[0]) { description_size = strlen(_menu_descr) + 1; over_alloc += description_size; } mt = MEM_callocN(sizeof(MenuType) + over_alloc, "python buttons menu"); memcpy(mt, &dummymt, sizeof(dummymt)); if (_menu_descr[0]) { char *buf = (char *)(mt + 1); memcpy(buf, _menu_descr, description_size); mt->description = buf; } else mt->description = ""; mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu); RNA_def_struct_translation_context(mt->ext.srna, mt->translation_context); mt->ext.data = data; mt->ext.call = call; mt->ext.free = free; RNA_struct_blender_type_set(mt->ext.srna, mt); RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES); mt->poll = (have_function[0]) ? menu_poll : NULL; mt->draw = (have_function[1]) ? menu_draw : NULL; WM_menutype_add(mt); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); return mt->ext.srna; }
static StructRNA *rna_Panel_register( Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { ARegionType *art; PanelType *pt, dummypt = {NULL}; Panel dummypanel = {NULL}; PointerRNA dummyptr; int have_function[3]; /* setup dummy panel & panel type to store static properties in */ dummypanel.type = &dummypt; RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr); /* We have to set default context! Else we get a void string... */ strcpy(dummypt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); /* validate the python class */ if (validate(&dummyptr, data, have_function) != 0) return NULL; if (strlen(identifier) >= sizeof(dummypt.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering panel class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummypt.idname)); return NULL; } if ((dummypt.category[0] == '\0') && (dummypt.region_type == RGN_TYPE_TOOLS)) { /* Use a fallback, otherwise an empty value will draw the panel in every category. */ strcpy(dummypt.category, PNL_CATEGORY_FALLBACK); } if (!(art = region_type_find(reports, dummypt.space_type, dummypt.region_type))) return NULL; /* check if we have registered this panel type before, and remove it */ for (pt = art->paneltypes.first; pt; pt = pt->next) { if (STREQ(pt->idname, dummypt.idname)) { if (pt->ext.srna) rna_Panel_unregister(bmain, pt->ext.srna); else BLI_freelinkN(&art->paneltypes, pt); break; } } if (!RNA_struct_available_or_report(reports, dummypt.idname)) { return NULL; } if (!RNA_struct_bl_idname_ok_or_report(reports, dummypt.idname, "_PT_")) { return NULL; } /* create a new panel type */ pt = MEM_callocN(sizeof(PanelType), "python buttons panel"); memcpy(pt, &dummypt, sizeof(dummypt)); pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel); RNA_def_struct_translation_context(pt->ext.srna, pt->translation_context); pt->ext.data = data; pt->ext.call = call; pt->ext.free = free; RNA_struct_blender_type_set(pt->ext.srna, pt); RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES); pt->poll = (have_function[0]) ? panel_poll : NULL; pt->draw = (have_function[1]) ? panel_draw : NULL; pt->draw_header = (have_function[2]) ? panel_draw_header : NULL; /* XXX use "no header" flag for some ordering of panels until we have real panel ordering */ if (pt->flag & PNL_NO_HEADER) { PanelType *pth = art->paneltypes.first; while (pth && pth->flag & PNL_NO_HEADER) pth = pth->next; if (pth) BLI_insertlinkbefore(&art->paneltypes, pth, pt); else BLI_addtail(&art->paneltypes, pt); } else BLI_addtail(&art->paneltypes, pt); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); return pt->ext.srna; }