From 4bd3163ea6399311d33f1c6c280d0d23c3a4e370 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 24 Apr 2010 19:26:05 +0000 Subject: [PATCH] py api: fix for context returning None for an empty list such as 'context.selected_objects', now returns [] --- source/blender/blenkernel/BKE_context.h | 11 +++++- source/blender/blenkernel/intern/context.c | 15 +++++++- .../blender/editors/screen/screen_context.c | 14 +++---- .../blender/editors/space_node/space_node.c | 1 + .../editors/space_view3d/space_view3d.c | 8 ++-- source/blender/python/intern/bpy_rna.c | 37 ++++++++++--------- 6 files changed, 55 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 48e2dbf4fec..f6d41190c5a 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -170,11 +170,17 @@ void CTX_wm_menu_set(bContext *C, struct ARegion *menu); freed with BLI_freelistN! - the dir listbase consits of LinkData items */ +/* data type, needed so we can tell between a NULL pointer and an empty list */ +enum { + CTX_DATA_TYPE_POINTER = 0, + CTX_DATA_TYPE_COLLECTION +}; + PointerRNA CTX_data_pointer_get(const bContext *C, const char *member); PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type); ListBase CTX_data_collection_get(const bContext *C, const char *member); ListBase CTX_data_dir_get(const bContext *C); -int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb); +int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type); void CTX_data_id_pointer_set(bContextDataResult *result, struct ID *id); void CTX_data_pointer_set(bContextDataResult *result, struct ID *id, StructRNA *type, void *data); @@ -184,6 +190,9 @@ void CTX_data_list_add(bContextDataResult *result, struct ID *id, StructRNA *typ void CTX_data_dir_set(bContextDataResult *result, const char **member); +void CTX_data_type_set(struct bContextDataResult *result, short type); +short CTX_data_type_get(struct bContextDataResult *result); + int CTX_data_equals(const char *member, const char *str); int CTX_data_dir(const char *member); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index e8f73a92ad5..9520df71b60 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -404,6 +404,7 @@ struct bContextDataResult { PointerRNA ptr; ListBase list; const char **dir; + short type; /* 0: normal, 1: seq */ }; static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result) @@ -548,7 +549,7 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member) } /* 1:found, -1:found but not set, 0:not found */ -int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb) +int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type) { bContextDataResult result; int ret= ctx_data_get((bContext*)C, member, &result); @@ -556,10 +557,12 @@ int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListB if(ret==1) { *r_ptr= result.ptr; *r_lb= result.list; + *r_type= result.type; } else { memset(r_ptr, 0, sizeof(*r_ptr)); memset(r_lb, 0, sizeof(*r_lb)); + *r_type= 0; } return ret; @@ -682,6 +685,16 @@ void CTX_data_dir_set(bContextDataResult *result, const char **dir) result->dir= dir; } +void CTX_data_type_set(bContextDataResult *result, short type) +{ + result->type= type; +} + +short CTX_data_type_get(bContextDataResult *result) +{ + return result->type; +} + /* data context */ Main *CTX_data_main(const bContext *C) diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 14cafc74ea5..2d5af4aa705 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -86,7 +86,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { @@ -100,7 +100,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { @@ -118,7 +118,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) { @@ -159,7 +159,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } @@ -201,7 +201,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } @@ -216,7 +216,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_list_add(result, &obact->id, &RNA_PoseBone, pchan); } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } @@ -232,7 +232,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_list_add(result, &obact->id, &RNA_PoseBone, pchan); } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index afb2ec04f55..bb568c49298 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -340,6 +340,7 @@ static int node_context(const bContext *C, const char *member, bContextDataResul CTX_data_list_add(result, &snode->edittree->id, &RNA_Node, node); } } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index bda7dfcabf1..a37ecda99ac 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -817,7 +817,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes } } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { @@ -835,7 +835,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes } } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) { @@ -851,7 +851,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes } } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) { @@ -867,7 +867,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes } } } - + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "active_base")) { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 7a0bde4fddb..fa52b86c116 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2236,28 +2236,29 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname ) else { PointerRNA newptr; ListBase newlb; + short newtype; - int done= CTX_data_get(C, name, &newptr, &newlb); + int done= CTX_data_get(C, name, &newptr, &newlb, &newtype); if(done==1) { /* found */ - if (newptr.data) { - ret = pyrna_struct_CreatePyObject(&newptr); - } - else if (newlb.first) { - CollectionPointerLink *link; - PyObject *linkptr; - - ret = PyList_New(0); - - for(link=newlb.first; link; link=link->next) { - linkptr= pyrna_struct_CreatePyObject(&link->ptr); - PyList_Append(ret, linkptr); - Py_DECREF(linkptr); + switch(newtype) { + case CTX_DATA_TYPE_POINTER: + ret = pyrna_struct_CreatePyObject(&newptr); /* can return a bpy_struct or None */ + break; + case CTX_DATA_TYPE_COLLECTION: + { + CollectionPointerLink *link; + PyObject *linkptr; + + ret = PyList_New(0); + + for(link=newlb.first; link; link=link->next) { + linkptr= pyrna_struct_CreatePyObject(&link->ptr); + PyList_Append(ret, linkptr); + Py_DECREF(linkptr); + } } - } - else { - ret = Py_None; - Py_INCREF(ret); + break; } } else if (done==-1) { /* found but not set */