merged changes to revision 24271

This commit is contained in:
Maxime Curioni
2009-11-03 09:15:21 +00:00
293 changed files with 49049 additions and 25275 deletions

View File

@@ -63,6 +63,7 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_text.h"
#include "BKE_context.h"
#include "BPY_extern.h"
@@ -202,6 +203,7 @@ static void bpy_init_modules( void )
bpy_import_test("bpy_ops"); /* adds its self to bpy.ops */
bpy_import_test("bpy_sys"); /* adds its self to bpy.sys */
bpy_import_test("bpy_ext"); /* extensions to our existing types */
}
/* stand alone utility modules not related to blender directly */
@@ -950,3 +952,65 @@ int BPY_button_eval(bContext *C, char *expr, double *value)
return error_ret;
}
int bpy_context_get(bContext *C, const char *member, bContextDataResult *result)
{
PyObject *pyctx= (PyObject *)CTX_py_dict_get(C);
PyObject *item= PyDict_GetItemString(pyctx, member);
PointerRNA *ptr= NULL;
int done= 0;
if(item==NULL) {
/* pass */
}
else if(item==Py_None) {
/* pass */
}
else if(BPy_StructRNA_Check(item)) {
ptr= &(((BPy_StructRNA *)item)->ptr);
//result->ptr= ((BPy_StructRNA *)item)->ptr;
CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data);
done= 1;
}
else if (PySequence_Check(item)) {
PyObject *seq_fast= PySequence_Fast(item, "bpy_context_get sequence conversion");
if (seq_fast==NULL) {
PyErr_Print();
PyErr_Clear();
}
else {
int len= PySequence_Fast_GET_SIZE(seq_fast);
int i;
for(i = 0; i < len; i++) {
PyObject *list_item= PySequence_Fast_GET_ITEM(seq_fast, i);
if(BPy_StructRNA_Check(list_item)) {
/*
CollectionPointerLink *link= MEM_callocN(sizeof(CollectionPointerLink), "bpy_context_get");
link->ptr= ((BPy_StructRNA *)item)->ptr;
BLI_addtail(&result->list, link);
*/
ptr= &(((BPy_StructRNA *)list_item)->ptr);
CTX_data_list_add(result, ptr->id.data, ptr->type, ptr->data);
}
else {
printf("List item not a valid type\n");
}
}
Py_DECREF(seq_fast);
done= 1;
}
}
if(done==0) {
if (item) printf("Context '%s' not found\n", member);
else printf("Context '%s' not a valid type\n", member);
}
return done;
}

View File

@@ -48,6 +48,8 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
char *opname;
PyObject *kw= NULL; /* optional args */
PyObject *context_dict= NULL; /* optional args */
PyObject *context_dict_back;
/* note that context is an int, python does the conversion in this case */
int context= WM_OP_EXEC_DEFAULT;
@@ -55,7 +57,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
// XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it...
bContext *C = BPy_GetContext();
if (!PyArg_ParseTuple(args, "s|O!i:bpy.__ops__.call", &opname, &PyDict_Type, &kw, &context))
if (!PyArg_ParseTuple(args, "sO|O!i:bpy.__ops__.call", &opname, &context_dict, &PyDict_Type, &kw, &context))
return NULL;
ot= WM_operatortype_find(opname, TRUE);
@@ -65,61 +67,74 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
return NULL;
}
if(!PyDict_Check(context_dict))
context_dict= NULL;
context_dict_back= CTX_py_dict_get(C);
CTX_py_dict_set(C, (void *)context_dict);
Py_XINCREF(context_dict); /* so we done loose it */
if(WM_operator_poll((bContext*)C, ot) == FALSE) {
PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect");
return NULL;
error_val= -1;
}
else {
/* WM_operator_properties_create(&ptr, opname); */
/* Save another lookup */
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
/* WM_operator_properties_create(&ptr, opname); */
/* Save another lookup */
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
if(kw && PyDict_Size(kw))
error_val= pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: ");
if (error_val==0) {
ReportList *reports;
reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
BKE_reports_init(reports, RPT_STORE);
WM_operator_call_py(C, ot, context, &ptr, reports);
if(BPy_reports_to_error(reports))
error_val = -1;
/* operator output is nice to have in the terminal/console too */
if(reports->list.first) {
char *report_str= BKE_reports_string(reports, 0); /* all reports */
if(kw && PyDict_Size(kw))
error_val= pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: ");
if(report_str) {
PySys_WriteStdout("%s\n", report_str);
MEM_freeN(report_str);
}
}
if (error_val==0) {
ReportList *reports;
reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
BKE_reports_init(reports, RPT_STORE);
WM_operator_call_py(C, ot, context, &ptr, reports);
if(BPy_reports_to_error(reports))
error_val = -1;
/* operator output is nice to have in the terminal/console too */
if(reports->list.first) {
char *report_str= BKE_reports_string(reports, 0); /* all reports */
if(report_str) {
PySys_WriteStdout("%s\n", report_str);
MEM_freeN(report_str);
BKE_reports_clear(reports);
if ((reports->flag & RPT_FREE) == 0)
{
MEM_freeN(reports);
}
}
BKE_reports_clear(reports);
if ((reports->flag & RPT_FREE) == 0)
{
MEM_freeN(reports);
}
}
WM_operator_properties_free(&ptr);
WM_operator_properties_free(&ptr);
#if 0
/* if there is some way to know an operator takes args we should use this */
{
/* no props */
if (kw != NULL) {
PyErr_Format(PyExc_AttributeError, "Operator \"%s\" does not take any args", opname);
return NULL;
}
/* if there is some way to know an operator takes args we should use this */
{
/* no props */
if (kw != NULL) {
PyErr_Format(PyExc_AttributeError, "Operator \"%s\" does not take any args", opname);
return NULL;
}
WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
}
WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
}
#endif
}
/* restore with original context dict, probably NULL but need this for nested operator calls */
Py_XDECREF(context_dict);
CTX_py_dict_set(C, (void *)context_dict_back);
if (error_val==-1) {
return NULL;

View File

@@ -41,13 +41,12 @@
#include "../generic/bpy_internal_import.h" // our own imports
#define PYOP_ATTR_PROP "__props__"
#define PYOP_ATTR_UINAME "__label__"
#define PYOP_ATTR_IDNAME "__idname__" /* the name given by python */
#define PYOP_ATTR_IDNAME_BL "__idname_bl__" /* our own name converted into blender syntax, users wont see this */
#define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */
#define PYOP_ATTR_REGISTER "__register__" /* True/False. if this python operator should be registered */
#define PYOP_ATTR_UNDO "__undo__" /* True/False. if this python operator should be undone */
#define PYOP_ATTR_UINAME "bl_label"
#define PYOP_ATTR_IDNAME "bl_idname" /* the name given by python */
#define PYOP_ATTR_IDNAME_BL "_bl_idname" /* our own name converted into blender syntax, users wont see this */
#define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */
#define PYOP_ATTR_REGISTER "bl_register" /* True/False. if this python operator should be registered */
#define PYOP_ATTR_UNDO "bl_undo" /* True/False. if this python operator should be undone */
static struct BPY_flag_def pyop_ret_flags[] = {
{"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
@@ -91,19 +90,23 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat
PointerRNA ptr_context;
PointerRNA ptr_operator;
PointerRNA ptr_event;
PyObject *py_operator;
PyGILState_STATE gilstate;
bpy_context_set(C, &gilstate);
args = PyTuple_New(1);
PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg
/* poll has no 'op', should be ok still */
/* use an rna instance as the first arg */
RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&ptr_operator));
py_class_instance = PyObject_Call(py_class, args, NULL);
Py_DECREF(args);
if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
PyObject *class_dict= PyObject_GetAttrString(py_class_instance, "__dict__");
/* Assign instance attributes from operator properties */
if(op) {
@@ -115,20 +118,12 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat
if (strcmp(arg_name, "rna_type")==0) continue;
item = pyrna_prop_to_py(op->ptr, prop);
PyObject_SetAttrString(py_class_instance, arg_name, item);
PyDict_SetItemString(class_dict, arg_name, item);
Py_DECREF(item);
}
RNA_STRUCT_END;
}
/* set operator pointer RNA as instance "__operator__" attribute */
if(op) {
RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
py_operator= pyrna_struct_CreatePyObject(&ptr_operator);
PyObject_SetAttrString(py_class_instance, "__operator__", py_operator);
Py_DECREF(py_operator);
}
RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
if (mode==PYOP_INVOKE) {
@@ -159,6 +154,11 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat
Py_DECREF(args);
Py_DECREF(item);
Py_DECREF(class_dict);
}
else {
PyErr_Print();
PyErr_Clear();
}
if (ret == NULL) { /* covers py_class_instance failing too */
@@ -246,7 +246,7 @@ static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot)
void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
{
PyObject *py_class = (PyObject *)userdata;
PyObject *props, *item;
PyObject *item;
/* identifiers */
item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME_BL);
@@ -300,46 +300,18 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
PyErr_Clear();
}
props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
if (props) {
PyObject *dummy_args = PyTuple_New(0);
int i;
for(i=0; i<PyList_Size(props); i++) {
PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
item = PyList_GET_ITEM(props, i);
if (PyArg_ParseTuple(item, "O!O!:PYTHON_OT_wrapper", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
py_srna_cobject = PyCObject_FromVoidPtr(ot->srna, NULL);
py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
if (py_ret) {
Py_DECREF(py_ret);
} else {
fprintf(stderr, "BPy Operator \"%s\" registration error: %s item %d could not run\n", ot->idname, PYOP_ATTR_PROP, i);
PyLineSpit();
PyErr_Print();
PyErr_Clear();
}
Py_DECREF(py_srna_cobject);
} else {
/* cant return NULL from here */ // XXX a bit ugly
PyErr_Print();
PyErr_Clear();
}
// expect a tuple with a CObject and a dict
/* Can't use this because it returns a dict proxy
*
* item= PyObject_GetAttrString(py_class, "__dict__");
*/
item= ((PyTypeObject*)py_class)->tp_dict;
if(item) {
if(pyrna_deferred_register_props(ot->srna, item)!=0) {
PyErr_Print();
PyErr_Clear();
}
Py_DECREF(dummy_args);
Py_DECREF(props);
} else {
}
else {
PyErr_Clear();
}
}
@@ -354,12 +326,10 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
char *idname= NULL;
char idname_bl[OP_MAX_TYPENAME]; /* converted to blender syntax */
int i;
static struct BPY_class_attr_check pyop_class_attr_values[]= {
{PYOP_ATTR_IDNAME, 's', -1, OP_MAX_TYPENAME-3, 0}, /* -3 because a.b -> A_OT_b */
{PYOP_ATTR_UINAME, 's', -1,-1, BPY_CLASS_ATTR_OPTIONAL},
{PYOP_ATTR_PROP, 'l', -1,-1, BPY_CLASS_ATTR_OPTIONAL},
{PYOP_ATTR_DESCRIPTION, 's', -1,-1, BPY_CLASS_ATTR_NONE_OK},
{"execute", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
{"invoke", 'f', 3, -1, BPY_CLASS_ATTR_OPTIONAL},
@@ -400,24 +370,6 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
WM_operatortype_remove(idname);
}
/* If we have properties set, check its a list of dicts */
item= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
if (item) {
for(i=0; i<PyList_Size(item); i++) {
PyObject *py_args = PyList_GET_ITEM(item, i);
PyObject *py_func_ptr, *py_kw; /* place holders */
if (!PyArg_ParseTuple(py_args, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.properties must contain values from FloatProperty", idname);
return NULL;
}
}
Py_DECREF(item);
}
else {
PyErr_Clear();
}
Py_INCREF(py_class);
WM_operatortype_append_ptr(PYTHON_OT_wrapper, py_class);

View File

@@ -71,6 +71,7 @@ static int mathutils_rna_vector_set(BPy_PropertyRNA *self, int subtype, float *v
return 0;
RNA_property_float_set_array(&self->ptr, self->prop, vec_to);
RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
return 1;
}
@@ -89,6 +90,7 @@ static int mathutils_rna_vector_set_index(BPy_PropertyRNA *self, int subtype, fl
return 0;
RNA_property_float_set_index(&self->ptr, self->prop, index, vec_to[index]);
RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
return 1;
}
@@ -119,6 +121,7 @@ static int mathutils_rna_matrix_set(BPy_PropertyRNA *self, int subtype, float *m
return 0;
RNA_property_float_set_array(&self->ptr, self->prop, mat_to);
RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
return 1;
}
@@ -1124,11 +1127,24 @@ static int pyrna_prop_contains(BPy_PropertyRNA * self, PyObject *value)
return 0;
}
static PyObject *pyrna_prop_item(BPy_PropertyRNA * self, Py_ssize_t index)
{
/* reuse subscript functions */
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
return prop_subscript_collection_int(self, index);
} else if (RNA_property_array_check(&self->ptr, self->prop)) {
return prop_subscript_array_int(self, index);
}
PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
return NULL;
}
static PySequenceMethods pyrna_prop_as_sequence = {
NULL, /* Cant set the len otherwise it can evaluate as false */
NULL, /* sq_concat */
NULL, /* sq_repeat */
NULL, /* sq_item */
(ssizeargfunc)pyrna_prop_item, /* sq_item */ /* Only set this so PySequence_Check() returns True */
NULL, /* sq_slice */
NULL, /* sq_ass_item */
NULL, /* sq_ass_slice */
@@ -1138,19 +1154,43 @@ static PySequenceMethods pyrna_prop_as_sequence = {
static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA * self, PyObject *args)
{
char *path;
char *path, *path_full;
int index= 0;
float cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
if(!RNA_struct_is_ID(self->ptr.type)) {
PyErr_SetString( PyExc_TypeError, "StructRNA - keyframe_insert only for ID type");
return NULL;
}
PropertyRNA *prop;
PyObject *result;
if (!PyArg_ParseTuple(args, "s|if:keyframe_insert", &path, &index, &cfra))
return NULL;
return PyBool_FromLong( insert_keyframe((ID *)self->ptr.data, NULL, NULL, path, index, cfra, 0));
if (self->ptr.data==NULL) {
PyErr_Format( PyExc_TypeError, "keyframe_insert, this struct has no data, cant be animated", path);
return NULL;
}
prop = RNA_struct_find_property(&self->ptr, path);
if (prop==NULL) {
PyErr_Format( PyExc_TypeError, "keyframe_insert, property \"%s\" not found", path);
return NULL;
}
if (!RNA_property_animateable(&self->ptr, prop)) {
PyErr_Format( PyExc_TypeError, "keyframe_insert, property \"%s\" not animatable", path);
return NULL;
}
path_full= RNA_path_from_ID_to_property(&self->ptr, prop);
if (path_full==NULL) {
PyErr_Format( PyExc_TypeError, "keyframe_insert, could not make path to \"%s\"", path);
return NULL;
}
result= PyBool_FromLong( insert_keyframe((ID *)self->ptr.id.data, NULL, NULL, path_full, index, cfra, 0));
MEM_freeN(path_full);
return result;
}
static PyObject *pyrna_struct_is_property_set(BPy_StructRNA * self, PyObject *args)
@@ -1178,7 +1218,6 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA * self, PyObject
return PyBool_FromLong(hidden);
}
static PyObject *pyrna_struct_dir(BPy_StructRNA * self)
{
PyObject *ret, *dict;
@@ -1263,6 +1302,13 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self)
BLI_freelistN(&lb);
}
/* Hard coded names */
{
pystring = PyUnicode_FromString("id_data");
PyList_Append(ret, pystring);
Py_DECREF(pystring);
}
return ret;
}
@@ -1319,6 +1365,16 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
BLI_freelistN(&newlb);
}
else if (strcmp(name, "id_data")==0) { /* XXX - hard coded */
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);
}
else {
Py_RETURN_NONE;
}
}
else {
PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name);
ret = NULL;
@@ -1334,10 +1390,14 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje
PropertyRNA *prop = RNA_struct_find_property(&self->ptr, name);
if (prop==NULL) {
// XXX - This currently allows anything to be assigned to an rna prop, need to see how this should be used
// but for now it makes porting scripts confusing since it fails silently.
#if 0
if (!BPy_StructRNA_CheckExact(self) && PyObject_GenericSetAttr((PyObject *)self, pyname, value) >= 0) {
return 0;
}
else {
} else
#endif
{
PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name);
return -1;
}
@@ -2350,7 +2410,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
item = pyrna_struct_CreatePyObject(&ptr);
//item = PyCObject_FromVoidPtr(srna, NULL);
PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", item);
PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "bl_rna", item);
Py_DECREF(item);
/* done with rna instance */
@@ -2666,6 +2726,7 @@ PyObject *BPY_rna_props( void )
{
PyObject *submodule;
submodule= PyModule_Create(&props_module);
PyDict_SetItemString(PySys_GetObject("modules"), props_module.m_name, submodule);
/* INCREF since its its assumed that all these functions return the
* module with a new ref like PyDict_New, since they are passed to
@@ -2682,26 +2743,26 @@ static StructRNA *pyrna_struct_as_srna(PyObject *self)
/* ack, PyObject_GetAttrString wont look up this types tp_dict first :/ */
if(PyType_Check(self)) {
py_srna = (BPy_StructRNA *)PyDict_GetItemString(((PyTypeObject *)self)->tp_dict, "__rna__");
py_srna = (BPy_StructRNA *)PyDict_GetItemString(((PyTypeObject *)self)->tp_dict, "bl_rna");
Py_XINCREF(py_srna);
}
if(py_srna==NULL)
py_srna = (BPy_StructRNA*)PyObject_GetAttrString(self, "__rna__");
py_srna = (BPy_StructRNA*)PyObject_GetAttrString(self, "bl_rna");
if(py_srna==NULL) {
PyErr_SetString(PyExc_SystemError, "internal error, self had no __rna__ attribute, should never happen.");
PyErr_SetString(PyExc_SystemError, "internal error, self had no bl_rna attribute, should never happen.");
return NULL;
}
if(!BPy_StructRNA_Check(py_srna)) {
PyErr_Format(PyExc_SystemError, "internal error, __rna__ was of type %.200s, instead of %.200s instance.", Py_TYPE(py_srna)->tp_name, pyrna_struct_Type.tp_name);
PyErr_Format(PyExc_SystemError, "internal error, bl_rna was of type %.200s, instead of %.200s instance.", Py_TYPE(py_srna)->tp_name, pyrna_struct_Type.tp_name);
Py_DECREF(py_srna);
return NULL;
}
if(py_srna->ptr.type != &RNA_Struct) {
PyErr_SetString(PyExc_SystemError, "internal error, __rna__ was not a RNA_Struct type of rna struct.");
PyErr_SetString(PyExc_SystemError, "internal error, bl_rna was not a RNA_Struct type of rna struct.");
Py_DECREF(py_srna);
return NULL;
}
@@ -2755,13 +2816,10 @@ static PyObject *bpy_prop_deferred_return(void *func, PyObject *kw)
PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "name", "description", "default", NULL};
char *id, *name="", *description="";
char *id=NULL, *name="", *description="";
int def=0;
PropertyRNA *prop;
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
@@ -2773,6 +2831,10 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def))
return NULL;
prop= RNA_def_boolean(srna, id, def, name, description);
RNA_def_property_duplicate_pointers(prop);
Py_RETURN_NONE;
@@ -2785,13 +2847,10 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
char *id, *name="", *description="";
char *id=NULL, *name="", *description="";
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, def=0;
PropertyRNA *prop;
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
@@ -2803,6 +2862,10 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
return NULL;
prop= RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max);
RNA_def_property_duplicate_pointers(prop);
Py_RETURN_NONE;
@@ -2815,13 +2878,10 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
char *id, *name="", *description="";
char *id=NULL, *name="", *description="";
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, def=0.0f;
PropertyRNA *prop;
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
@@ -2833,6 +2893,10 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
return NULL;
prop= RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
RNA_def_property_duplicate_pointers(prop);
Py_RETURN_NONE;
@@ -2845,13 +2909,10 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "name", "description", "maxlen", "default", NULL};
char *id, *name="", *description="", *def="";
char *id=NULL, *name="", *description="", *def="";
int maxlen=0;
PropertyRNA *prop;
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssis:StringProperty", kwlist, &id, &name, &description, &maxlen, &def))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
@@ -2863,6 +2924,10 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssis:StringProperty", kwlist, &id, &name, &description, &maxlen, &def))
return NULL;
prop= RNA_def_string(srna, id, def, maxlen, name, description);
RNA_def_property_duplicate_pointers(prop);
Py_RETURN_NONE;
@@ -2921,15 +2986,12 @@ static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, in
PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "items", "name", "description", "default", NULL};
char *id, *name="", *description="", *def="";
char *id=NULL, *name="", *description="", *def="";
int defvalue=0;
PyObject *items= Py_None;
EnumPropertyItem *eitems;
PropertyRNA *prop;
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sss:EnumProperty", kwlist, &id, &items, &name, &description, &def))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
@@ -2941,6 +3003,10 @@ PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sss:EnumProperty", kwlist, &id, &items, &name, &description, &def))
return NULL;
eitems= enum_items_from_py(items, def, &defvalue);
if(!eitems)
return NULL;
@@ -2977,13 +3043,10 @@ static StructRNA *pointer_type_from_py(PyObject *value)
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "type", "name", "description", NULL};
char *id, *name="", *description="";
char *id=NULL, *name="", *description="";
PropertyRNA *prop;
StructRNA *srna, *ptype;
PyObject *type= Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:PointerProperty", kwlist, &id, &type, &name, &description))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
@@ -2995,6 +3058,10 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:PointerProperty", kwlist, &id, &type, &name, &description))
return NULL;
ptype= pointer_type_from_py(type);
if(!ptype)
return NULL;
@@ -3012,13 +3079,10 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "type", "name", "description", NULL};
char *id, *name="", *description="";
char *id=NULL, *name="", *description="";
PropertyRNA *prop;
StructRNA *srna, *ptype;
PyObject *type= Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:CollectionProperty", kwlist, &id, &type, &name, &description))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
@@ -3030,6 +3094,10 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:CollectionProperty", kwlist, &id, &type, &name, &description))
return NULL;
ptype= pointer_type_from_py(type);
if(!ptype)
return NULL;
@@ -3044,50 +3112,58 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
static int deferred_register_props(PyObject *py_class, StructRNA *srna)
int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
{
PyObject *props, *dummy_args, *item;
int i;
props= PyObject_GetAttrString(py_class, "__props__");
if(!props) {
PyErr_Clear();
return 1;
}
PyObject *dummy_args, *item, *key;
Py_ssize_t pos = 0;
dummy_args = PyTuple_New(0);
for(i=0; i<PyList_Size(props); i++) {
while (PyDict_Next(class_dict, &pos, &key, &item)) {
PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
item = PyList_GET_ITEM(props, i);
if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL);
py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
Py_DECREF(py_srna_cobject);
/* We only care about results from C which
* are for sure types, save some time with error */
if(PyTuple_CheckExact(item)) {
if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
if(py_ret) {
Py_DECREF(py_ret);
PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL);
/* not 100% nice :/, modifies the dict passed, should be ok */
PyDict_SetItemString(py_kw, "attr", key);
py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
Py_DECREF(py_srna_cobject);
if(py_ret) {
Py_DECREF(py_ret);
}
else {
PyErr_Print();
PyErr_Clear();
PyLineSpit();
PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not run\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
Py_DECREF(dummy_args);
return -1;
}
}
else {
Py_DECREF(dummy_args);
return 0;
/* Since this is a class dict, ignore args that can't be passed */
/* for testing only */
/* PyObSpit("Why doesn't this work??", item);
PyErr_Print(); */
PyErr_Clear();
}
}
else {
PyErr_Clear();
PyErr_SetString(PyExc_AttributeError, "expected list of dicts for __props__.");
Py_DECREF(dummy_args);
return 0;
}
}
Py_DECREF(dummy_args);
return 1;
return 0;
}
/*-------------------- Type Registration ------------------------*/
@@ -3121,7 +3197,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
PyObject *item, *fitem;
PyObject *py_arg_count;
int i, flag, arg_count, func_arg_count;
char identifier[128];
const char *identifier;
if (base_class) {
if (!PyObject_IsSubclass(py_class, base_class)) {
@@ -3192,11 +3268,13 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
if(!(flag & PROP_REGISTER))
continue;
BLI_snprintf(identifier, sizeof(identifier), "__%s__", RNA_property_identifier(prop));
identifier= RNA_property_identifier(prop);
item = PyObject_GetAttrString(py_class, identifier);
if (item==NULL) {
if(strcmp(identifier, "__idname__") == 0) {
/* Sneaky workaround to use the class name as the bl_idname */
if(strcmp(identifier, "bl_idname") == 0) {
item= PyObject_GetAttrString(py_class, "__name__");
if(item) {
@@ -3207,7 +3285,8 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
}
}
if (item==NULL && (flag & PROP_REGISTER_OPTIONAL)==0) {
if (item == NULL && (((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL))) {
PyErr_Format( PyExc_AttributeError, "expected %.200s class to have an \"%.200s\" attribute", class_type, identifier);
return -1;
}
@@ -3450,8 +3529,19 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class)
// Py_DECREF(py_class); // shuld be able to do this XXX since the old rna adds a new ref.
}
if(!deferred_register_props(py_class, srna_new))
return NULL;
/* Can't use this because it returns a dict proxy
*
* item= PyObject_GetAttrString(py_class, "__dict__");
*/
item= ((PyTypeObject*)py_class)->tp_dict;
if(item) {
if(pyrna_deferred_register_props(srna_new, item)!=0) {
return NULL;
}
}
else {
PyErr_Clear();
}
Py_RETURN_NONE;
}

View File

@@ -91,6 +91,8 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw);
PyObject *pyrna_basetype_register(PyObject *self, PyObject *args);
PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args);
int pyrna_deferred_register_props(struct StructRNA *srna, PyObject *class_dict);
/* called before stopping python */
void pyrna_alloc_types(void);
void pyrna_free_types(void);