2.5: RNA, defining enums, pointers and collections properties is now
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 18 Aug 2009 01:29:25 +0000 (01:29 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 18 Aug 2009 01:29:25 +0000 (01:29 +0000)
possible from python, but it's still work in progress.

Pointers and collections are restricted to types derived from
IDPropertyGroup (same as for operators), because RNA knows how to
allocate/deallocate those.

Collections have .add() and .remove(number) functions that can be
used. The remove function should be fixed to take an other argument
than a number.

With the IDPropertyGroup restriction, pointers are more like nested
structs. They don't have add(), remove() yet, not sure where to put
them. Currently the pointer / nested struct is automatically allocated
in the get() function, this needs to be fixed, rule is that RNA get()
will not change any data for thread safety.

Also, it is only possible to add properties to structs after they have
been registered, which needs to be improved as well.

Example code:
http://www.pasteall.org/7201/python

15 files changed:
source/blender/blenkernel/intern/idprop.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/screen/screen_ops.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_ui.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna.h

index 54366aadd92b6aa86b8a15e4583f310c27b68a77..3cff82f522a507c03037b3d52ac79abbd6c3d85d 100644 (file)
@@ -167,7 +167,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
                for (i=newlen; i<prop->len; i++) {
                        IDP_FreeProperty(GETPROP(prop, i));
                }
-               memcpy(newarr, prop->data.pointer, newlen*prop->len*sizeof(IDProperty));
+               memcpy(newarr, prop->data.pointer, newlen*sizeof(IDProperty));
        }
 
        if(prop->data.pointer)
index 9272c6fe353a55541fd02bb2f4c00066c2bb7d6e..61f6cb8b44c706ed008f026c10800afc40aa4fe2 100644 (file)
@@ -1366,7 +1366,7 @@ void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
 
 static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData *fd)
 {
-       IDProperty **array;
+       IDProperty *array;
        int i;
 
        /*since we didn't save the extra buffer, set totallen to len.*/
@@ -1374,11 +1374,10 @@ static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 
        if (switch_endian) {
-               test_pointer_array(fd, prop->data.pointer);
-               array= (IDProperty**) prop->data.pointer;
+               array= (IDProperty*) prop->data.pointer;
 
                for(i=0; i<prop->len; i++)
-                       IDP_DirectLinkProperty(array[i], switch_endian, fd);
+                       IDP_DirectLinkProperty(&array[i], switch_endian, fd);
        }
 }
 
index cd388cdf9cc5256cfdb4a18a6a12ae86efcdb0c1..9d059af9887f0aacae539e277cc7f0d1fc1ce1ff 100644 (file)
@@ -407,13 +407,13 @@ static void IDP_WriteIDPArray(IDProperty *prop, void *wd)
 {
        /*REMEMBER to set totalen to len in the linking code!!*/
        if (prop->data.pointer) {
-               IDProperty **array = prop->data.pointer;
+               IDProperty *array = prop->data.pointer;
                int a;
 
-               writedata(wd, DATA, MEM_allocN_len(prop->data.pointer), prop->data.pointer);
+               writestruct(wd, DATA, "IDProperty", prop->len, array);
 
                for(a=0; a<prop->len; a++)
-                       IDP_WriteProperty(array[a], wd);
+                       IDP_WriteProperty_OnlyData(&array[a], wd);
        }
 }
 
index b591c6e6856de4308b73c7b7c049302252034e15..fab4de50568a9aa54e7c25d7abc4ac99c7054a65 100644 (file)
@@ -1582,7 +1582,6 @@ static void SCREEN_OT_screen_set(wmOperatorType *ot)
        ot->poll= ED_operator_screenactive;
        
        /* rna */
-       RNA_def_pointer_runtime(ot->srna, "screen", &RNA_Screen, "Screen", "");
        RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
 }
 
index 95c46515204e41d73e67bced1cc425431dbcd3bf..d5680ac77ba5a42302a83fb54953bef7221cfa97 100644 (file)
@@ -649,7 +649,7 @@ RawPropertyType RNA_property_raw_type(PropertyRNA *prop);
 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop);
 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop);
 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr);
-void RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key);
+int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key);
 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop);
 
 /* Path
index 72ecf0e7a937cc3209b9125ed19dbfcf0f32260d..042f7578cf4cf303c652b04fa95ce581fbd79fe3 100644 (file)
@@ -263,7 +263,7 @@ typedef int (*StructValidateFunc)(struct PointerRNA *ptr, void *data, int *have_
 typedef int (*StructCallbackFunc)(struct PointerRNA *ptr, struct FunctionRNA *func, ParameterList *list);
 typedef void (*StructFreeFunc)(void *data);
 typedef struct StructRNA *(*StructRegisterFunc)(const struct bContext *C, struct ReportList *reports, void *data,
-       StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free);
+       const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free);
 typedef void (*StructUnregisterFunc)(const struct bContext *C, struct StructRNA *type);
 
 typedef struct StructRNA StructRNA;
index cf3d59f78a0552ed5280591511fbde797404cd98..f6e0a2468c4c43863e488c94a7554e7477aa6958 100644 (file)
@@ -152,6 +152,30 @@ IDProperty *rna_IDPropertyGroup_idproperties(PointerRNA *ptr, int create)
        return ptr->data;
 }
 
+void rna_IDPropertyGroup_unregister(const bContext *C, StructRNA *type)
+{
+       RNA_struct_free(&BLENDER_RNA, type);
+}
+
+StructRNA *rna_IDPropertyGroup_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+       PointerRNA dummyptr;
+
+       /* create dummy pointer */
+       RNA_pointer_create(NULL, &RNA_IDPropertyGroup, NULL, &dummyptr);
+
+       /* validate the python class */
+       if(validate(&dummyptr, data, NULL) != 0)
+               return NULL;
+
+       return RNA_def_struct(&BLENDER_RNA, identifier, "IDPropertyGroup");  // XXX
+}
+
+StructRNA* rna_IDPropertyGroup_refine(PointerRNA *ptr)
+{
+       return ptr->type;
+}
+
 #else
 
 static void rna_def_ID_properties(BlenderRNA *brna)
@@ -210,6 +234,8 @@ static void rna_def_ID_properties(BlenderRNA *brna)
        srna= RNA_def_struct(brna, "IDPropertyGroup", NULL);
        RNA_def_struct_ui_text(srna, "ID Property Group", "Group of ID properties.");
        RNA_def_struct_idproperties_func(srna, "rna_IDPropertyGroup_idproperties");
+       RNA_def_struct_register_funcs(srna, "rna_IDPropertyGroup_register", "rna_IDPropertyGroup_unregister");
+       RNA_def_struct_refine_func(srna, "rna_IDPropertyGroup_refine");
 }
 
 static void rna_def_ID(BlenderRNA *brna)
index 2de59586611c986dfc82a57cd0412200e211976f..54cde57a54ff14542507c06808478ab6f1af71e6 100644 (file)
@@ -1259,8 +1259,15 @@ PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
        else if(pprop->get) {
                return pprop->get(ptr);
        }
+       else if(prop->flag & PROP_IDPROPERTY) {
+               /* XXX temporary hack to add it automatically, reading should
+                  never do any write ops, to ensure thread safety etc .. */
+               RNA_property_pointer_add(ptr, prop);
+               return RNA_property_pointer_get(ptr, prop);
+       }
        else {
                PointerRNA result;
+
                memset(&result, 0, sizeof(result));
                return result;
        }
@@ -1398,7 +1405,7 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
 {
        IDProperty *idprop;
-       //CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
+       CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
 
        if((idprop=rna_idproperty_check(&prop, ptr))) {
                IDPropertyTemplate val = {0};
@@ -1424,7 +1431,6 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
                        MEM_freeN(item);
                }
        }
-#if 0
        else if(cprop->add){
                if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
                        ParameterList params;
@@ -1433,9 +1439,8 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
                        RNA_parameter_list_free(&params);
                }
        }
-#endif
-       else
-               printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier);
+       /*else
+               printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier);*/
 
        if(r_ptr) {
                if(idprop) {
@@ -1450,10 +1455,10 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
        }
 }
 
-void RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
+int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
 {
        IDProperty *idprop;
-       //CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
+       CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
 
        if((idprop=rna_idproperty_check(&prop, ptr))) {
                IDProperty tmp, *array;
@@ -1472,20 +1477,25 @@ void RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
 
                        IDP_ResizeIDPArray(idprop, len-1);
                }
+
+               return 1;
        }
-       else if(prop->flag & PROP_IDPROPERTY);
-#if 0
+       else if(prop->flag & PROP_IDPROPERTY)
+               return 1;
        else if(cprop->remove){
                if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
                        ParameterList params;
-                       RNA_parameter_list_create(&ptr, cprop->remove);
+                       RNA_parameter_list_create(&params, ptr, cprop->remove);
                        RNA_function_call(NULL, NULL, ptr, cprop->remove, &params);
                        RNA_parameter_list_free(&params);
                }
+
+               return 0;
        }
-#endif
-       else
-               printf("RNA_property_collection_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
+       /*else
+               printf("RNA_property_collection_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);*/
+       
+       return 0;
 }
 
 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
index 0861d7d51a0aecd27ec979f17ea118f7db0dbd62..9bdbc8baed70008a1a58b845d0b5024a2b8cb32a 100644 (file)
@@ -2419,6 +2419,7 @@ void RNA_def_property_duplicate_pointers(PropertyRNA *prop)
        EnumPropertyItem *earray;
        float *farray;
        int *iarray;
+       int a;
 
        if(prop->identifier) prop->identifier= BLI_strdup(prop->identifier);
        if(prop->name) prop->name= BLI_strdup(prop->name);
@@ -2452,7 +2453,14 @@ void RNA_def_property_duplicate_pointers(PropertyRNA *prop)
                                earray= MEM_callocN(sizeof(EnumPropertyItem)*(eprop->totitem+1), "RNA_def_property_store"),
                                memcpy(earray, eprop->item, sizeof(EnumPropertyItem)*(eprop->totitem+1));
                                eprop->item= earray;
+
+                               for(a=0; a<eprop->totitem; a++) {
+                                       if(eprop->item[a].identifier) eprop->item[a].identifier= BLI_strdup(eprop->item[a].identifier);
+                                       if(eprop->item[a].name) eprop->item[a].name= BLI_strdup(eprop->item[a].name);
+                                       if(eprop->item[a].description) eprop->item[a].description= BLI_strdup(eprop->item[a].description);
+                               }
                        }
+                       break;
                }
                case PROP_FLOAT: {
                        FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
@@ -2479,6 +2487,8 @@ void RNA_def_property_duplicate_pointers(PropertyRNA *prop)
 void RNA_def_property_free_pointers(PropertyRNA *prop)
 {
        if(prop->flag & PROP_FREE_POINTERS) {
+               int a;
+
                if(prop->identifier) MEM_freeN((void*)prop->identifier);
                if(prop->name) MEM_freeN((void*)prop->name);
                if(prop->description) MEM_freeN((void*)prop->description);
@@ -2502,6 +2512,13 @@ void RNA_def_property_free_pointers(PropertyRNA *prop)
                        case PROP_ENUM: {
                                EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
                                if(eprop->item) MEM_freeN((void*)eprop->item);
+
+                               for(a=0; a<eprop->totitem; a++) {
+                                       if(eprop->item[a].identifier) MEM_freeN((void*)eprop->item[a].identifier);
+                                       if(eprop->item[a].name) MEM_freeN((void*)eprop->item[a].name);
+                                       if(eprop->item[a].description) MEM_freeN((void*)eprop->item[a].description);
+                               }
+                               break;
                        }
                        case PROP_STRING: {
                                StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
index a8c7032733fbeb946f41f006c0b0781a73fd8dc5..579441691ff3f03deb7e78ead71d2a3f8f5911e4 100644 (file)
@@ -181,6 +181,9 @@ struct StructRNA *rna_ID_refine(struct PointerRNA *ptr);
 struct IDProperty *rna_ID_idproperties(struct PointerRNA *ptr, int create);
 void rna_ID_fake_user_set(struct PointerRNA *ptr, int value);
 struct IDProperty *rna_IDPropertyGroup_idproperties(struct PointerRNA *ptr, int create);
+void rna_IDPropertyGroup_unregister(const struct bContext *C, struct StructRNA *type);
+struct StructRNA *rna_IDPropertyGroup_register(const struct bContext *C, struct ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free);
+struct StructRNA* rna_IDPropertyGroup_refine(struct PointerRNA *ptr);
 
 void rna_object_vgroup_name_index_get(struct PointerRNA *ptr, char *value, int index);
 int rna_object_vgroup_name_index_length(struct PointerRNA *ptr, int index);
index 26fc3c2941e2a7aef5af1522c2f5d534522c3098..c09b83dd6826893d37b2902e9a2c9ed7ab549212 100644 (file)
@@ -220,34 +220,34 @@ void RNA_def_main(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
-       const char *lists[][5]= {
-               {"cameras", "Camera", "rna_Main_camera_begin", "Cameras", "Camera datablocks."},
-               {"scenes", "Scene", "rna_Main_scene_begin", "Scenes", "Scene datablocks."},
-               {"objects", "Object", "rna_Main_object_begin", "Objects", "Object datablocks."},
-               {"materials", "Material", "rna_Main_mat_begin", "Materials", "Material datablocks."},
-               {"nodetrees", "NodeTree", "rna_Main_nodetree_begin", "Node Trees", "Nodetree datablocks."},
-               {"meshes", "Mesh", "rna_Main_mesh_begin", "Meshes", "Mesh datablocks."}, 
-               {"lamps", "Lamp", "rna_Main_lamp_begin", "Lamps", "Lamp datablocks."},
-               {"libraries", "Library", "rna_Main_library_begin", "Libraries", "Library datablocks."},
-               {"screens", "Screen", "rna_Main_screen_begin", "Screens", "Screen datablocks."},
-               {"windowmanagers", "WindowManager", "rna_Main_wm_begin", "Window Managers", "Window manager datablocks."},
-               {"images", "Image", "rna_Main_image_begin", "Images", "Image datablocks."},
-               {"lattices", "Lattice", "rna_Main_latt_begin", "Lattices", "Lattice datablocks."},
-               {"curves", "Curve", "rna_Main_curve_begin", "Curves", "Curve datablocks."}, 
-               {"metaballs", "MetaBall", "rna_Main_mball_begin", "Metaballs", "Metaball datablocks."},
-               {"vfonts", "VectorFont", "rna_Main_vfont_begin", "Vector Fonts", "Vector font datablocks."},
-               {"textures", "Texture", "rna_Main_tex_begin", "Textures", "Texture datablocks."},
-               {"brushes", "Brush", "rna_Main_brush_begin", "Brushes", "Brush datablocks."},
-               {"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks."},
-               {"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks."},
-               {"keys", "ID", "rna_Main_key_begin", "Keys", "Key datablocks."},
-               {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks."},
-               {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks."},
-               {"sounds", "ID", "rna_Main_sound_begin", "Sounds", "Sound datablocks."},
-               {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks."},
-               {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks."},
-               {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks."},
-               {NULL, NULL, NULL, NULL, NULL}};
+       const char *lists[][7]= {
+               {"cameras", "Camera", "rna_Main_camera_begin", "Cameras", "Camera datablocks.", NULL, NULL},
+               {"scenes", "Scene", "rna_Main_scene_begin", "Scenes", "Scene datablocks.", NULL, NULL},
+               {"objects", "Object", "rna_Main_object_begin", "Objects", "Object datablocks.", NULL, NULL},
+               {"materials", "Material", "rna_Main_mat_begin", "Materials", "Material datablocks.", NULL, NULL},
+               {"nodetrees", "NodeTree", "rna_Main_nodetree_begin", "Node Trees", "Nodetree datablocks.", NULL, NULL},
+               {"meshes", "Mesh", "rna_Main_mesh_begin", "Meshes", "Mesh datablocks.", "add_mesh", "remove_mesh"}, 
+               {"lamps", "Lamp", "rna_Main_lamp_begin", "Lamps", "Lamp datablocks.", NULL, NULL},
+               {"libraries", "Library", "rna_Main_library_begin", "Libraries", "Library datablocks.", NULL, NULL},
+               {"screens", "Screen", "rna_Main_screen_begin", "Screens", "Screen datablocks.", NULL, NULL},
+               {"windowmanagers", "WindowManager", "rna_Main_wm_begin", "Window Managers", "Window manager datablocks.", NULL, NULL},
+               {"images", "Image", "rna_Main_image_begin", "Images", "Image datablocks.", NULL, NULL},
+               {"lattices", "Lattice", "rna_Main_latt_begin", "Lattices", "Lattice datablocks.", NULL, NULL},
+               {"curves", "Curve", "rna_Main_curve_begin", "Curves", "Curve datablocks.", NULL, NULL} ,
+               {"metaballs", "MetaBall", "rna_Main_mball_begin", "Metaballs", "Metaball datablocks.", NULL, NULL},
+               {"vfonts", "VectorFont", "rna_Main_vfont_begin", "Vector Fonts", "Vector font datablocks.", NULL, NULL},
+               {"textures", "Texture", "rna_Main_tex_begin", "Textures", "Texture datablocks.", NULL, NULL},
+               {"brushes", "Brush", "rna_Main_brush_begin", "Brushes", "Brush datablocks.", NULL, NULL},
+               {"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks.", NULL, NULL},
+               {"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks.", NULL, NULL},
+               {"keys", "ID", "rna_Main_key_begin", "Keys", "Key datablocks.", NULL, NULL},
+               {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks.", NULL, NULL},
+               {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks.", NULL, NULL},
+               {"sounds", "ID", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", NULL, NULL},
+               {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks.", NULL, NULL},
+               {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks.", NULL, NULL},
+               {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks.", NULL, NULL},
+               {NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
        int i;
        
        srna= RNA_def_struct(brna, "Main", NULL);
@@ -264,7 +264,7 @@ void RNA_def_main(BlenderRNA *brna)
        {
                prop= RNA_def_property(srna, lists[i][0], PROP_COLLECTION, PROP_NONE);
                RNA_def_property_struct_type(prop, lists[i][1]);
-               RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0, 0);
+               RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, lists[i][5], lists[i][6]);
                RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]);
        }
 
index a219bd5aefa83a4ab30fff95dca70c2b4e25393d..9137e596da1d812d2c5f739578760401633a576f 100644 (file)
@@ -111,7 +111,7 @@ static void rna_RenderEngine_unregister(const bContext *C, StructRNA *type)
        RNA_struct_free(&BLENDER_RNA, type);
 }
 
-static StructRNA *rna_RenderEngine_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_RenderEngine_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
 {
        RenderEngineType *et, dummyet = {0};
        RenderEngine dummyengine= {0};
index 660dbb490270301d7cfede00047b9b7c3e75fb2c..f16180451a7a16aec9361197cf440cf88b9df27a 100644 (file)
@@ -148,7 +148,7 @@ static void rna_Panel_unregister(const bContext *C, StructRNA *type)
                WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
 }
 
-static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
 {
        ARegionType *art;
        PanelType *pt, dummypt = {0};
@@ -245,7 +245,7 @@ static void rna_Header_unregister(const bContext *C, StructRNA *type)
                WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
 }
 
-static StructRNA *rna_Header_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_Header_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
 {
        ARegionType *art;
        HeaderType *ht, dummyht = {0};
@@ -361,7 +361,7 @@ static void rna_Menu_unregister(const bContext *C, StructRNA *type)
                WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
 }
 
-static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
 {
        ARegionType *art;
        MenuType *mt, dummymt = {0};
index 114727eeef5bc8af999f927ece88d2eefef3718d..bece114d8bd8daa4f52a7b4dd4b1494b8cf085f4 100644 (file)
@@ -1451,6 +1451,38 @@ static PyObject *pyrna_prop_get(BPy_PropertyRNA *self, PyObject *args)
 }
 
 
+static PyObject *pyrna_prop_add(BPy_PropertyRNA *self, PyObject *args)
+{
+       PointerRNA newptr;
+
+       RNA_property_collection_add(&self->ptr, self->prop, &newptr);
+       if(!newptr.data) {
+               PyErr_SetString( PyExc_TypeError, "add() not supported for this collection");
+               return NULL;
+       }
+       else {
+               return pyrna_struct_CreatePyObject(&newptr);
+       }
+}
+
+static PyObject *pyrna_prop_remove(BPy_PropertyRNA *self, PyObject *args)
+{
+       PyObject *ret;
+       int key= 0;
+
+       if (!PyArg_ParseTuple(args, "i:remove", &key))
+               return NULL;
+
+       if(!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
+               PyErr_SetString( PyExc_TypeError, "remove() not supported for this collection");
+               return NULL;
+       }
+
+       ret = Py_None;
+       Py_INCREF(ret);
+
+       return ret;
+}
 
 static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
                                                                        /* values to assign */
@@ -1736,6 +1768,9 @@ static struct PyMethodDef pyrna_prop_methods[] = {
        
        {"get", (PyCFunction)pyrna_prop_get, METH_VARARGS, NULL},
 
+       {"add", (PyCFunction)pyrna_prop_add, METH_VARARGS, NULL},
+       {"remove", (PyCFunction)pyrna_prop_remove, METH_VARARGS, NULL},
+
        /* array accessor function */
        {"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL},
        {"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL},
@@ -2307,10 +2342,13 @@ PyObject *BPy_GetStructRNA(PyObject *self)
 */
 
 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, ""},
+       {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
+       {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
        {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
+       {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""},
+       {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""},
+       {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""},
 
 //     {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""},
        {NULL, NULL, 0, NULL}
@@ -2583,10 +2621,13 @@ PyObject *BPY_rna_types(void)
 }
 
 static struct PyMethodDef props_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, ""},
+       {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
+       {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
        {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
+       {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""},
+       {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""},
+       {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""},
        {NULL, NULL, 0, NULL}
 };
 
@@ -2679,15 +2720,16 @@ static PyObject *bpy_prop_deferred_return(void *func, PyObject *kw)
 
 /* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna allong
  * This isnt incorrect since its a python object - but be careful */
-PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
+
+PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
 {
-       static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
+       static char *kwlist[] = {"attr", "name", "description", "default", NULL};
        char *id, *name="", *description="";
-       float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f;
+       int def=0;
        PropertyRNA *prop;
        StructRNA *srna;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
+       if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def))
                return NULL;
        
        if (PyTuple_Size(args) > 0) {
@@ -2700,12 +2742,12 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
                return NULL; /* self's type was compatible but error getting the srna */
        }
        else if(srna) {
-               prop= RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
+               prop= RNA_def_boolean(srna, id, def, name, description);
                RNA_def_property_duplicate_pointers(prop);
                Py_RETURN_NONE;
        }
        else { /* operators defer running this function */
-               return bpy_prop_deferred_return((void *)BPy_FloatProperty, kw);
+               return bpy_prop_deferred_return((void *)BPy_BoolProperty, kw);
        }
 }
 
@@ -2739,15 +2781,15 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
        }
 }
 
-PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
+PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
 {
-       static char *kwlist[] = {"attr", "name", "description", "default", NULL};
+       static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
        char *id, *name="", *description="";
-       int def=0;
+       float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f;
        PropertyRNA *prop;
        StructRNA *srna;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def))
+       if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
                return NULL;
        
        if (PyTuple_Size(args) > 0) {
@@ -2760,12 +2802,12 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
                return NULL; /* self's type was compatible but error getting the srna */
        }
        else if(srna) {
-               prop= RNA_def_boolean(srna, id, def, name, description);
+               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 { /* operators defer running this function */
-               return bpy_prop_deferred_return((void *)BPy_BoolProperty, kw);
+               return bpy_prop_deferred_return((void *)BPy_FloatProperty, kw);
        }
 }
 
@@ -2799,6 +2841,178 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
        }
 }
 
+static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, int *defvalue)
+{
+       EnumPropertyItem *items= NULL;
+       PyObject *item;
+       int seq_len, i, totitem= 0;
+       
+       if(!PySequence_Check(value)) {
+               PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items");
+               return NULL;
+       }
+
+       seq_len = PySequence_Length(value);
+       for(i=0; i<seq_len; i++) {
+               EnumPropertyItem tmp= {0, "", 0, "", ""};
+
+               item= PySequence_GetItem(value, i);
+               if(item==NULL || PyTuple_Check(item)==0) {
+                       PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items");
+                       if(items) MEM_freeN(items);
+                       Py_XDECREF(item);
+                       return NULL;
+               }
+
+               if(!PyArg_ParseTuple(item, "sss", &tmp.identifier, &tmp.name, &tmp.description)) {
+                       PyErr_SetString(PyExc_TypeError, "expected an identifier, name and description in the tuple");
+                       Py_DECREF(item);
+                       return NULL;
+               }
+
+               tmp.value= i;
+               RNA_enum_item_add(&items, &totitem, &tmp);
+
+               if(def[0] && strcmp(def, tmp.identifier) == 0)
+                       *defvalue= tmp.value;
+
+               Py_DECREF(item);
+       }
+
+       if(!def[0])
+               *defvalue= 0;
+
+       RNA_enum_item_end(&items, &totitem);
+
+       return items;
+}
+
+PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
+{
+       static char *kwlist[] = {"attr", "items", "name", "description", "default", NULL};
+       char *id, *name="", *description="", *def="";
+       int defvalue=0;
+       PyObject *items= Py_None;
+       EnumPropertyItem *eitems;
+       PropertyRNA *prop;
+       StructRNA *srna;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sss:EnumProperty", kwlist, &id, &items, &name, &description, &def))
+               return NULL;
+       
+       if (PyTuple_Size(args) > 0) {
+               PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
+               return NULL;
+       }
+       
+       srna= srna_from_self(self);
+       if(srna==NULL && PyErr_Occurred()) {
+               return NULL; /* self's type was compatible but error getting the srna */
+       }
+       else if(srna) {
+               eitems= enum_items_from_py(items, def, &defvalue);
+               if(!eitems)
+                       return NULL;
+                       
+               prop= RNA_def_enum(srna, id, eitems, defvalue, name, description);
+               RNA_def_property_duplicate_pointers(prop);
+               MEM_freeN(eitems);
+
+               Py_RETURN_NONE;
+       }
+       else { /* operators defer running this function */
+               return bpy_prop_deferred_return((void *)BPy_EnumProperty, kw);
+       }
+}
+
+static StructRNA *pointer_type_from_py(PyObject *value)
+{
+       StructRNA *srna;
+
+       srna= srna_from_self(value);
+       if(!srna) {
+               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup (1)");
+               return NULL;
+       }
+
+       if(!RNA_struct_is_a(srna, &RNA_IDPropertyGroup)) {
+               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup (3)");
+               return NULL;
+       }
+
+       return srna;
+}
+
+PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
+{
+       static char *kwlist[] = {"attr", "type", "name", "description", NULL};
+       char *id, *name="", *description="";
+       PropertyRNA *prop;
+       StructRNA *srna, *ptype;
+       PyObject *type= Py_None;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:PointerProperty", kwlist, &id, &type, &name, &description))
+               return NULL;
+       
+       if (PyTuple_Size(args) > 0) {
+               PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
+               return NULL;
+       }
+
+       srna= srna_from_self(self);
+       if(srna==NULL && PyErr_Occurred()) {
+               return NULL; /* self's type was compatible but error getting the srna */
+       }
+       else if(srna) {
+               ptype= pointer_type_from_py(type);
+               if(!ptype)
+                       return NULL;
+
+               prop= RNA_def_pointer_runtime(srna, id, ptype, name, description);
+               RNA_def_property_duplicate_pointers(prop);
+               Py_RETURN_NONE;
+       }
+       else { /* operators defer running this function */
+               return bpy_prop_deferred_return((void *)BPy_PointerProperty, kw);
+       }
+       return NULL;
+}
+
+PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
+{
+       static char *kwlist[] = {"attr", "type", "name", "description", NULL};
+       char *id, *name="", *description="";
+       PropertyRNA *prop;
+       StructRNA *srna, *ptype;
+       PyObject *type= Py_None;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:CollectionProperty", kwlist, &id, &type, &name, &description))
+               return NULL;
+       
+       if (PyTuple_Size(args) > 0) {
+               PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
+               return NULL;
+       }
+
+       srna= srna_from_self(self);
+       if(srna==NULL && PyErr_Occurred()) {
+               return NULL; /* self's type was compatible but error getting the srna */
+       }
+       else if(srna) {
+               ptype= pointer_type_from_py(type);
+               if(!ptype)
+                       return NULL;
+
+               prop= RNA_def_collection_runtime(srna, id, ptype, name, description);
+               RNA_def_property_duplicate_pointers(prop);
+               Py_RETURN_NONE;
+       }
+       else { /* operators defer running this function */
+               return bpy_prop_deferred_return((void *)BPy_CollectionProperty, kw);
+       }
+       return NULL;
+}
+
 /*-------------------- Type Registration ------------------------*/
 
 static int rna_function_arg_count(FunctionRNA *func)
@@ -3113,6 +3327,8 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class)
        StructRegisterFunc reg;
        StructRNA *srna;
        StructRNA *srna_new;
+       PyObject *item;
+       const char *identifier= "";
 
        srna= pyrna_struct_as_srna(py_class);
        if(srna==NULL)
@@ -3129,9 +3345,17 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class)
        /* get the context, so register callback can do necessary refreshes */
        C= BPy_GetContext();
 
-       /* call the register callback */
+       /* call the register callback with reports & identifier */
        BKE_reports_init(&reports, RPT_STORE);
-       srna_new= reg(C, &reports, py_class, bpy_class_validate, bpy_class_call, bpy_class_free);
+
+       item= PyObject_GetAttrString(py_class, "__name__");
+
+       if(item) {
+               identifier= _PyUnicode_AsString(item);
+               Py_DECREF(item); /* no need to keep a ref, the class owns it */
+       }
+
+       srna_new= reg(C, &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free);
 
        if(!srna_new) {
                BPy_reports_to_error(&reports);
index 717ea75a7a898e2826dd4c0ac38b5b33c5880235..1b8d69bc5110d73f7c5b96c24249d78c6fa962ec 100644 (file)
@@ -75,10 +75,13 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
 PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop);
 
 /* functions for setting up new props - experemental */
-PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw);
 PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw);
+PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw);
+PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw);
 PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw);
+PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw);
+PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw);
+PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw);
 
 /* function for registering types */
 PyObject *pyrna_basetype_register(PyObject *self, PyObject *args);