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.
This commit is contained in:
parent
1f2fe7ec14
commit
7efc2c2375
|
@ -22,6 +22,17 @@ StructRNA = bpy.types.Struct.__bases__[0]
|
|||
# StructRNA = bpy.types.Struct
|
||||
|
||||
|
||||
class Context(StructRNA):
|
||||
|
||||
def copy(self):
|
||||
new_context = {}
|
||||
for item in dir(self):
|
||||
if item not in StructRNA.__dict__ and item != "id_data":
|
||||
new_context[item] = getattr(self, item)
|
||||
|
||||
return new_context
|
||||
|
||||
|
||||
class Object(bpy.types.ID):
|
||||
|
||||
def _get_children(self):
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ************************/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue