diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-07 04:49:39 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-07 04:49:39 +0400 |
commit | 767db1b71674efb599f03b5892c32d207647acd3 (patch) | |
tree | fc64129bea43fe563bc0ad1448e17405e1b04bb0 /source/blender | |
parent | 88ab62c03189a04f6a74b040ad269e5a901c4af1 (diff) |
RNA: Commit of the API patch by vekoon. This adds Functions to RNA,
which can be defined to call C functions with defined parameters.
* Parameters are RNA properties, with the same types.
* Parameters are stored in a ParameterList, which is like a small
stack with the values. This is then used to call the C function.
* Includes Python integration.
* Only one test function is part of this commit, ID.rename.
* Integration with the editors/ module is not included in this
commit, there's some issues to be worked out for that still.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 43 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_define.h | 68 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_types.h | 31 | ||||
-rw-r--r-- | source/blender/makesrna/SConscript | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/CMakeLists.txt | 53 | ||||
-rw-r--r-- | source/blender/makesrna/intern/SConscript | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/makesrna.c | 463 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ID.c | 12 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 352 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_define.c | 529 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal.h | 29 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal_types.h | 42 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_rna.c | 135 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 556 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.h | 16 |
16 files changed, 2027 insertions, 309 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 5bba2d3fda0..d15ef90eee8 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -609,7 +609,7 @@ void uiItemBooleanO(uiLayout *layout, int slot, const char *name, int icon, char void uiItemIntO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, int value); void uiItemFloatO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, float value); void uiItemStringO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, char *value); -void uiItemFullO(uiLayout *layout, int slot, const char *name, int icon, char *idname, IDProperty *properties, int context); +void uiItemFullO(uiLayout *layout, int slot, const char *name, int icon, char *idname, struct IDProperty *properties, int context); void uiItemR(uiLayout *layout, int slot, const char *name, int icon, struct PointerRNA *ptr, char *propname); void uiItemFullR(uiLayout *layout, int slot, const char *name, int icon, struct PointerRNA *ptr, char *propname, int index); diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 1bc898016e6..b37557fbe2b 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -25,6 +25,8 @@ #ifndef RNA_ACCESS #define RNA_ACCESS +#include <stdarg.h> + #include "DNA_listBase.h" #include "RNA_types.h" @@ -47,6 +49,7 @@ extern StructRNA RNA_ActuatorSensor; extern StructRNA RNA_AlwaysSensor; extern StructRNA RNA_AndController; extern StructRNA RNA_AnimData; +extern StructRNA RNA_AnyType; extern StructRNA RNA_Area; extern StructRNA RNA_AreaLamp; extern StructRNA RNA_Armature; @@ -100,6 +103,7 @@ extern StructRNA RNA_FloatProperty; extern StructRNA RNA_FluidFluidSettings; extern StructRNA RNA_FluidSettings; extern StructRNA RNA_FluidSimulationModifier; +extern StructRNA RNA_Function; extern StructRNA RNA_GameBooleanProperty; extern StructRNA RNA_GameFloatProperty; extern StructRNA RNA_GameIntProperty; @@ -312,9 +316,15 @@ PropertyRNA *RNA_struct_iterator_property(PointerRNA *ptr); int RNA_struct_is_ID(PointerRNA *ptr); int RNA_struct_is_a(PointerRNA *ptr, StructRNA *srna); +void *RNA_struct_py_type_get(StructRNA *srna); +void RNA_struct_py_type_set(StructRNA *srna, void *py_type); + PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier); const struct ListBase *RNA_struct_defined_properties(StructRNA *srna); +FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier); +const struct ListBase *RNA_struct_defined_functions(StructRNA *srna); + /* Properties * * Access to struct properties. All this works with RNA pointers rather than @@ -490,6 +500,39 @@ int RNA_property_is_set(PointerRNA *ptr, const char *name); /* python compatible string representation of this property, (must be freed!) */ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop); +/* Function */ + +const char *RNA_function_identifier(PointerRNA *ptr, FunctionRNA *func); +PropertyRNA *RNA_function_return(PointerRNA *ptr, FunctionRNA *func); +const char *RNA_function_ui_description(PointerRNA *ptr, FunctionRNA *func); + +PropertyRNA *RNA_function_get_parameter(PointerRNA *ptr, FunctionRNA *func, int index); +PropertyRNA *RNA_function_find_parameter(PointerRNA *ptr, FunctionRNA *func, const char *identifier); +const struct ListBase *RNA_function_defined_parameters(PointerRNA *ptr, FunctionRNA *func); + +/* Utility */ + +ParameterList *RNA_parameter_list_create(PointerRNA *ptr, FunctionRNA *func); +void RNA_parameter_list_free(ParameterList *parms); + +void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter); +void RNA_parameter_list_next(ParameterIterator *iter); +void RNA_parameter_list_end(ParameterIterator *iter); + +void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **value); +void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value); +void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, void *value); +void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, void *value); + +int RNA_function_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *parms); +int RNA_function_call_lookup(PointerRNA *ptr, const char *identifier, ParameterList *parms); + +/* not implemented yet +int RNA_function_call_direct(PointerRNA *ptr, FunctionRNA *func, const char *format, ...); +int RNA_function_call_direct_lookup(PointerRNA *ptr, const char *identifier, const char *format, ...); +int RNA_function_call_direct_va(PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args); +int RNA_function_call_direct_va_lookup(PointerRNA *ptr, const char *identifier, const char *format, va_list args);*/ + #ifdef __cplusplus } #endif diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 94a2c51c660..aede53aff94 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -60,54 +60,46 @@ void RNA_struct_free(BlenderRNA *brna, StructRNA *srna); /* Compact Property Definitions */ -PropertyRNA *RNA_def_boolean(StructRNA *srna, const char *identifier, int default_value, - const char *ui_name, const char *ui_description); -PropertyRNA *RNA_def_boolean_array(StructRNA *srna, const char *identifier, int len, int *default_value, - const char *ui_name, const char *ui_description); -PropertyRNA *RNA_def_boolean_vector(StructRNA *srna, const char *identifier, int len, int *default_value, - const char *ui_name, const char *ui_description); +typedef void StructOrFunctionRNA; -PropertyRNA *RNA_def_int(StructRNA *srna, const char *identifier, int default_value, int hardmin, int hardmax, - const char *ui_name, const char *ui_description, int softmin, int softmax); -PropertyRNA *RNA_def_int_vector(StructRNA *srna, const char *identifier, int len, const int *default_value, int hardmin, int hardmax, - const char *ui_name, const char *ui_description, int softmin, int softmax); -PropertyRNA *RNA_def_int_array(StructRNA *srna, const char *identifier, int len, const int *default_value, int hardmin, int hardmax, - const char *ui_name, const char *ui_description, int softmin, int softmax); +PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont, const char *identifier, int default_value, const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description); -PropertyRNA *RNA_def_string(StructRNA *srna, const char *identifier, const char *default_value, int maxlen, - const char *ui_name, const char *ui_description); -PropertyRNA *RNA_def_string_file_path(StructRNA *srna, const char *identifier, const char *default_value, int maxlen, - const char *ui_name, const char *ui_description); -PropertyRNA *RNA_def_string_dir_path(StructRNA *srna, const char *identifier, const char *default_value, int maxlen, - const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax); +PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const int *default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax); +PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont, const char *identifier, int len, const int *default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax); -PropertyRNA *RNA_def_enum(StructRNA *srna, const char *identifier, EnumPropertyItem *items, int default_value, - const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description); -PropertyRNA *RNA_def_float(StructRNA *srna, const char *identifier, float default_value, float hardmin, float hardmax, - const char *ui_name, const char *ui_description, float softmin, float softmax); -PropertyRNA *RNA_def_float_vector(StructRNA *srna, const char *identifier, int len, const float *default_value, - float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); -PropertyRNA *RNA_def_float_color(StructRNA *srna, const char *identifier, int len, const float *default_value, - float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); -PropertyRNA *RNA_def_float_matrix(StructRNA *srna, const char *identifier, int len, const float *default_value, - float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); -PropertyRNA *RNA_def_float_rotation(StructRNA *srna, const char *identifier, int len, const float *default_value, +PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description); + +PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); +PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); +PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); +PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); +PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); -PropertyRNA *RNA_def_float_array(StructRNA *srna, const char *identifier, int len, const float *default_value, +PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); -PropertyRNA *RNA_def_float_percentage(StructRNA *srna, const char *identifier, float default_value, float hardmin, float hardmax, +PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); -PropertyRNA *RNA_def_pointer_runtime(StructRNA *srna, const char *identifier, StructRNA *type, +PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont, const char *identifier, const char *type, + const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description); -PropertyRNA *RNA_def_collection_runtime(StructRNA *srna, const char *identifier, StructRNA *type, +PropertyRNA *RNA_def_collection(StructOrFunctionRNA *cont, const char *identifier, const char *type, + const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_collection_runtime(StructOrFunctionRNA *cont, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description); /* Extended Property Definitions */ -PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, int subtype); +PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont, const char *identifier, int type, int subtype); void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit); void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit); @@ -152,6 +144,14 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set); void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring); +/* Function */ + +FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call); +FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc call); +void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret); +void RNA_def_function_flag(FunctionRNA *func, int flag); +void RNA_def_function_ui_description(FunctionRNA *func, const char *description); + #ifdef __cplusplus } #endif diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index c3dcf4040ea..4ea97041f83 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -29,6 +29,8 @@ extern "C" { #endif +struct ParameterList; +struct FunctionRNA; struct PropertyRNA; struct StructRNA; struct BlenderRNA; @@ -123,6 +125,35 @@ typedef struct EnumPropertyItem { typedef struct PropertyRNA PropertyRNA; +/* Parameter List */ + +typedef struct ParameterList ParameterList; + +typedef struct ParameterIterator { + ParameterList *parms; + PointerRNA funcptr; + void *data; + int size, offset; + + PropertyRNA *parm; + int valid; +} ParameterIterator; + +/* Function */ + +typedef enum FunctionFlag { + FUNC_TYPESTATIC = 1, /* for static functions, FUNC_ STATIC is taken by some windows header it seems */ + + /* internal flags */ + FUNC_BUILTIN = 128, + FUNC_EXPORT = 256, + FUNC_RUNTIME = 512 +} FunctionFlag; + +typedef void (*CallFunc)(PointerRNA *ptr, ParameterList *parms); + +typedef struct FunctionRNA FunctionRNA; + /* Struct */ typedef enum StructFlag { diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index ace5b80a63c..94ea9ad764a 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -7,6 +7,6 @@ o = SConscript('intern/SConscript') objs += o incs = '#/intern/guardedalloc ../blenkernel ../blenlib ../makesdna intern .' -incs += ' ../windowmanager' +incs += ' ../windowmanager ../editors' env.BlenderLib ( 'bf_rna', objs, Split(incs), [], libtype=['core'], priority = [195] ) diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 934e009eebc..ecdc2ca865c 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -24,55 +24,8 @@ # # ***** END GPL LICENSE BLOCK ***** -SET(DEFSRC - rna_action.c - rna_actuator.c - rna_animation.c - rna_armature.c - rna_brush.c - rna_camera.c - rna_cloth.c - rna_color.c - rna_constraint.c - rna_context.c - rna_controller.c - rna_curve.c - rna_fluidsim.c - rna_group.c - rna_ID.c - rna_image.c - rna_key.c - rna_lamp.c - rna_lattice.c - rna_main.c - rna_material.c - rna_mesh.c - rna_meta.c - rna_modifier.c - rna_nodetree.c - rna_object.c - rna_object_force.c - rna_packedfile.c - rna_particle.c - rna_pose.c - rna_property.c - rna_radio.c - rna_rna.c - rna_scene.c - rna_screen.c - rna_scriptlink.c - rna_sensor.c - rna_sequence.c - rna_sound.c - rna_space.c - rna_text.c - rna_texture.c - rna_timeline.c - rna_userdef.c - rna_vfont.c - rna_vpaint.c - rna_wm.c - rna_world.c) +FILE(GLOB DEFSRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c") +LIST(REMOVE_ITEM DEFSRC rna_access.c rna_define.c makesrna.c) STRING(REGEX REPLACE "rna_([a-zA-Z0-9_-]*).c" "${CMAKE_CURRENT_BINARY_DIR}/rna_\\1_gen.c" GENSRC "${DEFSRC}") @@ -83,7 +36,7 @@ SET(SRC ../../../../intern/guardedalloc/intern/mallocn.c ../../../../intern/guardedalloc/intern/mmap_win.c) -INCLUDE_DIRECTORIES(../../../../intern/guardedalloc .. ../../makesdna ../../blenkernel ../../blenlib ../../windowmanager .) +INCLUDE_DIRECTORIES(../../../../intern/guardedalloc .. ../../makesdna ../../blenkernel ../../blenlib ../../windowmanager ../../editors .) FILE(GLOB INC_FILES ../*.h ../../makesdna/*.h) # Build makesrna executable diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index 7bd52114792..46f748f7c7c 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -31,7 +31,8 @@ makesrna_tool.Append (CPPPATH = ['#/intern/guardedalloc', '../../blenkernel', '../../makesdna', '../../makesrna', - '../../windowmanager']) + '../../windowmanager', + '../../editors']) if env['OURPLATFORM'] == 'linuxcross': USE_WINE = True # when cross compiling on linux 64bit this is useful diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 0d124a121d5..a9f08f8f82a 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -156,7 +156,29 @@ static char *rna_alloc_function_name(const char *structname, const char *propnam return result; } -static const char *rna_type_type(PropertyRNA *prop) +static const char *rna_find_type(const char *type) +{ + StructDefRNA *ds; + + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) + if(ds->dnaname && strcmp(ds->dnaname, type)==0) + return ds->srna->identifier; + + return NULL; +} + +static const char *rna_find_dna_type(const char *type) +{ + StructDefRNA *ds; + + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) + if(strcmp(ds->srna->identifier, type)==0) + return ds->dnaname; + + return NULL; +} + +static const char *rna_type_type_name(PropertyRNA *prop) { switch(prop->type) { case PROP_BOOLEAN: @@ -168,7 +190,58 @@ static const char *rna_type_type(PropertyRNA *prop) case PROP_STRING: return "char*"; default: - return "PointerRNA"; + return NULL; + } +} + +static const char *rna_type_type(PropertyRNA *prop) +{ + const char *type; + + type= rna_type_type_name(prop); + + if(type) + return type; + + return "PointerRNA"; +} + +static const char *rna_type_struct(PropertyRNA *prop) +{ + const char *type; + + type= rna_type_type_name(prop); + + if(type) + return ""; + + return "struct "; +} + +static const char *rna_parameter_type_name(PropertyRNA *parm) +{ + const char *type; + + type= rna_type_type_name(parm); + + if(type) + return type; + + switch(parm->type) { + case PROP_POINTER: { + PointerPropertyRNA *pparm= (PointerPropertyRNA*)parm; + + if(strcmp((char*)pparm->type, "AnyType") == 0) + return "PointerRNA"; + else + return rna_find_dna_type((const char *)pparm->type); + } + case PROP_COLLECTION: { + CollectionPropertyRNA *cparm= (CollectionPropertyRNA*)parm; + return rna_find_dna_type((const char *)cparm->type); + } + default: + return "<error, no type specified>"; } } @@ -666,12 +739,10 @@ static char *rna_def_property_end_func(FILE *f, StructRNA *srna, PropertyRNA *pr return func; } -static void rna_def_property_funcs(FILE *f, PropertyDefRNA *dp) +static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) { PropertyRNA *prop; - StructRNA *srna; - srna= dp->srna; prop= dp->prop; switch(prop->type) { @@ -775,13 +846,11 @@ static void rna_def_property_funcs(FILE *f, PropertyDefRNA *dp) } } -static void rna_def_property_funcs_header(FILE *f, PropertyDefRNA *dp) +static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefRNA *dp) { PropertyRNA *prop; - StructRNA *srna; char *func; - srna= dp->srna; prop= dp->prop; if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN)) @@ -863,12 +932,10 @@ static void rna_def_property_funcs_header(FILE *f, PropertyDefRNA *dp) fprintf(f, "\n"); } -static void rna_def_property_funcs_header_cpp(FILE *f, PropertyDefRNA *dp) +static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, PropertyDefRNA *dp) { PropertyRNA *prop; - StructRNA *srna; - srna= dp->srna; prop= dp->prop; if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN)) @@ -946,12 +1013,10 @@ static void rna_def_property_funcs_header_cpp(FILE *f, PropertyDefRNA *dp) fprintf(f, "\n"); } -static void rna_def_property_funcs_impl_cpp(FILE *f, PropertyDefRNA *dp) +static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDefRNA *dp) { PropertyRNA *prop; - StructRNA *srna; - srna= dp->srna; prop= dp->prop; if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN)) @@ -1011,15 +1076,88 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, PropertyDefRNA *dp) fprintf(f, "\n"); } -static const char *rna_find_type(const char *type) +static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA *dfunc) { - StructDefRNA *ds; + StructRNA *srna; + FunctionRNA *func; + PropertyDefRNA *dparm; + char *funcname, *ptrstr; - for(ds=DefRNA.structs.first; ds; ds=ds->next) - if(ds->dnaname && strcmp(ds->dnaname, type)==0) - return ds->srna->identifier; - - return NULL; + srna= dsrna->srna; + func= dfunc->func; + + funcname= rna_alloc_function_name(srna->identifier, func->identifier, "call"); + + fprintf(f, "void %s(PointerRNA *_ptr, ParameterList *_parms)", funcname); + fprintf(f, "\n{\n"); + + if((func->flag & FUNC_TYPESTATIC)==0) { + if(dsrna->dnaname) fprintf(f, "\tstruct %s *_self;\n", dsrna->dnaname); + else fprintf(f, "\tstruct %s *_self;\n", srna->identifier); + } + + dparm= dfunc->cont.properties.first; + for(; dparm; dparm= dparm->next) { + ptrstr= (dparm->prop->type == PROP_POINTER || dparm->prop->arraylength > 0)? "*" : ""; + fprintf(f, "\t%s%s %s%s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier); + } + + fprintf(f, "\tchar *_data"); + if(func->ret) fprintf(f, ", *_retdata"); + fprintf(f, ";\n"); + fprintf(f, "\t\n"); + + if((func->flag & FUNC_TYPESTATIC)==0) { + if(dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname); + else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier); + } + + fprintf(f, "\t_data= (char *)_parms->data;\n"); + + dparm= dfunc->cont.properties.first; + for(; dparm; dparm= dparm->next) { + ptrstr= (dparm->prop->type == PROP_POINTER || dparm->prop->arraylength > 0)? "*" : ""; + + if(dparm->prop==func->ret) + fprintf(f, "\t_retdata= _data;\n"); + else + fprintf(f, "\t%s= *((%s%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr); + + if(dparm->next) + fprintf(f, "\t_data+= %d;\n", rna_parameter_size(dparm->prop)); + } + + if(dfunc->call) { + fprintf(f, "\t\n"); + fprintf(f, "\t"); + if(func->ret) fprintf(f, "%s= ", func->ret->identifier); + fprintf(f, "%s(", dfunc->call); + + if((func->flag & FUNC_TYPESTATIC)==0) + fprintf(f, "_self"); + + dparm= dfunc->cont.properties.first; + for(; dparm; dparm= dparm->next) { + if(dparm->prop==func->ret) + continue; + + if((func->flag & FUNC_TYPESTATIC)==0 || dparm!=dfunc->cont.properties.first) + fprintf(f, ", "); + fprintf(f, "%s", dparm->prop->identifier); + } + + fprintf(f, ");\n"); + + if(func->ret) { + dparm= rna_find_parameter_def(func->ret); + ptrstr= dparm->prop->type == PROP_POINTER || dparm->prop->arraylength > 0 ? "*" : ""; + fprintf(f, "\t*((%s%s%s*)_retdata)= %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->ret->identifier); + } + } + + fprintf(f, "}\n\n"); + + dfunc->call= funcname; } static void rna_auto_types() @@ -1027,12 +1165,12 @@ static void rna_auto_types() StructDefRNA *ds; PropertyDefRNA *dp; - for(ds=DefRNA.structs.first; ds; ds=ds->next) { + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) { /* DNA name for Screen is patched in 2.5, we do the reverse here .. */ if(ds->dnaname && strcmp(ds->dnaname, "Screen") == 0) ds->dnaname= "bScreen"; - for(dp=ds->properties.first; dp; dp=dp->next) { + for(dp=ds->cont.properties.first; dp; dp=dp->next) { if(dp->dnastructname && strcmp(dp->dnastructname, "Screen") == 0) dp->dnastructname= "bScreen"; @@ -1062,11 +1200,11 @@ static void rna_sort(BlenderRNA *brna) rna_sortlist(&brna->structs, cmp_struct); rna_sortlist(&DefRNA.structs, cmp_def_struct); - for(srna=brna->structs.first; srna; srna=srna->next) - rna_sortlist(&srna->properties, cmp_property); + for(srna=brna->structs.first; srna; srna=srna->cont.next) + rna_sortlist(&srna->cont.properties, cmp_property); - for(ds=DefRNA.structs.first; ds; ds=ds->next) - rna_sortlist(&ds->properties, cmp_def_property); + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) + rna_sortlist(&ds->cont.properties, cmp_def_property); } static const char *rna_property_structname(PropertyType type) @@ -1118,7 +1256,7 @@ static void rna_generate_prototypes(BlenderRNA *brna, FILE *f) { StructRNA *srna; - for(srna=brna->structs.first; srna; srna=srna->next) + for(srna=brna->structs.first; srna; srna=srna->cont.next) fprintf(f, "extern StructRNA RNA_%s;\n", srna->identifier); fprintf(f, "\n"); } @@ -1148,34 +1286,81 @@ static void rna_generate_property_prototypes(BlenderRNA *brna, StructRNA *srna, base= srna->base; while (base) { fprintf(f, "\n"); - for(prop=base->properties.first; prop; prop=prop->next) + for(prop=base->cont.properties.first; prop; prop=prop->next) fprintf(f, "%s%s rna_%s_%s;\n", "extern ", rna_property_structname(prop->type), base->identifier, prop->identifier); base= base->base; } - if(srna->properties.first) + if(srna->cont.properties.first) fprintf(f, "\n"); - for(prop=srna->properties.first; prop; prop=prop->next) + for(prop=srna->cont.properties.first; prop; prop=prop->next) fprintf(f, "%s%s rna_%s_%s;\n", (prop->flag & PROP_EXPORT)? "": "", rna_property_structname(prop->type), srna->identifier, prop->identifier); fprintf(f, "\n"); } -static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) +static void rna_generate_parameter_prototypes(BlenderRNA *brna, StructRNA *srna, FunctionRNA *func, FILE *f) { - PropertyRNA *prop; + PropertyRNA *parm; + + for(parm= func->cont.properties.first; parm; parm= parm->next) + fprintf(f, "%s%s rna_%s_%s_%s;\n", "extern ", rna_property_structname(parm->type), srna->identifier, func->identifier, parm->identifier); + + if(func->cont.properties.first) + fprintf(f, "\n"); +} + +static void rna_generate_function_prototypes(BlenderRNA *brna, StructRNA *srna, FILE *f) +{ + FunctionRNA *func; StructRNA *base; - fprintf(f, "/* %s */\n", srna->name); + base= srna->base; + while (base) { + for(func= base->functions.first; func; func= func->cont.next) { + fprintf(f, "%s%s rna_%s_%s;\n", "extern ", "FunctionRNA", base->identifier, func->identifier); + rna_generate_parameter_prototypes(brna, base, func, f); + } + + if(base->functions.first) + fprintf(f, "\n"); + + base= base->base; + } + + for(func= srna->functions.first; func; func= func->cont.next) { + fprintf(f, "%s%s rna_%s_%s;\n", "extern ", "FunctionRNA", srna->identifier, func->identifier); + rna_generate_parameter_prototypes(brna, srna, func, f); + } + + if(srna->functions.first) + fprintf(f, "\n"); +} + +static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, PropertyRNA *prop) +{ + char *strnest= "", *errnest= ""; + int len, freenest= 0; + + if(nest != NULL) { + len= strlen(nest); + + strnest= MEM_mallocN(sizeof(char)*(len+1), "rna_generate_property -> strnest"); + errnest= MEM_mallocN(sizeof(char)*(len+1), "rna_generate_property -> errnest"); + + strcpy(strnest, "_"); strcat(strnest, nest); + strcpy(errnest, "."); strcat(errnest, nest); + + freenest= 1; + } - for(prop=srna->properties.first; prop; prop=prop->next) { - switch(prop->type) { + switch(prop->type) { case PROP_ENUM: { EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop; int i, defaultfound= 0; if(eprop->item) { - fprintf(f, "static EnumPropertyItem rna_%s_%s_items[%d] = {", srna->identifier, prop->identifier, eprop->totitem); + fprintf(f, "static EnumPropertyItem rna_%s%s_%s_items[%d] = {", srna->identifier, strnest, prop->identifier, eprop->totitem); for(i=0; i<eprop->totitem; i++) { fprintf(f, "{%d, ", eprop->item[i].value); @@ -1192,22 +1377,22 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) fprintf(f, "};\n\n"); if(!defaultfound) { - fprintf(stderr, "rna_generate_structs: %s.%s, enum default is not in items.\n", srna->identifier, prop->identifier); + fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default is not in items.\n", srna->identifier, errnest, prop->identifier); DefRNA.error= 1; } } else { - fprintf(stderr, "rna_generate_structs: %s.%s, enum must have items defined.\n", srna->identifier, prop->identifier); + fprintf(stderr, "rna_generate_structs: %s%s.%s, enum must have items defined.\n", srna->identifier, errnest, prop->identifier); DefRNA.error= 1; } break; - } + } case PROP_BOOLEAN: { BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; unsigned int i; if(prop->arraylength) { - fprintf(f, "static int rna_%s_%s_default[%d] = {", srna->identifier, prop->identifier, prop->arraylength); + fprintf(f, "static int rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->arraylength); for(i=0; i<prop->arraylength; i++) { if(bprop->defaultarray) @@ -1221,13 +1406,13 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) fprintf(f, "};\n\n"); } break; - } + } case PROP_INT: { IntPropertyRNA *iprop= (IntPropertyRNA*)prop; unsigned int i; if(prop->arraylength) { - fprintf(f, "static int rna_%s_%s_default[%d] = {", srna->identifier, prop->identifier, prop->arraylength); + fprintf(f, "static int rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->arraylength); for(i=0; i<prop->arraylength; i++) { if(iprop->defaultarray) @@ -1241,13 +1426,13 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) fprintf(f, "};\n\n"); } break; - } + } case PROP_FLOAT: { FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; unsigned int i; if(prop->arraylength) { - fprintf(f, "static float rna_%s_%s_default[%d] = {", srna->identifier, prop->identifier, prop->arraylength); + fprintf(f, "static float rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->arraylength); for(i=0; i<prop->arraylength; i++) { if(fprop->defaultarray) @@ -1261,33 +1446,33 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) fprintf(f, "};\n\n"); } break; - } + } default: break; - } + } - fprintf(f, "%s%s rna_%s_%s = {\n", (prop->flag & PROP_EXPORT)? "": "", rna_property_structname(prop->type), srna->identifier, prop->identifier); + fprintf(f, "%s%s rna_%s%s_%s = {\n", (prop->flag & PROP_EXPORT)? "": "", rna_property_structname(prop->type), srna->identifier, strnest, prop->identifier); - if(prop->next) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->next->identifier); - else fprintf(f, "\t{NULL, "); - if(prop->prev) fprintf(f, "(PropertyRNA*)&rna_%s_%s,\n", srna->identifier, prop->prev->identifier); - else fprintf(f, "NULL,\n"); - fprintf(f, "\t%d, ", prop->magic); - rna_print_c_string(f, prop->identifier); - fprintf(f, ", %d, ", prop->flag); - rna_print_c_string(f, prop->name); fprintf(f, ",\n\t"); - rna_print_c_string(f, prop->description); fprintf(f, ",\n"); - fprintf(f, "\t%s, %s, %d,\n", rna_property_typename(prop->type), rna_property_subtypename(prop->subtype), prop->arraylength); - fprintf(f, "\t%s, %d, %s},\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable)); - - switch(prop->type) { + if(prop->next) fprintf(f, "\t{(PropertyRNA*)&rna_%s%s_%s, ", srna->identifier, strnest, prop->next->identifier); + else fprintf(f, "\t{NULL, "); + if(prop->prev) fprintf(f, "(PropertyRNA*)&rna_%s%s_%s,\n", srna->identifier, strnest, prop->prev->identifier); + else fprintf(f, "NULL,\n"); + fprintf(f, "\t%d, ", prop->magic); + rna_print_c_string(f, prop->identifier); + fprintf(f, ", %d, ", prop->flag); + rna_print_c_string(f, prop->name); fprintf(f, ",\n\t"); + rna_print_c_string(f, prop->description); fprintf(f, ",\n"); + fprintf(f, "\t%s, %s, %d,\n", rna_property_typename(prop->type), rna_property_subtypename(prop->subtype), prop->arraylength); + fprintf(f, "\t%s, %d, %s},\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable)); + + switch(prop->type) { case PROP_BOOLEAN: { BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %d, ", rna_function_string(bprop->get), rna_function_string(bprop->set), rna_function_string(bprop->getarray), rna_function_string(bprop->setarray), bprop->defaultvalue); - if(prop->arraylength) fprintf(f, "rna_%s_%s_default\n", srna->identifier, prop->identifier); + if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; - } + } case PROP_INT: { IntPropertyRNA *iprop= (IntPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %s,\n\t", rna_function_string(iprop->get), rna_function_string(iprop->set), rna_function_string(iprop->getarray), rna_function_string(iprop->setarray), rna_function_string(iprop->range)); @@ -1297,10 +1482,10 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) rna_int_print(f, iprop->hardmax); fprintf(f, ", "); rna_int_print(f, iprop->step); fprintf(f, ", "); rna_int_print(f, iprop->defaultvalue); fprintf(f, ", "); - if(prop->arraylength) fprintf(f, "rna_%s_%s_default\n", srna->identifier, prop->identifier); + if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; - } + } case PROP_FLOAT: { FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), rna_function_string(fprop->range)); @@ -1311,47 +1496,107 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) rna_float_print(f, fprop->step); fprintf(f, ", "); rna_int_print(f, (int)fprop->precision); fprintf(f, ", "); rna_float_print(f, fprop->defaultvalue); fprintf(f, ", "); - if(prop->arraylength) fprintf(f, "rna_%s_%s_default\n", srna->identifier, prop->identifier); + if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; - } + } case PROP_STRING: { StringPropertyRNA *sprop= (StringPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), sprop->maxlength); rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n"); break; - } + } case PROP_ENUM: { EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop; - fprintf(f, "\t%s, %s, rna_%s_%s_items, %d, %d\n", rna_function_string(eprop->get), rna_function_string(eprop->set), srna->identifier, prop->identifier, eprop->totitem, eprop->defaultvalue); + fprintf(f, "\t%s, %s, rna_%s%s_%s_items, %d, %d\n", rna_function_string(eprop->get), rna_function_string(eprop->set), srna->identifier, strnest, prop->identifier, eprop->totitem, eprop->defaultvalue); break; - } + } case PROP_POINTER: { PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop; fprintf(f, "\t%s, %s, ", rna_function_string(pprop->get), rna_function_string(pprop->set)); if(pprop->type) fprintf(f, "&RNA_%s\n", (char*)pprop->type); else fprintf(f, "NULL\n"); break; - } + } case PROP_COLLECTION: { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring)); if(cprop->type) fprintf(f, "&RNA_%s\n", (char*)cprop->type); else fprintf(f, "NULL\n"); break; - } - } + } + } - fprintf(f, "};\n\n"); + fprintf(f, "};\n\n"); + + if(freenest) { + MEM_freeN(strnest); + MEM_freeN(errnest); + } +} + +static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) +{ + FunctionRNA *func; + FunctionDefRNA *dfunc; + PropertyRNA *prop, *parm; + StructRNA *base; + + fprintf(f, "/* %s */\n", srna->name); + + for(prop= srna->cont.properties.first; prop; prop= prop->next) + rna_generate_property(f, srna, NULL, prop); + + for(func= srna->functions.first; func; func= func->cont.next) { + for(parm= func->cont.properties.first; parm; parm= parm->next) + rna_generate_property(f, srna, func->identifier, parm); + + fprintf(f, "%s%s rna_%s_%s = {\n", "", "FunctionRNA", srna->identifier, func->identifier); + + if(func->cont.next) fprintf(f, "\t{(FunctionRNA*)&rna_%s_%s, ", srna->identifier, ((FunctionRNA*)func->cont.next)->identifier); + else fprintf(f, "\t{NULL, "); + if(func->cont.prev) fprintf(f, "(FunctionRNA*)&rna_%s_%s,\n", srna->identifier, ((FunctionRNA*)func->cont.prev)->identifier); + else fprintf(f, "NULL,\n"); + + parm= func->cont.properties.first; + if(parm) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s_%s, ", srna->identifier, func->identifier, parm->identifier); + else fprintf(f, "\t{NULL, "); + + parm= func->cont.properties.last; + if(parm) fprintf(f, "(PropertyRNA*)&rna_%s_%s_%s}},\n", srna->identifier, func->identifier, parm->identifier); + else fprintf(f, "NULL}},\n"); + + fprintf(f, "\t"); + rna_print_c_string(f, func->identifier); + fprintf(f, ", %d, ", func->flag); + rna_print_c_string(f, func->description); fprintf(f, ",\n"); + + dfunc= rna_find_function_def(func); + if(dfunc->call) fprintf(f, "\t%s,\n", dfunc->call); + else fprintf(f, "\tNULL,\n"); + + if(func->ret) fprintf(f, "\t(PropertyRNA*)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->ret->identifier); + else fprintf(f, "\tNULL\n"); + + fprintf(f, "};\n"); + fprintf(f, "\n"); } fprintf(f, "StructRNA RNA_%s = {\n", srna->identifier); - if(srna->next) fprintf(f, "\t&RNA_%s, ", srna->next->identifier); - else fprintf(f, "\tNULL, "); - if(srna->prev) fprintf(f, "&RNA_%s,\n", srna->prev->identifier); + if(srna->cont.next) fprintf(f, "\t{(ContainerRNA *)&RNA_%s, ", ((StructRNA*)srna->cont.next)->identifier); + else fprintf(f, "\t{NULL, "); + if(srna->cont.prev) fprintf(f, "(ContainerRNA *)&RNA_%s,\n", ((StructRNA*)srna->cont.prev)->identifier); else fprintf(f, "NULL,\n"); - + + prop= srna->cont.properties.first; + if(prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier); + else fprintf(f, "\t{NULL, "); + + prop= srna->cont.properties.last; + if(prop) fprintf(f, "(PropertyRNA*)&rna_%s_%s}},\n", srna->identifier, prop->identifier); + else fprintf(f, "NULL}},\n"); + fprintf(f, "\tNULL,\n"); /* PyType - Cant initialize here */ fprintf(f, "\t"); @@ -1387,12 +1632,12 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) fprintf(f, "\t%s,\n", rna_function_string(srna->refine)); fprintf(f, "\t%s,\n", rna_function_string(srna->path)); - prop= srna->properties.first; - if(prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier); + func= srna->functions.first; + if(func) fprintf(f, "\t{(FunctionRNA*)&rna_%s_%s, ", srna->identifier, func->identifier); else fprintf(f, "\t{NULL, "); - prop= srna->properties.last; - if(prop) fprintf(f, "(PropertyRNA*)&rna_%s_%s}\n", srna->identifier, prop->identifier); + func= srna->functions.last; + if(func) fprintf(f, "(FunctionRNA*)&rna_%s_%s}\n", srna->identifier, func->identifier); else fprintf(f, "NULL}\n"); fprintf(f, "};\n"); @@ -1460,6 +1705,7 @@ static void rna_generate(BlenderRNA *brna, FILE *f, char *filename) { StructDefRNA *ds; PropertyDefRNA *dp; + FunctionDefRNA *dfunc; fprintf(f, "\n/* Automatically generated struct definitions for the Data API.\n" " Do not edit manually, changes will be overwritten. */\n\n" @@ -1483,16 +1729,24 @@ static void rna_generate(BlenderRNA *brna, FILE *f, char *filename) fprintf(f, "/* Autogenerated Functions */\n\n"); - for(ds=DefRNA.structs.first; ds; ds=ds->next) - if(!filename || ds->filename == filename) + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) { + if(!filename || ds->filename == filename) { rna_generate_property_prototypes(brna, ds->srna, f); + rna_generate_function_prototypes(brna, ds->srna, f); + } + } - for(ds=DefRNA.structs.first; ds; ds=ds->next) + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) if(!filename || ds->filename == filename) - for(dp=ds->properties.first; dp; dp=dp->next) - rna_def_property_funcs(f, dp); + for(dp=ds->cont.properties.first; dp; dp=dp->next) + rna_def_property_funcs(f, ds->srna, dp); - for(ds=DefRNA.structs.first; ds; ds=ds->next) + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) + if(!filename || ds->filename == filename) + for(dfunc=ds->functions.first; dfunc; dfunc= dfunc->cont.next) + rna_def_function_funcs(f, ds, dfunc); + + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) if(!filename || ds->filename == filename) rna_generate_struct(brna, ds->srna, f); @@ -1532,7 +1786,7 @@ static void rna_generate_header(BlenderRNA *brna, FILE *f) fprintf(f, " property##_end(&rna_macro_iter); \\\n"); fprintf(f, " }\n\n"); - for(ds=DefRNA.structs.first; ds; ds=ds->next) { + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) { srna= ds->srna; fprintf(f, "/**************** %s ****************/\n\n", srna->name); @@ -1543,8 +1797,8 @@ static void rna_generate_header(BlenderRNA *brna, FILE *f) } fprintf(f, "\n"); - for(dp=ds->properties.first; dp; dp=dp->next) - rna_def_property_funcs_header(f, dp); + for(dp=ds->cont.properties.first; dp; dp=dp->next) + rna_def_property_funcs_header(f, ds->srna, dp); } fprintf(f, "#ifdef __cplusplus\n}\n#endif\n\n"); @@ -1679,11 +1933,11 @@ static void rna_generate_header_cpp(BlenderRNA *brna, FILE *f) fprintf(f, "/**************** Declarations ****************/\n\n"); - for(ds=DefRNA.structs.first; ds; ds=ds->next) + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) fprintf(f, "class %s;\n", ds->srna->identifier); fprintf(f, "\n"); - for(ds=DefRNA.structs.first; ds; ds=ds->next) { + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) { srna= ds->srna; fprintf(f, "/**************** %s ****************/\n\n", srna->name); @@ -1691,23 +1945,23 @@ static void rna_generate_header_cpp(BlenderRNA *brna, FILE *f) fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base)? srna->base->identifier: "Pointer"); fprintf(f, "public:\n"); fprintf(f, "\t%s(const PointerRNA& ptr) :\n\t\t%s(ptr)", srna->identifier, (srna->base)? srna->base->identifier: "Pointer"); - for(dp=ds->properties.first; dp; dp=dp->next) + for(dp=ds->cont.properties.first; dp; dp=dp->next) if(!(dp->prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))) if(dp->prop->type == PROP_COLLECTION) fprintf(f, ",\n\t\t%s(ptr)", dp->prop->identifier); fprintf(f, "\n\t\t{}\n\n"); - for(dp=ds->properties.first; dp; dp=dp->next) - rna_def_property_funcs_header_cpp(f, dp); + for(dp=ds->cont.properties.first; dp; dp=dp->next) + rna_def_property_funcs_header_cpp(f, ds->srna, dp); fprintf(f, "};\n\n"); } fprintf(f, "/**************** Implementation ****************/\n"); - for(ds=DefRNA.structs.first; ds; ds=ds->next) { - for(dp=ds->properties.first; dp; dp=dp->next) - rna_def_property_funcs_impl_cpp(f, dp); + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) { + for(dp=ds->cont.properties.first; dp; dp=dp->next) + rna_def_property_funcs_impl_cpp(f, ds->srna, dp); fprintf(f, "\n"); } @@ -1737,7 +1991,7 @@ static int rna_preprocess(char *outfile) if(PROCESS_ITEMS[i].define) { PROCESS_ITEMS[i].define(brna); - for(ds=DefRNA.structs.first; ds; ds=ds->next) + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) if(!ds->filename) ds->filename= PROCESS_ITEMS[i].filename; } @@ -1827,11 +2081,17 @@ static int rna_preprocess(char *outfile) return status; } +static void mem_error_cb(char *errorStr) +{ + fprintf(stderr, "%s", errorStr); + fflush(stderr); +} + int main(int argc, char **argv) { int totblock, return_status = 0; - if (argc<2) { + if(argc<2) { printf("Usage: %s outdirectory/\n", argv[0]); return_status = 1; } @@ -1843,6 +2103,7 @@ int main(int argc, char **argv) totblock= MEM_get_memory_blocks_in_use(); if(totblock!=0) { printf("Error Totblock: %d\n",totblock); + MEM_set_error_callback(mem_error_cb); MEM_printmemlist(); } diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 5955f16f916..cdae8d78ffe 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -167,6 +167,7 @@ static void rna_def_ID(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; srna= RNA_def_struct(brna, "ID", NULL); RNA_def_struct_ui_text(srna, "ID", "Base type for datablocks, defining a unique name, linking from other libraries and garbage collection."); @@ -193,6 +194,11 @@ static void rna_def_ID(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "lib"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Library", "Library file the datablock is linked from."); + + /* XXX temporary for testing */ + func= RNA_def_function(srna, "rename", "rename_id"); + RNA_def_function_ui_description(func, "Rename this ID datablock."); + RNA_def_string(func, "name", "", 0, "", "New name for the datablock."); } static void rna_def_library(BlenderRNA *brna) @@ -212,10 +218,14 @@ void RNA_def_ID(BlenderRNA *brna) { StructRNA *srna; - /* simple built-in unknown type */ + /* built-in unknown type */ srna= RNA_def_struct(brna, "UnknownType", NULL); RNA_def_struct_ui_text(srna, "Unknown Type", "Stub RNA type used for pointers to unknown or internal data."); + /* built-in any type */ + srna= RNA_def_struct(brna, "AnyType", NULL); + RNA_def_struct_ui_text(srna, "Any Type", "RNA type used for pointers to any possible data."); + rna_def_ID(brna); rna_def_ID_properties(brna); rna_def_library(brna); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index cf6072c2bfd..d08516c4a62 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -331,7 +331,48 @@ PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier) const struct ListBase *RNA_struct_defined_properties(StructRNA *srna) { - return &srna->properties; + return &srna->cont.properties; +} + +FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier) +{ + PointerRNA tptr; + CollectionPropertyIterator iter; + PropertyRNA *iterprop; + FunctionRNA *func; + int i = 0; + + RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr); + iterprop= RNA_struct_find_property(&tptr, "functions"); + + RNA_property_collection_begin(&tptr, iterprop, &iter); + func= NULL; + + for(; iter.valid; RNA_property_collection_next(&iter), i++) { + if(strcmp(identifier, RNA_function_identifier(&tptr, iter.ptr.data)) == 0) { + func= iter.ptr.data; + break; + } + } + + RNA_property_collection_end(&iter); + + return func; +} + +const struct ListBase *RNA_struct_defined_functions(StructRNA *srna) +{ + return &srna->functions; +} + +void *RNA_struct_py_type_get(StructRNA *srna) +{ + return srna->py_type; +} + +void RNA_struct_py_type_set(StructRNA *srna, void *py_type) +{ + srna->py_type= py_type; } /* Property Information */ @@ -493,8 +534,8 @@ int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *iden RNA_property_enum_items(ptr, prop, &item, &totitem); - for (i=0; i<totitem; i++) { - if (strcmp(item[i].identifier, identifier)==0) { + for(i=0; i<totitem; i++) { + if(strcmp(item[i].identifier, identifier)==0) { *value = item[i].value; return 1; } @@ -510,8 +551,8 @@ int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int v RNA_property_enum_items(ptr, prop, &item, &totitem); - for (i=0; i<totitem; i++) { - if (item[i].value==value) { + for(i=0; i<totitem; i++) { + if(item[i].value==value) { *identifier = item[i].identifier; return 1; } @@ -1267,7 +1308,7 @@ int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, co found= 1; } - if ((char *)&name != nameptr) + if((char *)&name != nameptr) MEM_freeN(nameptr); if(found) @@ -1835,7 +1876,7 @@ int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname) int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value) { for( ; item->identifier; item++) { - if (strcmp(item->identifier, identifier)==0) { + if(strcmp(item->identifier, identifier)==0) { *value= item->value; return 1; } @@ -1847,7 +1888,7 @@ int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int * int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier) { for( ; item->identifier; item++) { - if (item->value==value) { + if(item->value==value) { *identifier= item->identifier; return 1; } @@ -2002,7 +2043,7 @@ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop) /* see if we can coorce into a python type - PropertyType */ switch (type) { case PROP_BOOLEAN: - if (len==0) { + if(len==0) { BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False"); } else { @@ -2014,7 +2055,7 @@ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop) } break; case PROP_INT: - if (len==0) { + if(len==0) { BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop)); } else { @@ -2026,7 +2067,7 @@ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop) } break; case PROP_FLOAT: - if (len==0) { + if(len==0) { BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop)); } else { @@ -2052,7 +2093,7 @@ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop) const char *identifier; int val = RNA_property_enum_get(ptr, prop); - if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) { + if(RNA_property_enum_identifier(ptr, prop, val, &identifier)) { BLI_dynstr_appendf(dynstr, "'%s'", identifier); } else { @@ -2078,3 +2119,290 @@ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop) return cstring; } +/* Function */ + +const char *RNA_function_identifier(PointerRNA *ptr, FunctionRNA *func) +{ + return func->identifier; +} + +PropertyRNA *RNA_function_return(PointerRNA *ptr, FunctionRNA *func) +{ + return func->ret; +} + +const char *RNA_function_ui_description(PointerRNA *ptr, FunctionRNA *func) +{ + return func->description; +} + +PropertyRNA *RNA_function_get_parameter(PointerRNA *ptr, FunctionRNA *func, int index) +{ + PropertyRNA *parm; + int i; + + parm= func->cont.properties.first; + for(i= 0; parm; parm= parm->next, i++) + if(i==index) + return parm; + + return NULL; +} + +PropertyRNA *RNA_function_find_parameter(PointerRNA *ptr, FunctionRNA *func, const char *identifier) +{ + PropertyRNA *parm; + + parm= func->cont.properties.first; + for(; parm; parm= parm->next) + if(strcmp(parm->identifier, identifier)==0) + return parm; + + return NULL; +} + +const struct ListBase *RNA_function_defined_parameters(PointerRNA *ptr, FunctionRNA *func) +{ + return &func->cont.properties; +} + +/* Utility */ + +ParameterList *RNA_parameter_list_create(PointerRNA *ptr, FunctionRNA *func) +{ + ParameterList *parms; + PropertyRNA *parm; + int tot; + + parms= MEM_callocN(sizeof(ParameterList), "ParameterList"); + + parm= func->cont.properties.first; + for(tot= 0; parm; parm= parm->next) + tot+= rna_parameter_size(parm); + + parms->data= MEM_callocN(tot, "RNA_parameter_list_create"); + parms->func= func; + + return parms; +} + +void RNA_parameter_list_free(ParameterList *parms) +{ + MEM_freeN(parms->data); + + parms->func= NULL; + + MEM_freeN(parms); +} + +void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter) +{ + PropertyType ptype; + + RNA_pointer_create(NULL, &RNA_Function, parms->func, &iter->funcptr); + + iter->parms= parms; + iter->parm= parms->func->cont.properties.first; + iter->valid= iter->parm != NULL; + iter->offset= 0; + + if(iter->valid) { + iter->size= rna_parameter_size(iter->parm); + iter->data= (((char*)iter->parms->data)+iter->offset); + ptype= RNA_property_type(&iter->funcptr, iter->parm); + } +} + +void RNA_parameter_list_next(ParameterIterator *iter) +{ + PropertyType ptype; + + iter->offset+= iter->size; + iter->parm= iter->parm->next; + iter->valid= iter->parm != NULL; + + if(iter->valid) { + iter->size= rna_parameter_size(iter->parm); + iter->data= (((char*)iter->parms->data)+iter->offset); + ptype= RNA_property_type(&iter->funcptr, iter->parm); + } +} + +void RNA_parameter_list_end(ParameterIterator *iter) +{ + /* nothing to do */ +} + +void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **value) +{ + ParameterIterator iter; + + RNA_parameter_list_begin(parms, &iter); + + for(; iter.valid; RNA_parameter_list_next(&iter)) + if(iter.parm==parm) + break; + + if(iter.valid) + *value= iter.data; + else + *value= NULL; + + RNA_parameter_list_end(&iter); +} + +void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value) +{ + PointerRNA funcptr; + PropertyRNA *parm; + + RNA_pointer_create(NULL, &RNA_Function, parms->func, &funcptr); + + parm= parms->func->cont.properties.first; + for(; parm; parm= parm->next) + if(strcmp(RNA_property_identifier(&funcptr, parm), identifier)==0) + break; + + if(parm) + RNA_parameter_get(parms, parm, value); +} + +void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, void *value) +{ + PointerRNA funcptr; + ParameterIterator iter; + + RNA_pointer_create(NULL, &RNA_Function, parms->func, &funcptr); + RNA_parameter_list_begin(parms, &iter); + + for(; iter.valid; RNA_parameter_list_next(&iter)) + if(iter.parm==parm) + break; + + if(iter.valid) + memcpy(iter.data, value, iter.size); + + RNA_parameter_list_end(&iter); +} + +void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, void *value) +{ + PointerRNA funcptr; + PropertyRNA *parm; + + RNA_pointer_create(NULL, &RNA_Function, parms->func, &funcptr); + + parm= parms->func->cont.properties.first; + for(; parm; parm= parm->next) + if(strcmp(RNA_property_identifier(&funcptr, parm), identifier)==0) + break; + + if(parm) + RNA_parameter_set(parms, parm, value); +} + +int RNA_function_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) +{ + if(func->call) { + func->call(ptr, parms); + + return 0; + } + + return 1; +} + +int RNA_function_call_lookup(PointerRNA *ptr, const char *identifier, ParameterList *parms) +{ + FunctionRNA *func; + + func= RNA_struct_find_function(ptr, identifier); + + if(func) + return RNA_function_call(ptr, func, parms); + + return 0; +} + +#if 0 +int RNA_function_call_direct(PointerRNA *ptr, FunctionRNA *func, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + + ret= RNA_function_call_direct_va(ptr, func, format, args); + + va_end(args); + + return ret; +} + +int RNA_function_call_direct_lookup(PointerRNA *ptr, const char *identifier, const char *format, ...) +{ + FunctionRNA *func; + + func= RNA_struct_find_function(ptr, identifier); + + if(func) { + va_list args; + int ret; + + va_start(args, format); + + ret= RNA_function_call_direct_va(ptr, func, format, args); + + va_end(args); + + return ret; + } + + return 0; +} + +int RNA_function_call_direct_va(PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args) +{ + PointerRNA funcptr; + ParameterList *parms; + ParameterIterator iter; + PropertyRNA *pret, *parm; + PropertyType ptype; + PropertySubType psubtype; + int i, tlen, alen, err= 0; + const char *tid, *fid, *pid; + void **retdata; + + RNA_pointer_create(NULL, &RNA_Function, func, &funcptr); + + tid= RNA_struct_identifier(ptr); + fid= RNA_function_identifier(ptr, func); + pret= RNA_function_return(ptr, func); + + parms= RNA_parameter_list_create(ptr, func); + RNA_parameter_list_begin(parms, &iter); + + for(i= 0; iter.valid; RNA_parameter_list_next(&iter), i++) { + parm= iter.parm; + if(parm==pret) { + retdata= iter.data; + continue; + } + + /* XXX todo later, this is not really a priority as of now */ + } +} + +int RNA_function_call_direct_va_lookup(PointerRNA *ptr, const char *identifier, const char *format, va_list args) +{ + FunctionRNA *func; + + func= RNA_struct_find_function(ptr, identifier); + + if(func) + return RNA_function_call_direct_va(ptr, func, format, args); + + return 0; +} +#endif + diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 15486efc9d0..31f7509981e 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -92,6 +92,158 @@ void rna_freelistN(ListBase *listbase) listbase->first= listbase->last= NULL; } +StructDefRNA *rna_find_struct_def(StructRNA *srna) +{ + StructDefRNA *dsrna; + + if(!DefRNA.preprocess) { + /* we should never get here */ + fprintf(stderr, "rna_find_struct_def: only at preprocess time.\n"); + return NULL; + } + + dsrna= DefRNA.structs.last; + for (; dsrna; dsrna= dsrna->cont.prev) + if (dsrna->srna==srna) + return dsrna; + + return NULL; +} + +PropertyDefRNA *rna_find_struct_property_def(PropertyRNA *prop) +{ + StructDefRNA *dsrna; + PropertyDefRNA *dprop; + + if(!DefRNA.preprocess) { + /* we should never get here */ + fprintf(stderr, "rna_find_property_def: only at preprocess time.\n"); + return NULL; + } + + dsrna= rna_find_struct_def(DefRNA.laststruct); + dprop= dsrna->cont.properties.last; + for (; dprop; dprop= dprop->prev) + if (dprop->prop==prop) + return dprop; + + dsrna= DefRNA.structs.last; + for (; dsrna; dsrna= dsrna->cont.prev) { + dprop= dsrna->cont.properties.last; + for (; dprop; dprop= dprop->prev) + if (dprop->prop==prop) + return dprop; + } + + return NULL; +} + +PropertyDefRNA *rna_find_property_def(PropertyRNA *prop) +{ + PropertyDefRNA *dprop; + + if(!DefRNA.preprocess) { + /* we should never get here */ + fprintf(stderr, "rna_find_property_def: only at preprocess time.\n"); + return NULL; + } + + dprop= rna_find_struct_property_def(prop); + if (dprop) + return dprop; + + dprop= rna_find_parameter_def(prop); + if (dprop) + return dprop; + + return NULL; +} + +FunctionDefRNA *rna_find_function_def(FunctionRNA *func) +{ + StructDefRNA *dsrna; + FunctionDefRNA *dfunc; + + if(!DefRNA.preprocess) { + /* we should never get here */ + fprintf(stderr, "rna_find_function_def: only at preprocess time.\n"); + return NULL; + } + + dsrna= rna_find_struct_def(DefRNA.laststruct); + dfunc= dsrna->functions.last; + for (; dfunc; dfunc= dfunc->cont.prev) + if (dfunc->func==func) + return dfunc; + + dsrna= DefRNA.structs.last; + for (; dsrna; dsrna= dsrna->cont.prev) { + dfunc= dsrna->functions.last; + for (; dfunc; dfunc= dfunc->cont.prev) + if (dfunc->func==func) + return dfunc; + } + + return NULL; +} + +PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm) +{ + StructDefRNA *dsrna; + FunctionDefRNA *dfunc; + PropertyDefRNA *dparm; + + if(!DefRNA.preprocess) { + /* we should never get here */ + fprintf(stderr, "rna_find_parameter_def: only at preprocess time.\n"); + return NULL; + } + + dsrna= rna_find_struct_def(DefRNA.laststruct); + dfunc= dsrna->functions.last; + for (; dfunc; dfunc= dfunc->cont.prev) { + dparm= dfunc->cont.properties.last; + for (; dparm; dparm= dparm->prev) + if (dparm->prop==parm) + return dparm; + } + + dsrna= DefRNA.structs.last; + for (; dsrna; dsrna= dsrna->cont.prev) { + dfunc= dsrna->functions.last; + for (; dfunc; dfunc= dfunc->cont.prev) { + dparm= dfunc->cont.properties.last; + for (; dparm; dparm= dparm->prev) + if (dparm->prop==parm) + return dparm; + } + } + + return NULL; +} + +ContainerDefRNA *rna_find_container_def(ContainerRNA *cont) +{ + StructDefRNA *ds; + FunctionDefRNA *dfunc; + + if(!DefRNA.preprocess) { + /* we should never get here */ + fprintf(stderr, "rna_find_container_def: only at preprocess time.\n"); + return NULL; + } + + ds= rna_find_struct_def((StructRNA*)cont); + if(ds) + return &ds->cont; + + dfunc= rna_find_function_def((FunctionRNA*)cont); + if(dfunc) + return &dfunc->cont; + + return NULL; +} + /* DNA utility function for looking up members */ typedef struct DNAStructMember { @@ -244,15 +396,21 @@ BlenderRNA *RNA_create() void RNA_define_free(BlenderRNA *brna) { - StructDefRNA *srna; + StructDefRNA *ds; + FunctionDefRNA *dfunc; AllocDefRNA *alloc; for(alloc=DefRNA.allocs.first; alloc; alloc=alloc->next) MEM_freeN(alloc->mem); rna_freelistN(&DefRNA.allocs); - for(srna=DefRNA.structs.first; srna; srna=srna->next) - rna_freelistN(&srna->properties); + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) { + for (dfunc= ds->functions.first; dfunc; dfunc= dfunc->cont.next) + rna_freelistN(&dfunc->cont.properties); + + rna_freelistN(&ds->cont.properties); + rna_freelistN(&ds->functions); + } rna_freelistN(&DefRNA.structs); @@ -268,12 +426,19 @@ void RNA_free(BlenderRNA *brna) { StructRNA *srna, *nextsrna; PropertyRNA *prop, *nextprop; + FunctionRNA *func, *nextfunc; + PropertyRNA *parm, *nextparm; if(DefRNA.preprocess) { RNA_define_free(brna); - for(srna=brna->structs.first; srna; srna=srna->next) - rna_freelistN(&srna->properties); + for(srna=brna->structs.first; srna; srna=srna->cont.next) { + for (func= srna->functions.first; func; func= func->cont.next) + rna_freelistN(&func->cont.properties); + + rna_freelistN(&srna->cont.properties); + rna_freelistN(&srna->functions); + } rna_freelistN(&brna->structs); @@ -281,13 +446,28 @@ void RNA_free(BlenderRNA *brna) } else { for(srna=brna->structs.first; srna; srna=nextsrna) { - nextsrna= srna->next; + nextsrna= srna->cont.next; - for(prop=srna->properties.first; prop; prop=nextprop) { + for(prop=srna->cont.properties.first; prop; prop=nextprop) { nextprop= prop->next; if(prop->flag & PROP_RUNTIME) - rna_freelinkN(&srna->properties, prop); + rna_freelinkN(&srna->cont.properties, prop); + } + + for(func=srna->functions.first; func; func=nextfunc) { + nextfunc= func->cont.next; + + for(parm=func->cont.properties.first; parm; parm=nextparm) { + nextparm= parm->next; + + if(parm->flag & PROP_RUNTIME) + rna_freelinkN(&func->cont.properties, parm); + } + + if(func->flag & FUNC_RUNTIME) { + rna_freelinkN(&srna->functions, func); + } } if(srna->flag & STRUCT_RUNTIME) @@ -314,7 +494,7 @@ static StructDefRNA *rna_find_def_struct(StructRNA *srna) { StructDefRNA *ds; - for(ds=DefRNA.structs.first; ds; ds=ds->next) + for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) if(ds->srna == srna) return ds; @@ -340,7 +520,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * if(from) { /* find struct to derive from */ - for(srnafrom= brna->structs.first; srnafrom; srnafrom=srnafrom->next) + for(srnafrom= brna->structs.first; srnafrom; srnafrom=srnafrom->cont.next) if(strcmp(srnafrom->identifier, from) == 0) break; @@ -357,7 +537,8 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * /* copy from struct to derive stuff, a bit clumsy since we can't * use MEM_dupallocN, data structs may not be alloced but builtin */ memcpy(srna, srnafrom, sizeof(StructRNA)); - srna->properties.first= srna->properties.last= NULL; + srna->cont.properties.first= srna->cont.properties.last= NULL; + srna->functions.first= srna->functions.last= NULL; if(DefRNA.preprocess) { srna->base= srnafrom; @@ -394,7 +575,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * } else { /* define some builtin properties */ - prop= RNA_def_property(srna, "rna_properties", PROP_COLLECTION, PROP_NONE); + prop= RNA_def_property(&srna->cont, "rna_properties", PROP_COLLECTION, PROP_NONE); RNA_def_property_flag(prop, PROP_BUILTIN); RNA_def_property_ui_text(prop, "Properties", "RNA property collection."); @@ -412,7 +593,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * #endif } - prop= RNA_def_property(srna, "rna_type", PROP_POINTER, PROP_NONE); + prop= RNA_def_property(&srna->cont, "rna_type", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "RNA", "RNA type definition."); if(DefRNA.preprocess) { @@ -433,13 +614,15 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * void RNA_def_struct_sdna(StructRNA *srna, const char *structname) { - StructDefRNA *ds= DefRNA.structs.last; + StructDefRNA *ds; if(!DefRNA.preprocess) { fprintf(stderr, "RNA_def_struct_sdna: only during preprocessing.\n"); return; } + ds= rna_find_def_struct(srna); + if(!DNA_struct_find_nr(DefRNA.sdna, structname)) { if(!DefRNA.silent) { fprintf(stderr, "RNA_def_struct_sdna: %s not found.\n", structname); @@ -453,13 +636,15 @@ void RNA_def_struct_sdna(StructRNA *srna, const char *structname) void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname) { - StructDefRNA *ds= DefRNA.structs.last; + StructDefRNA *ds; if(!DefRNA.preprocess) { fprintf(stderr, "RNA_def_struct_sdna_from: only during preprocessing.\n"); return; } + ds= rna_find_def_struct(srna); + if(!ds->dnaname) { fprintf(stderr, "RNA_def_struct_sdna_from: %s base struct must know DNA already.\n", structname); return; @@ -492,7 +677,7 @@ void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *struct StructRNA *srnafrom; /* find struct to derive from */ - for(srnafrom= brna->structs.first; srnafrom; srnafrom=srnafrom->next) + for(srnafrom= brna->structs.first; srnafrom; srnafrom=srnafrom->cont.next) if(strcmp(srnafrom->identifier, structname) == 0) break; @@ -547,16 +732,18 @@ void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *descr void RNA_struct_free(BlenderRNA *brna, StructRNA *srna) { - rna_freelistN(&srna->properties); + rna_freelistN(&srna->cont.properties); rna_freelinkN(&brna->structs, srna); } /* Property Definition */ -PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, int subtype) +PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype) { - StructDefRNA *ds; - PropertyDefRNA *dp= NULL; + StructRNA *srna= DefRNA.laststruct; + ContainerRNA *cont= cont_; + ContainerDefRNA *dcont; + PropertyDefRNA *dprop= NULL; PropertyRNA *prop; if(DefRNA.preprocess) { @@ -567,9 +754,9 @@ PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, DefRNA.error= 1; } - ds= DefRNA.structs.last; - dp= MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA"); - rna_addtail(&ds->properties, dp); + dcont= rna_find_container_def(cont); + dprop= MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA"); + rna_addtail(&dcont->properties, dprop); } prop= MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA"); @@ -628,8 +815,8 @@ PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, } if(DefRNA.preprocess) { - dp->srna= srna; - dp->prop= prop; + dprop->cont= cont; + dprop->prop= prop; } prop->magic= RNA_MAGIC; @@ -639,8 +826,12 @@ PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, prop->name= identifier; prop->description= ""; - if(type != PROP_COLLECTION && type != PROP_POINTER) - prop->flag= PROP_EDITABLE|PROP_ANIMATEABLE; + if(type != PROP_COLLECTION && type != PROP_POINTER) { + prop->flag= PROP_EDITABLE; + + if(type != PROP_STRING) + prop->flag |= PROP_ANIMATEABLE; + } if(DefRNA.preprocess) { switch(type) { @@ -687,7 +878,7 @@ PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, else prop->flag |= PROP_IDPROPERTY|PROP_RUNTIME; - rna_addtail(&srna->properties, prop); + rna_addtail(&cont->properties, prop); return prop; } @@ -1050,8 +1241,13 @@ void RNA_def_property_enum_default(PropertyRNA *prop, int value) static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *structname, const char *propname) { DNAStructMember smember; - StructDefRNA *ds= DefRNA.structs.last; - PropertyDefRNA *dp= ds->properties.last; + StructDefRNA *ds; + PropertyDefRNA *dp; + + dp= rna_find_struct_property_def(prop); + if (dp==NULL) return NULL; + + ds= rna_find_struct_def((StructRNA*)dp->cont); if(!structname) structname= ds->dnaname; @@ -1104,12 +1300,13 @@ void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, co void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *structname, const char *propname, int booleanbit) { - StructDefRNA *ds; PropertyDefRNA *dp; RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit); - if((ds=DefRNA.structs.last) && (dp=ds->properties.last)) + dp= rna_find_struct_property_def(prop); + + if(dp) dp->booleannegative= 1; } @@ -1200,13 +1397,14 @@ void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structname, const char *propname) { - StructDefRNA *ds; PropertyDefRNA *dp; RNA_def_property_enum_sdna(prop, structname, propname); - if((ds=DefRNA.structs.last) && (dp=ds->properties.last)) - dp->enumbitflags= 1; + dp= rna_find_struct_property_def(prop); + + if(dp) + dp->booleannegative= 1; } void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname) @@ -1297,7 +1495,7 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, if(dp && lengthpropname) { DNAStructMember smember; - StructDefRNA *ds= DefRNA.structs.last; + StructDefRNA *ds= rna_find_struct_def((StructRNA*)dp->cont); if(!structname) structname= ds->dnaname; @@ -1548,23 +1746,25 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, con /* Compact definitions */ -PropertyRNA *RNA_def_boolean(StructRNA *srna, const char *identifier, int default_value, - const char *ui_name, const char *ui_description) +PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, int default_value, const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_default(prop, default_value); RNA_def_property_ui_text(prop, ui_name, ui_description); return prop; } -PropertyRNA *RNA_def_boolean_array(StructRNA *srna, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description) +PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, + const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_boolean_array_default(prop, default_value); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1572,11 +1772,13 @@ PropertyRNA *RNA_def_boolean_array(StructRNA *srna, const char *identifier, int return prop; } -PropertyRNA *RNA_def_boolean_vector(StructRNA *srna, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description) +PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, + const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_BOOLEAN, PROP_VECTOR); + prop= RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_VECTOR); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_boolean_array_default(prop, default_value); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1584,12 +1786,13 @@ PropertyRNA *RNA_def_boolean_vector(StructRNA *srna, const char *identifier, int return prop; } -PropertyRNA *RNA_def_int(StructRNA *srna, const char *identifier, int default_value, int hardmin, int hardmax, +PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_INT, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_INT, PROP_NONE); RNA_def_property_int_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1598,12 +1801,13 @@ PropertyRNA *RNA_def_int(StructRNA *srna, const char *identifier, int default_va return prop; } -PropertyRNA *RNA_def_int_vector(StructRNA *srna, const char *identifier, int len, const int *default_value, +PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_INT, PROP_VECTOR); + prop= RNA_def_property(cont, identifier, PROP_INT, PROP_VECTOR); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_int_array_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -1613,12 +1817,13 @@ PropertyRNA *RNA_def_int_vector(StructRNA *srna, const char *identifier, int len return prop; } -PropertyRNA *RNA_def_int_array(StructRNA *srna, const char *identifier, int len, const int *default_value, +PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_INT, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_INT, PROP_NONE); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_int_array_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -1628,12 +1833,13 @@ PropertyRNA *RNA_def_int_array(StructRNA *srna, const char *identifier, int len, return prop; } -PropertyRNA *RNA_def_string(StructRNA *srna, const char *identifier, const char *default_value, int maxlen, +PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_STRING, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_NONE); if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen); if(default_value) RNA_def_property_string_default(prop, default_value); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1641,12 +1847,13 @@ PropertyRNA *RNA_def_string(StructRNA *srna, const char *identifier, const char return prop; } -PropertyRNA *RNA_def_string_file_path(StructRNA *srna, const char *identifier, const char *default_value, int maxlen, +PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_STRING, PROP_FILEPATH); + prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_FILEPATH); if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen); if(default_value) RNA_def_property_string_default(prop, default_value); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1654,12 +1861,13 @@ PropertyRNA *RNA_def_string_file_path(StructRNA *srna, const char *identifier, c return prop; } -PropertyRNA *RNA_def_string_dir_path(StructRNA *srna, const char *identifier, const char *default_value, int maxlen, +PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_STRING, PROP_DIRPATH); + prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_DIRPATH); if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen); if(default_value) RNA_def_property_string_default(prop, default_value); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1667,12 +1875,13 @@ PropertyRNA *RNA_def_string_dir_path(StructRNA *srna, const char *identifier, co return prop; } -PropertyRNA *RNA_def_enum(StructRNA *srna, const char *identifier, EnumPropertyItem *items, int default_value, +PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_ENUM, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE); if(items) RNA_def_property_enum_items(prop, items); RNA_def_property_enum_default(prop, default_value); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1680,12 +1889,13 @@ PropertyRNA *RNA_def_enum(StructRNA *srna, const char *identifier, EnumPropertyI return prop; } -PropertyRNA *RNA_def_float(StructRNA *srna, const char *identifier, float default_value, +PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE); RNA_def_property_float_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1694,12 +1904,13 @@ PropertyRNA *RNA_def_float(StructRNA *srna, const char *identifier, float defaul return prop; } -PropertyRNA *RNA_def_float_vector(StructRNA *srna, const char *identifier, int len, const float *default_value, +PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_FLOAT, PROP_VECTOR); + prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_VECTOR); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_float_array_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -1709,12 +1920,13 @@ PropertyRNA *RNA_def_float_vector(StructRNA *srna, const char *identifier, int l return prop; } -PropertyRNA *RNA_def_float_color(StructRNA *srna, const char *identifier, int len, const float *default_value, +PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_FLOAT, PROP_COLOR); + prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_float_array_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -1725,12 +1937,13 @@ PropertyRNA *RNA_def_float_color(StructRNA *srna, const char *identifier, int le } -PropertyRNA *RNA_def_float_matrix(StructRNA *srna, const char *identifier, int len, const float *default_value, +PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_FLOAT, PROP_MATRIX); + prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_float_array_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -1740,12 +1953,13 @@ PropertyRNA *RNA_def_float_matrix(StructRNA *srna, const char *identifier, int l return prop; } -PropertyRNA *RNA_def_float_rotation(StructRNA *srna, const char *identifier, int len, const float *default_value, +PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_FLOAT, PROP_ROTATION); + prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_ROTATION); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_float_array_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -1755,12 +1969,13 @@ PropertyRNA *RNA_def_float_rotation(StructRNA *srna, const char *identifier, int return prop; } -PropertyRNA *RNA_def_float_array(StructRNA *srna, const char *identifier, int len, const float *default_value, +PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE); if(len != 0) RNA_def_property_array(prop, len); if(default_value) RNA_def_property_float_array_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -1770,12 +1985,13 @@ PropertyRNA *RNA_def_float_array(StructRNA *srna, const char *identifier, int le return prop; } -PropertyRNA *RNA_def_float_percentage(StructRNA *srna, const char *identifier, float default_value, +PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -1784,27 +2000,190 @@ PropertyRNA *RNA_def_float_percentage(StructRNA *srna, const char *identifier, f return prop; } -PropertyRNA *RNA_def_pointer_runtime(StructRNA *srna, const char *identifier, StructRNA *type, +PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, + const char *ui_name, const char *ui_description) +{ + ContainerRNA *cont= cont_; + PropertyRNA *prop; + + prop= RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, type); + RNA_def_property_ui_text(prop, ui_name, ui_description); + + return prop; +} + +PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_POINTER, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE); RNA_def_property_struct_runtime(prop, type); RNA_def_property_ui_text(prop, ui_name, ui_description); return prop; } -PropertyRNA *RNA_def_collection_runtime(StructRNA *srna, const char *identifier, StructRNA *type, +PropertyRNA *RNA_def_collection(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description) { + ContainerRNA *cont= cont_; PropertyRNA *prop; - prop= RNA_def_property(srna, identifier, PROP_COLLECTION, PROP_NONE); + prop= RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, type); + RNA_def_property_ui_text(prop, ui_name, ui_description); + + return prop; +} + +PropertyRNA *RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, + const char *ui_name, const char *ui_description) +{ + ContainerRNA *cont= cont_; + PropertyRNA *prop; + + prop= RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_runtime(prop, type); RNA_def_property_ui_text(prop, ui_name, ui_description); return prop; } +/* Function */ + +static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier) +{ + FunctionRNA *func; + StructDefRNA *dsrna; + FunctionDefRNA *dfunc; + + if(DefRNA.preprocess) { + char error[512]; + + if (rna_validate_identifier(identifier, error, 0) == 0) { + fprintf(stderr, "RNA_def_function: function identifier \"%s\" - %s\n", identifier, error); + DefRNA.error= 1; + } + } + + func= MEM_callocN(sizeof(FunctionRNA), "FunctionRNA"); + func->identifier= identifier; + func->description= identifier; + + rna_addtail(&srna->functions, func); + + if(DefRNA.preprocess) { + dsrna= rna_find_struct_def(srna); + dfunc= MEM_callocN(sizeof(FunctionDefRNA), "FunctionDefRNA"); + rna_addtail(&dsrna->functions, dfunc); + dfunc->func= func; + } + else + func->flag|= FUNC_RUNTIME; + + return func; +} + +FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call) +{ + FunctionRNA *func; + FunctionDefRNA *dfunc; + + func= rna_def_function(srna, identifier); + + if(!DefRNA.preprocess) { + fprintf(stderr, "RNA_def_function: only at preprocess time.\n"); + return func; + } + + dfunc= rna_find_function_def(func); + dfunc->call= call; + + return func; +} + +FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc call) +{ + FunctionRNA *func; + + func= rna_def_function(srna, identifier); + + if(DefRNA.preprocess) { + fprintf(stderr, "RNA_def_function_call_runtime: only at runtime.\n"); + return func; + } + + func->call= call; + + + return func; +} + +void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret) +{ + func->ret= ret; +} + +void RNA_def_function_flag(FunctionRNA *func, int flag) +{ + func->flag|= flag; +} + +void RNA_def_function_ui_description(FunctionRNA *func, const char *description) +{ + func->description= description; +} + +int rna_parameter_size(PropertyRNA *parm) +{ + PropertyType ptype= parm->type; + int len= parm->arraylength; + + if(len > 0) { + switch (ptype) { + case PROP_BOOLEAN: + case PROP_INT: + return sizeof(int)*len; + case PROP_FLOAT: + return sizeof(float)*len; + default: + break; + } + } + else { + switch (ptype) { + case PROP_BOOLEAN: + case PROP_INT: + case PROP_ENUM: + return sizeof(int); + case PROP_FLOAT: + return sizeof(float); + case PROP_STRING: + return sizeof(char *); + case PROP_POINTER: { + PointerPropertyRNA *pprop= (PointerPropertyRNA*)parm; + +#ifdef RNA_RUNTIME + if(pprop->type == &RNA_AnyType) + return sizeof(PointerRNA); + else + return sizeof(void *); +#else + if(strcmp((char*)pprop->type, "AnyType") == 0) + return sizeof(PointerRNA); + else + return sizeof(void *); +#endif + } + case PROP_COLLECTION: + /* XXX does not work yet */ + return sizeof(ListBase); + } + } + + return sizeof(void *); +} + diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 4101291e825..572c8b2ae14 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -34,10 +34,25 @@ struct SDNA; /* Data structures used during define */ +typedef struct ContainerDefRNA { + void *next, *prev; + + ContainerRNA *cont; + ListBase properties; +} ContainerDefRNA; + +typedef struct FunctionDefRNA { + ContainerDefRNA cont; + + FunctionRNA *func; + const char *srna; + const char *call; +} FunctionDefRNA; + typedef struct PropertyDefRNA { struct PropertyDefRNA *next, *prev; - struct StructRNA *srna; + struct ContainerRNA *cont; struct PropertyRNA *prop; /* struct */ @@ -61,7 +76,7 @@ typedef struct PropertyDefRNA { } PropertyDefRNA; typedef struct StructDefRNA { - struct StructDefRNA *next, *prev; + ContainerDefRNA cont; struct StructRNA *srna; const char *filename; @@ -72,7 +87,7 @@ typedef struct StructDefRNA { const char *dnafromname; const char *dnafromprop; - ListBase properties; + ListBase functions; } StructDefRNA; typedef struct AllocDefRNA { @@ -221,10 +236,18 @@ void rna_addtail(struct ListBase *listbase, void *vlink); void rna_freelinkN(struct ListBase *listbase, void *vlink); void rna_freelistN(struct ListBase *listbase); +StructDefRNA *rna_find_struct_def(StructRNA *srna); +FunctionDefRNA *rna_find_function_def(FunctionRNA *func); +PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm); + /* Pointer Handling */ PointerRNA rna_pointer_inherit_refine(struct PointerRNA *ptr, struct StructRNA *type, void *data); +/* Functions */ + +int rna_parameter_size(struct PropertyRNA *parm); + #endif /* RNA_INTERNAL_H */ diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index bc0c2a07b35..5e44b7f7452 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -28,6 +28,7 @@ #include "DNA_listBase.h" struct BlenderRNA; +struct ContainerRNA; struct StructRNA; struct PropertyRNA; struct PointerRNA; @@ -72,6 +73,40 @@ typedef int (*PropCollectionLengthFunc)(struct PointerRNA *ptr); typedef PointerRNA (*PropCollectionLookupIntFunc)(struct PointerRNA *ptr, int key); typedef PointerRNA (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, const char *key); +/* Container - generic abstracted container of RNA properties */ +typedef struct ContainerRNA { + void *next, *prev; + + ListBase properties; +} ContainerRNA; + +struct ParameterList { + /* storage for parameters */ + void *data; + + /* function passed at creation time */ + FunctionRNA *func; +}; + +struct FunctionRNA { + /* structs are containers of properties */ + ContainerRNA cont; + + /* unique identifier */ + const char *identifier; + /* various options */ + int flag; + + /* single line description, displayed in the tooltip for example */ + const char *description; + + /* callback to execute the function */ + CallFunc call; + + /* parameter for the return value */ + PropertyRNA *ret; +}; + struct PropertyRNA { struct PropertyRNA *next, *prev; @@ -207,7 +242,8 @@ typedef struct CollectionPropertyRNA { /* changes to this struct require updating rna_generate_struct in makesrna.c */ struct StructRNA { - struct StructRNA *next, *prev; + /* structs are containers of properties */ + ContainerRNA cont; /* python type, this is a subtype of pyrna_struct_Type but used so each struct can have its own type * which is useful for subclassing RNA */ @@ -244,8 +280,8 @@ struct StructRNA { /* function to find path to this struct in an ID */ StructPathFunc path; - /* properties of this struct */ - ListBase properties; + /* functions of this struct */ + ListBase functions; }; /* Blender RNA diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index f2e3f27edad..ae0a44f9ac2 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -87,11 +87,12 @@ static int rna_idproperty_known(CollectionPropertyIterator *iter, void *data) { IDProperty *idprop= (IDProperty*)data; PropertyRNA *prop; + StructRNA *ptype= iter->parent.type; /* function to skip any id properties that are already known by RNA, * for the second loop where we go over unknown id properties */ - for(prop= iter->parent.type->properties.first; prop; prop=prop->next) + for(prop= ptype->cont.properties.first; prop; prop=prop->next) if(strcmp(prop->identifier, idprop->name) == 0) return 1; @@ -107,7 +108,16 @@ static int rna_property_builtin(CollectionPropertyIterator *iter, void *data) return (prop->flag & PROP_BUILTIN); } -static void rna_inheritance_next_level_restart(CollectionPropertyIterator *iter, IteratorSkipFunc skip) +static int rna_function_builtin(CollectionPropertyIterator *iter, void *data) +{ + FunctionRNA *func= (FunctionRNA*)data; + + /* function to skip builtin rna functions */ + + return (func->flag & FUNC_BUILTIN); +} + +static void rna_inheritance_next_level_restart(CollectionPropertyIterator *iter, IteratorSkipFunc skip, int funcs) { /* RNA struct inheritance */ while(!iter->valid && iter->level > 0) { @@ -120,20 +130,36 @@ static void rna_inheritance_next_level_restart(CollectionPropertyIterator *iter, srna= srna->base; rna_iterator_listbase_end(iter); - rna_iterator_listbase_begin(iter, &srna->properties, skip); + + if (funcs) + rna_iterator_listbase_begin(iter, &srna->functions, skip); + else + rna_iterator_listbase_begin(iter, &srna->cont.properties, skip); } } -static void rna_inheritance_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip) +static void rna_inheritance_properties_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip) +{ + rna_iterator_listbase_begin(iter, lb, skip); + rna_inheritance_next_level_restart(iter, skip, 0); +} + +static void rna_inheritance_properties_listbase_next(CollectionPropertyIterator *iter, IteratorSkipFunc skip) +{ + rna_iterator_listbase_next(iter); + rna_inheritance_next_level_restart(iter, skip, 0); +} + +static void rna_inheritance_functions_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip) { rna_iterator_listbase_begin(iter, lb, skip); - rna_inheritance_next_level_restart(iter, skip); + rna_inheritance_next_level_restart(iter, skip, 1); } -static void rna_inheritance_listbase_next(CollectionPropertyIterator *iter, IteratorSkipFunc skip) +static void rna_inheritance_functions_listbase_next(CollectionPropertyIterator *iter, IteratorSkipFunc skip) { rna_iterator_listbase_next(iter); - rna_inheritance_next_level_restart(iter, skip); + rna_inheritance_next_level_restart(iter, skip, 1); } static void rna_Struct_properties_next(CollectionPropertyIterator *iter) @@ -147,7 +173,7 @@ static void rna_Struct_properties_next(CollectionPropertyIterator *iter) } else { /* regular properties */ - rna_inheritance_listbase_next(iter, rna_property_builtin); + rna_inheritance_properties_listbase_next(iter, rna_property_builtin); /* try id properties */ if(!iter->valid) { @@ -175,7 +201,7 @@ static void rna_Struct_properties_begin(CollectionPropertyIterator *iter, Pointe srna= srna->base; } - rna_inheritance_listbase_begin(iter, &srna->properties, rna_property_builtin); + rna_inheritance_properties_listbase_begin(iter, &srna->cont.properties, rna_property_builtin); } static PointerRNA rna_Struct_properties_get(CollectionPropertyIterator *iter) @@ -187,6 +213,35 @@ static PointerRNA rna_Struct_properties_get(CollectionPropertyIterator *iter) return rna_pointer_inherit_refine(&iter->parent, &RNA_Property, internal->link); } +static void rna_Struct_functions_next(CollectionPropertyIterator *iter) +{ + rna_inheritance_functions_listbase_next(iter, rna_function_builtin); +} + +static void rna_Struct_functions_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + StructRNA *srna; + + /* here ptr->data should always be the same as iter->parent.type */ + srna= (StructRNA *)ptr->data; + + while(srna->base) { + iter->level++; + srna= srna->base; + } + + rna_inheritance_functions_listbase_begin(iter, &srna->functions, rna_function_builtin); +} + +static PointerRNA rna_Struct_functions_get(CollectionPropertyIterator *iter) +{ + ListBaseIterator *internal= iter->internal; + + /* we return either PropertyRNA* or IDProperty*, the rna_access.c + * functions can handle both as PropertyRNA* with some tricks */ + return rna_pointer_inherit_refine(&iter->parent, &RNA_Function, internal->link); +} + /* Builtin properties iterator re-uses the Struct properties iterator, only * difference is that we need to see the ptr data to the type of the struct * whose properties we want to iterate over. */ @@ -447,6 +502,33 @@ static PointerRNA rna_CollectionProperty_fixed_type_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((CollectionPropertyRNA*)prop)->type); } +/* Function */ + +static void rna_Function_identifier_get(PointerRNA *ptr, char *value) +{ + strcpy(value, ((FunctionRNA*)ptr->data)->identifier); +} + +static int rna_Function_identifier_length(PointerRNA *ptr) +{ + return strlen(((FunctionRNA*)ptr->data)->identifier); +} + +static void rna_Function_description_get(PointerRNA *ptr, char *value) +{ + strcpy(value, ((FunctionRNA*)ptr->data)->description); +} + +static int rna_Function_description_length(PointerRNA *ptr) +{ + return strlen(((FunctionRNA*)ptr->data)->description); +} + +static void rna_Function_parameters_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + rna_iterator_listbase_begin(iter, &((FunctionRNA*)ptr->data)->cont.properties, rna_property_builtin); +} + /* Blender RNA */ static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) @@ -503,6 +585,12 @@ static void rna_def_struct(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Property"); RNA_def_property_collection_funcs(prop, "rna_Struct_properties_begin", "rna_Struct_properties_next", "rna_iterator_listbase_end", "rna_Struct_properties_get", 0, 0, 0); RNA_def_property_ui_text(prop, "Properties", "Properties in the struct."); + + prop= RNA_def_property(srna, "functions", PROP_COLLECTION, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "Function"); + RNA_def_property_collection_funcs(prop, "rna_Struct_functions_begin", "rna_Struct_functions_next", "rna_iterator_listbase_end", "rna_Struct_functions_get", 0, 0, 0); + RNA_def_property_ui_text(prop, "Functions", ""); } static void rna_def_property(BlenderRNA *brna) @@ -569,6 +657,32 @@ static void rna_def_property(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Editable", "Property is editable through RNA."); } +static void rna_def_function(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "Function", NULL); + RNA_def_struct_ui_text(srna, "Function Definition", "RNA function definition"); + + prop= RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_string_funcs(prop, "rna_Function_identifier_get", "rna_Function_identifier_length", NULL); + RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting."); + RNA_def_struct_name_property(srna, prop); + + prop= RNA_def_property(srna, "description", PROP_STRING, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_string_funcs(prop, "rna_Function_description_get", "rna_Function_description_length", NULL); + RNA_def_property_ui_text(prop, "Description", "Description of the Function's purpose."); + + prop= RNA_def_property(srna, "parameters", PROP_COLLECTION, PROP_NONE); + /*RNA_def_property_clear_flag(prop, PROP_EDITABLE);*/ + RNA_def_property_struct_type(prop, "Property"); + RNA_def_property_collection_funcs(prop, "rna_Function_parameters_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0); + RNA_def_property_ui_text(prop, "Parameters", "Parameters for the function."); +} + static void rna_def_number_property(StructRNA *srna, PropertyType type) { PropertyRNA *prop; @@ -718,6 +832,9 @@ void RNA_def_rna(BlenderRNA *brna) srna= RNA_def_struct(brna, "CollectionProperty", "Property"); RNA_def_struct_ui_text(srna, "Collection Definition", "RNA collection property to define lists, arrays and mappings."); rna_def_pointer_property(srna, PROP_COLLECTION); + + /* Function */ + rna_def_function(brna); /* Blender RNA */ srna= RNA_def_struct(brna, "BlenderRNA", NULL); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 20ca134c67e..b30616ba035 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -24,6 +24,7 @@ #include "bpy_rna.h" #include "bpy_compat.h" +#include "bpy_util.h" //#include "blendef.h" #include "BLI_dynstr.h" #include "BLI_listbase.h" @@ -45,6 +46,11 @@ static int pyrna_prop_compare( BPy_PropertyRNA * a, BPy_PropertyRNA * b ) return (a->prop==b->prop && a->ptr.data==b->ptr.data ) ? 0 : -1; } +static int pyrna_func_compare( BPy_FunctionRNA * a, BPy_FunctionRNA * b ) +{ + return (a->func==b->func && a->ptr.data==b->ptr.data ) ? 0 : -1; +} + /* For some reason python3 needs these :/ */ static PyObject *pyrna_struct_richcmp(BPy_StructRNA * a, BPy_StructRNA * b, int op) @@ -67,6 +73,16 @@ static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, in return Py_CmpToRich(op, cmp_result); } +static PyObject *pyrna_func_richcmp(BPy_FunctionRNA * a, BPy_FunctionRNA * b, int op) +{ + int cmp_result= -1; /* assume false */ + if (BPy_FunctionRNA_Check(a) && BPy_FunctionRNA_Check(b)) { + cmp_result= pyrna_func_compare(a, b); + } + + return Py_CmpToRich(op, cmp_result); +} + /*----------------------repr--------------------------------------------*/ static PyObject *pyrna_struct_repr( BPy_StructRNA * self ) { @@ -105,6 +121,11 @@ static PyObject *pyrna_prop_repr( BPy_PropertyRNA * self ) return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(&self->ptr), RNA_property_identifier(&self->ptr, self->prop)); } +static PyObject *pyrna_func_repr( BPy_FunctionRNA * self ) +{ + return PyUnicode_FromFormat( "[BPy_FunctionRNA \"%s\"]", RNA_function_identifier(&self->ptr, self->func)); +} + static long pyrna_struct_hash( BPy_StructRNA * self ) { return (long)self->ptr.data; @@ -124,13 +145,22 @@ static void pyrna_struct_dealloc( BPy_StructRNA * self ) return; } +/* use our own dealloc so we can free a property if we use one */ +static void pyrna_function_dealloc( BPy_FunctionRNA * self ) +{ + if (Py_TYPE(self)->tp_free) + Py_TYPE(self)->tp_free(self); + + return; +} + static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) { const EnumPropertyItem *item; - int totitem, i; + int totitem; RNA_property_enum_items(ptr, prop, &item, &totitem); - return BPy_enum_as_string(item); + return (char*)BPy_enum_as_string((EnumPropertyItem*)item); } PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) @@ -201,6 +231,10 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) return ret; } +PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) +{ + return pyrna_func_CreatePyObject(ptr, func); +} int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) { @@ -401,7 +435,6 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) return 0; } - static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int index) { PyObject *ret; @@ -661,6 +694,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) char *name = _PyUnicode_AsString(pyname); PyObject *ret; PropertyRNA *prop; + FunctionRNA *func; /* Include this incase this instance is a subtype of a python class * In these instances we may want to return a function or variable provided by the subtype @@ -671,13 +705,14 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) if (ret) return ret; else PyErr_Clear(); /* done with subtypes */ - - prop = RNA_struct_find_property(&self->ptr, name); - if (prop) { - ret = pyrna_prop_to_py(&self->ptr, prop); + if ((prop = RNA_struct_find_property(&self->ptr, name))) { + ret = pyrna_prop_to_py(&self->ptr, prop); + } + else if ((func = RNA_struct_find_function(&self->ptr, name))) { + ret = pyrna_func_to_py(&self->ptr, func); } - else if (/*self->ptr.type == &RNA_Context*/0) { + else if (self->ptr.type == &RNA_Context) { PointerRNA newptr; ListBase newlb; @@ -918,6 +953,393 @@ static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *k } } +/* only needed for subtyping, so a new class gets a valid BPy_FunctionRNA +* todo - also accept useful args */ +static PyObject * pyrna_func_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + + BPy_FunctionRNA *base = NULL; + + if (!PyArg_ParseTuple(args, "O!:Base BPy_FunctionRNA", &pyrna_func_Type, &base)) + return NULL; + + if (type == &pyrna_func_Type) { + return pyrna_func_CreatePyObject(&base->ptr, base->func); + } else { + BPy_FunctionRNA *ret = (BPy_FunctionRNA *) type->tp_alloc(type, 0); + ret->ptr = base->ptr; + ret->func = base->func; + return (PyObject *)ret; + } +} + +int pyrna_py_to_param(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value) +{ + /* XXX hard limits should be checked here */ + int type = RNA_property_type(ptr, prop); + int len = RNA_property_array_length(ptr, prop); + + if (len > 0) { + PyObject *item; + int i; + + if (!PySequence_Check(value)) { + PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array."); + return -1; + } + + if ((int)PySequence_Length(value) != len) { + PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array."); + return -1; + } + + /* for arrays we have a limited number of types */ + switch (type) { + case PROP_BOOLEAN: + { + int *param_arr = (int*)data; + + /* collect the variables before assigning, incase one of them is incorrect */ + for (i=0; i<len; i++) { + item = PySequence_GetItem(value, i); + param_arr[i] = PyObject_IsTrue( item ); + Py_DECREF(item); + + if (param_arr[i] < 0) { + PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence is not a boolean"); + return -1; + } + } + + break; + } + case PROP_INT: + { + int *param_arr = (int*)data; + + /* collect the variables */ + for (i=0; i<len; i++) { + item = PySequence_GetItem(value, i); + param_arr[i] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */ + Py_DECREF(item); + } + + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as an int"); + return -1; + } + + break; + } + case PROP_FLOAT: + { + float *param_arr = (float*)data; + + /* collect the variables */ + for (i=0; i<len; i++) { + item = PySequence_GetItem(value, i); + param_arr[i] = (float)PyFloat_AsDouble(item); /* deal with any errors later */ + Py_DECREF(item); + } + + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as a float"); + return -1; + } + + break; + } + } + } else { + /* Normal Property (not an array) */ + + /* see if we can coorce into a python type - PropertyType */ + switch (type) { + case PROP_BOOLEAN: + { + int param = PyObject_IsTrue( value ); + + if( param < 0 ) { + PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1"); + return -1; + } else { + *((int*)data)= param; + } + break; + } + case PROP_INT: + { + int param = PyLong_AsSsize_t(value); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "expected an int type"); + return -1; + } else { + *((int*)data)= param; + } + break; + } + case PROP_FLOAT: + { + float param = PyFloat_AsDouble(value); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "expected a float type"); + return -1; + } else { + *((float*)data)= param; + } + break; + } + case PROP_STRING: + { + char *param = _PyUnicode_AsString(value); + + if (param==NULL) { + PyErr_SetString(PyExc_TypeError, "expected a string type"); + return -1; + } else { + *((char**)data)= param; + } + break; + } + case PROP_ENUM: + { + char *param = _PyUnicode_AsString(value); + + if (param==NULL) { + char *enum_str= pyrna_enum_as_string(ptr, prop); + PyErr_Format(PyExc_TypeError, "expected a string enum type in (%s)", enum_str); + MEM_freeN(enum_str); + return -1; + } else { + int val; + if (RNA_property_enum_value(ptr, prop, param, &val)) { + *((int*)data)= val; + } else { + char *enum_str= pyrna_enum_as_string(ptr, prop); + PyErr_Format(PyExc_AttributeError, "enum \"%s\" not found in (%s)", param, enum_str); + MEM_freeN(enum_str); + return -1; + } + } + + break; + } + case PROP_POINTER: + { + StructRNA *ptype= RNA_property_pointer_type(ptr, prop); + + if(!BPy_StructRNA_Check(value)) { + PointerRNA tmp; + RNA_pointer_create(NULL, ptype, NULL, &tmp); + PyErr_Format(PyExc_TypeError, "expected a %s type", RNA_struct_identifier(&tmp)); + return -1; + } else { + BPy_StructRNA *param= (BPy_StructRNA*)value; + + if(ptype == &RNA_AnyType) { + *((PointerRNA*)data)= param->ptr; + } + else if(RNA_struct_is_a(¶m->ptr, ptype)) { + *((void**)data)= param->ptr.data; + } else { + PointerRNA tmp; + RNA_pointer_create(NULL, ptype, NULL, &tmp); + PyErr_Format(PyExc_TypeError, "expected a %s type", RNA_struct_identifier(&tmp)); + return -1; + } + } + break; + } + case PROP_COLLECTION: + PyErr_SetString(PyExc_AttributeError, "cant pass collections yet"); + return -1; + break; + default: + PyErr_SetString(PyExc_AttributeError, "unknown property type (pyrna_py_to_param)"); + return -1; + break; + } + } + + return 0; +} + +PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) +{ + PyObject *ret; + int type = RNA_property_type(ptr, prop); + int len = RNA_property_array_length(ptr, prop); + int a; + + if(len > 0) { + /* resolve the array from a new pytype */ + ret = PyTuple_New(len); + + switch (type) { + case PROP_BOOLEAN: + for(a=0; a<len; a++) + PyTuple_SET_ITEM(ret, a, PyBool_FromLong( ((int*)data)[a] )); + break; + case PROP_INT: + for(a=0; a<len; a++) + PyTuple_SET_ITEM(ret, a, PyLong_FromSsize_t( (Py_ssize_t)((int*)data)[a] )); + break; + case PROP_FLOAT: + for(a=0; a<len; a++) + PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble( ((float*)data)[a] )); + break; + default: + PyErr_Format(PyExc_AttributeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type); + ret = NULL; + break; + } + } + else { + /* see if we can coorce into a python type - PropertyType */ + switch (type) { + case PROP_BOOLEAN: + ret = PyBool_FromLong( *(int*)data ); + break; + case PROP_INT: + ret = PyLong_FromSsize_t( (Py_ssize_t)*(int*)data ); + break; + case PROP_FLOAT: + ret = PyFloat_FromDouble( *(float*)data ); + break; + case PROP_STRING: + { + ret = PyUnicode_FromString( *(char**)data ); + break; + } + case PROP_ENUM: + { + const char *identifier; + int val = *(int*)data; + + if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) { + ret = PyUnicode_FromString( identifier ); + } else { + PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val); + ret = NULL; + } + + break; + } + case PROP_POINTER: + { + PointerRNA newptr; + StructRNA *type= RNA_property_pointer_type(ptr, prop); + + if(type == &RNA_AnyType) { + /* in this case we get the full ptr */ + newptr= *(PointerRNA*)data; + } + else { + /* XXX this is missing the ID part! */ + RNA_pointer_create(NULL, type, *(void**)data, &newptr); + } + + if (newptr.data) { + ret = pyrna_struct_CreatePyObject(&newptr); + } else { + ret = Py_None; + Py_INCREF(ret); + } + break; + } + case PROP_COLLECTION: + /* XXX not supported yet + * ret = pyrna_prop_CreatePyObject(ptr, prop); */ + break; + default: + PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type); + ret = NULL; + break; + } + } + + return ret; +} + +static PyObject * pyrna_func_call(BPy_FunctionRNA * self, PyObject *args, PyObject *kw) +{ + PointerRNA funcptr; + ParameterList *parms; + ParameterIterator iter; + PropertyRNA *pret, *parm; + PyObject *ret, *item; + int i, tlen, err= 0; + const char *tid, *fid, *pid; + void *retdata= NULL; + + /* setup */ + RNA_pointer_create(NULL, &RNA_Function, self->func, &funcptr); + + pret= RNA_function_return(&self->ptr, self->func); + tlen= PyTuple_GET_SIZE(args); + + parms= RNA_parameter_list_create(&self->ptr, self->func); + RNA_parameter_list_begin(parms, &iter); + + /* parse function parameters */ + for (i= 0; iter.valid; RNA_parameter_list_next(&iter), i++) { + parm= iter.parm; + + if (parm==pret) { + retdata= iter.data; + continue; + } + + pid= RNA_property_identifier(&funcptr, parm); + item= NULL; + + if (i < tlen) + item= PyTuple_GET_ITEM(args, i); + + if (kw != NULL) + item= PyDict_GetItemString(kw, pid); + + if (item==NULL) { + /* XXX need to add flag for optional required parameters + if (flag & PARAM_OPTIONAL) + continue; */ + + tid= RNA_struct_identifier(&self->ptr); + fid= RNA_function_identifier(&self->ptr, self->func); + + PyErr_Format(PyExc_AttributeError, "%s.%s(): required parameter \"%s\" not specified", tid, fid, pid); + err= -1; + break; + } + + err= pyrna_py_to_param(&funcptr, parm, iter.data, item); + + if(err!=0) + break; + } + + ret= NULL; + if (err==0) { + /* call function */ + RNA_function_call(&self->ptr, self->func, parms); + + /* return value */ + if(pret) + ret= pyrna_param_to_py(&funcptr, pret, retdata); + } + + /* cleanup */ + RNA_parameter_list_end(&iter); + RNA_parameter_list_free(parms); + + if (ret) + return ret; + + if (err==-1) + return NULL; + + Py_RETURN_NONE; +} + /*-----------------------BPy_StructRNA method def------------------------------*/ PyTypeObject pyrna_struct_Type = { #if (PY_VERSION_HEX >= 0x02060000) @@ -1089,6 +1511,92 @@ PyTypeObject pyrna_prop_Type = { NULL }; +/*-----------------------BPy_FunctionRNA method def------------------------------*/ +PyTypeObject pyrna_func_Type = { +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif + + "FunctionRNA", /* tp_name */ + sizeof( BPy_FunctionRNA ), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + ( destructor ) pyrna_function_dealloc, /* tp_dealloc */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + ( cmpfunc ) pyrna_func_compare, /* tp_compare */ + ( reprfunc ) pyrna_func_repr, /* tp_repr */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + NULL, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + (ternaryfunc)pyrna_func_call, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /*PyObject_GenericGetAttr - MINGW Complains, assign later */ /* getattrofunc tp_getattro; */ /* will only use these if this is a subtype of a py class */ + NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */ /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + (richcmpfunc)pyrna_func_richcmp, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + (getiterfunc)NULL, /* getiterfunc tp_iter; */ + NULL, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + NULL, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + NULL, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + pyrna_func_new, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + PyObject* pyrna_struct_Subtype(PointerRNA *ptr) { PyObject *newclass = NULL; @@ -1096,12 +1604,12 @@ PyObject* pyrna_struct_Subtype(PointerRNA *ptr) if (ptr->type==NULL) { newclass= NULL; /* Nothing to do */ - } else if ((newclass= (PyObject *)BPy_RNA_PYTYPE(ptr->data))) { + } else if ((newclass= RNA_struct_py_type_get(ptr->data))) { Py_INCREF(newclass); } else if ((nameprop = RNA_struct_name_property(ptr))) { /* for now, return the base RNA type rather then a real module */ - /* Assume BPy_RNA_PYTYPE(ptr->data) was alredy checked */ + /* Assume RNA_struct_py_type_get(ptr->data) was alredy checked */ /* subclass equivelents - class myClass(myBase): @@ -1140,7 +1648,7 @@ PyObject* pyrna_struct_Subtype(PointerRNA *ptr) if (newclass) { PyObject *rna; - BPy_RNA_PYTYPE(ptr->data) = (void *)newclass; /* Store for later use */ + RNA_struct_py_type_set(ptr->data, (void *)newclass); /* Store for later use */ /* Not 100% needed but useful, * having an instance within a type looks wrong however this instance IS an rna type */ @@ -1152,9 +1660,8 @@ PyObject* pyrna_struct_Subtype(PointerRNA *ptr) Py_DECREF(args); - if ((char *)&name != nameptr) + if (name != nameptr) MEM_freeN(nameptr); - } return newclass; @@ -1211,6 +1718,25 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop ) return ( PyObject * ) pyrna; } +PyObject *pyrna_func_CreatePyObject( PointerRNA *ptr, FunctionRNA *func ) +{ + BPy_FunctionRNA *pyrna; + + pyrna = ( BPy_FunctionRNA * ) PyObject_NEW( BPy_FunctionRNA, &pyrna_func_Type ); + + if( !pyrna ) { + PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_FunctionRNA object" ); + return NULL; + } + + pyrna->ptr = *ptr; + pyrna->func = func; + + /* TODO - iterator? */ + + return ( PyObject * ) pyrna; +} + PyObject *BPY_rna_module( void ) { @@ -1226,6 +1752,8 @@ PyObject *BPY_rna_module( void ) if( PyType_Ready( &pyrna_prop_Type ) < 0 ) return NULL; + if( PyType_Ready( &pyrna_func_Type ) < 0 ) + return NULL; /* for now, return the base RNA type rather then a real module */ RNA_main_pointer_create(G.main, &ptr); @@ -1291,7 +1819,7 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) return list; } -PyTypeObject pyrna_basetype_Type = {NULL}; +PyTypeObject pyrna_basetype_Type = {}; PyObject *BPY_rna_types(void) { diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 878b2a7d17a..059eedb4020 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -32,15 +32,14 @@ extern PyTypeObject pyrna_struct_Type; extern PyTypeObject pyrna_prop_Type; +extern PyTypeObject pyrna_func_Type; #define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type)) #define BPy_StructRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_struct_Type) #define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type)) #define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type) - - //XXX add propper accessor function, we know this is just after next/prev pointers - - #define BPy_RNA_PYTYPE( _data ) (((BPy_StructFakeType *)(_data))->py_type) +#define BPy_FunctionRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_func_Type)) +#define BPy_FunctionRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_func_Type) typedef struct { void * _a; @@ -61,6 +60,12 @@ typedef struct { PropertyRNA *prop; } BPy_PropertyRNA; +typedef struct { + PyObject_HEAD /* required python macro */ + PointerRNA ptr; + FunctionRNA *func; +} BPy_FunctionRNA; + /* cheap trick */ #define BPy_BaseTypeRNA BPy_PropertyRNA @@ -70,11 +75,14 @@ PyObject *BPY_rna_types( void ); PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr ); PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop ); +PyObject *pyrna_func_CreatePyObject( PointerRNA *ptr, FunctionRNA *func ); /* operators also need this to set args */ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value); PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop); +PyObject *pyrna_func_to_py( PointerRNA *ptr, FunctionRNA *func ); + /* 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); |