diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-11-10 18:09:53 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-11-10 18:09:53 +0300 |
commit | 7efc2c2375bb591d57f6f3d63b274de48172e43b (patch) | |
tree | 5bf49f58ed3fb4cf6be8a953645d692503afc1c5 /source | |
parent | 1f2fe7ec1409298527d757cb395358bc02d494c1 (diff) |
modify the python context access so invalid names will raise an exception rather then returning None.
this way the UI scripts are less likely to fail silently and wont let typos work ok.
also allow subclassing of the context, added a copy function,
bpy.context.copy(), returns the context as a python dict to be modified and used in python.
This also showed up an invalid brush member in the screen context.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_context.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/context.c | 53 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_context.c | 7 | ||||
-rw-r--r-- | source/blender/editors/space_buttons/buttons_context.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 6 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 46 |
6 files changed, 80 insertions, 39 deletions
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index feba39ee11d..7f64538b10d 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -174,7 +174,7 @@ 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); -void 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); 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); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 7f2872c0797..1cd0e6cd677 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -408,6 +408,7 @@ struct bContextDataResult { static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result) { int done= 0, recursion= C->data.recursion; + int ret= 0; memset(result, 0, sizeof(bContextDataResult)); @@ -417,7 +418,14 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res /* we check recursion to ensure that we do not get infinite * loops requesting data from ourselfs in a context callback */ - if(!done && recursion < 1 && C->wm.store) { + + /* Ok, this looks evil... + * if(ret) done= -(-ret | -done); + * + * Values in order of importance + * (0, -1, 1) - Where 1 is highest priority + * */ + if(done!=1 && recursion < 1 && C->wm.store) { bContextStoreEntry *entry; C->data.recursion= 1; @@ -429,21 +437,28 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res } } } - if(!done && recursion < 2 && C->wm.region) { + if(done!=1 && recursion < 2 && C->wm.region) { C->data.recursion= 2; - if(C->wm.region->type && C->wm.region->type->context) - done= C->wm.region->type->context(C, member, result); + if(C->wm.region->type && C->wm.region->type->context) { + ret = C->wm.region->type->context(C, member, result); + if(ret) done= -(-ret | -done); + + } } - if(!done && recursion < 3 && C->wm.area) { + if(done!=1 && recursion < 3 && C->wm.area) { C->data.recursion= 3; - if(C->wm.area->type && C->wm.area->type->context) - done= C->wm.area->type->context(C, member, result); + if(C->wm.area->type && C->wm.area->type->context) { + ret = C->wm.area->type->context(C, member, result); + if(ret) done= -(-ret | -done); + } } - if(!done && recursion < 4 && C->wm.screen) { + if(done!=1 && recursion < 4 && C->wm.screen) { bContextDataCallback cb= C->wm.screen->context; C->data.recursion= 4; - if(cb) - done= cb(C, member, result); + if(cb) { + ret = cb(C, member, result); + if(ret) done= -(-ret | -done); + } } C->data.recursion= recursion; @@ -455,7 +470,7 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member) { bContextDataResult result; - if(C && ctx_data_get((bContext*)C, member, &result)) + if(C && ctx_data_get((bContext*)C, member, &result)==1) return result.ptr.data; return NULL; @@ -465,7 +480,7 @@ static int ctx_data_pointer_verify(const bContext *C, const char *member, void * { bContextDataResult result; - if(ctx_data_get((bContext*)C, member, &result)) { + if(ctx_data_get((bContext*)C, member, &result)==1) { *pointer= result.ptr.data; return 1; } @@ -479,7 +494,7 @@ static int ctx_data_collection_get(const bContext *C, const char *member, ListBa { bContextDataResult result; - if(ctx_data_get((bContext*)C, member, &result)) { + if(ctx_data_get((bContext*)C, member, &result)==1) { *list= result.list; return 1; } @@ -494,7 +509,7 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member) { bContextDataResult result; - if(ctx_data_get((bContext*)C, member, &result)) + if(ctx_data_get((bContext*)C, member, &result)==1) return result.ptr; else return PointerRNA_NULL; @@ -514,7 +529,7 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member) { bContextDataResult result; - if(ctx_data_get((bContext*)C, member, &result)) { + if(ctx_data_get((bContext*)C, member, &result)==1) { return result.list; } else { @@ -524,11 +539,13 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member) } } -void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb) +/* 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) { bContextDataResult result; + int ret= ctx_data_get((bContext*)C, member, &result); - if(ctx_data_get((bContext*)C, member, &result)) { + if(ret==1) { *r_ptr= result.ptr; *r_lb= result.list; } @@ -536,6 +553,8 @@ void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, List memset(r_ptr, 0, sizeof(*r_ptr)); memset(r_lb, 0, sizeof(*r_lb)); } + + return ret; } static void data_dir_add(ListBase *lb, const char *member) diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 31827e1b9c0..1a1def70717 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -67,7 +67,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult "visible_pchans", "selected_pchans", "active_bone", "active_pchan", "active_base", "active_object", "edit_object", "sculpt_object", "vertex_paint_object", "weight_paint_object", - "texture_paint_object", "brush", "particle_edit_object", NULL}; + "texture_paint_object", "particle_edit_object", NULL}; CTX_data_dir_set(result, dir); return 1; @@ -304,7 +304,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } + else { + return 0; /* not found */ + } - return 0; + return -1; /* found but not available */ } diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 71d5b59f253..0e2769a3557 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -707,8 +707,11 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_Brush); return 1; } + else { + return 0; /* not found */ + } - return 0; + return -1; /* found but not available */ } /************************* Drawing the Path ************************/ diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 4a9042aa31c..5bde6e029e4 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -747,7 +747,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } - return 0; + else { + return 0; /* not found */ + } + + return -1; /* found but not available */ } /* only called once, from space/spacetypes.c */ diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index bcc12eb4502..c06931feedb 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1376,27 +1376,38 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) else if (self->ptr.type == &RNA_Context) { PointerRNA newptr; ListBase newlb; + int done; - CTX_data_get(self->ptr.data, name, &newptr, &newlb); + done= CTX_data_get(self->ptr.data, name, &newptr, &newlb); - if (newptr.data) { - ret = pyrna_struct_CreatePyObject(&newptr); - } - else if (newlb.first) { - CollectionPointerLink *link; - PyObject *linkptr; + if(done==1) { /* found */ + if (newptr.data) { + ret = pyrna_struct_CreatePyObject(&newptr); + } + else if (newlb.first) { + CollectionPointerLink *link; + PyObject *linkptr; - ret = PyList_New(0); + 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); + 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); } } - else { - ret = Py_None; - Py_INCREF(ret); + else if (done==-1) { /* found but not set */ + ret = Py_None; + Py_INCREF(ret); + } + else { /* not found in the context */ + /* lookup the subclass. raise an error if its not found */ + ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } BLI_freelistN(&newlb); @@ -1405,10 +1416,11 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) if(self->ptr.id.data) { PointerRNA id_ptr; RNA_id_pointer_create((ID *)self->ptr.id.data, &id_ptr); - return pyrna_struct_CreatePyObject(&id_ptr); + ret = pyrna_struct_CreatePyObject(&id_ptr); } else { - Py_RETURN_NONE; + ret = Py_None; + Py_INCREF(ret); } } else { |