Merged changes in the trunk up to revision 31880.
This commit is contained in:
@@ -170,6 +170,8 @@ void BPy_init_modules( void )
|
||||
BPY_rna_init();
|
||||
|
||||
PyModule_AddObject( mod, "types", BPY_rna_types() ); /* needs to be first so bpy_types can run */
|
||||
PyModule_AddObject(mod, "StructMetaIDProp", (PyObject *)&pyrna_struct_meta_idprop_Type); /* metaclass for idprop types, bpy_types.py needs access */
|
||||
|
||||
bpy_import_test("bpy_types");
|
||||
PyModule_AddObject( mod, "data", BPY_rna_module() ); /* imports bpy_types by running this */
|
||||
bpy_import_test("bpy_types");
|
||||
|
||||
@@ -289,24 +289,36 @@ static PyObject *pyop_getrna(PyObject *self, PyObject *value)
|
||||
return (PyObject *)pyrna;
|
||||
}
|
||||
|
||||
PyObject *BPY_operator_module( void )
|
||||
static struct PyMethodDef bpy_ops_methods[] = {
|
||||
{"poll", (PyCFunction) pyop_poll, METH_VARARGS, NULL},
|
||||
{"call", (PyCFunction) pyop_call, METH_VARARGS, NULL},
|
||||
{"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL},
|
||||
{"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL},
|
||||
{"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL},
|
||||
{"macro_define", (PyCFunction) PYOP_wrap_macro_define, METH_VARARGS, NULL},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef bpy_ops_module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_bpy.ops",
|
||||
NULL,
|
||||
-1,/* multiple "initialization" just copies the module dict. */
|
||||
bpy_ops_methods,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyObject *BPY_operator_module(void)
|
||||
{
|
||||
static PyMethodDef pyop_poll_meth = {"poll", (PyCFunction) pyop_poll, METH_VARARGS, NULL};
|
||||
static PyMethodDef pyop_call_meth = {"call", (PyCFunction) pyop_call, METH_VARARGS, NULL};
|
||||
static PyMethodDef pyop_as_string_meth ={"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL};
|
||||
static PyMethodDef pyop_dir_meth = {"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL};
|
||||
static PyMethodDef pyop_getrna_meth = {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL};
|
||||
static PyMethodDef pyop_macro_def_meth ={"macro_define", (PyCFunction) PYOP_wrap_macro_define, METH_VARARGS, NULL};
|
||||
PyObject *submodule;
|
||||
|
||||
submodule= PyModule_Create(&bpy_ops_module);
|
||||
PyDict_SetItemString(PyImport_GetModuleDict(), bpy_ops_module.m_name, submodule);
|
||||
|
||||
PyObject *submodule = PyModule_New("_bpy.ops");
|
||||
PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy.ops", submodule);
|
||||
|
||||
PyModule_AddObject( submodule, "poll", PyCFunction_New(&pyop_poll_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "call", PyCFunction_New(&pyop_call_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "as_string",PyCFunction_New(&pyop_as_string_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "dir", PyCFunction_New(&pyop_dir_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "get_rna", PyCFunction_New(&pyop_getrna_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "macro_define",PyCFunction_New(&pyop_macro_def_meth, NULL) );
|
||||
/* INCREF since its its assumed that all these functions return the
|
||||
* module with a new ref like PyDict_New, since they are passed to
|
||||
* PyModule_AddObject which steals a ref */
|
||||
Py_INCREF(submodule);
|
||||
|
||||
return submodule;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,9 @@ static void operator_properties_init(wmOperatorType *ot)
|
||||
PyErr_Print(); /* failed to register operator props */
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
// see bpy_types.py:Operator, May redo this some other way!
|
||||
PyObject_CallMethod(py_class, "easy_getsets", NULL);
|
||||
}
|
||||
|
||||
void operator_wrapper(wmOperatorType *ot, void *userdata)
|
||||
|
||||
@@ -77,19 +77,62 @@ EnumPropertyItem property_subtype_array_items[] = {
|
||||
{PROP_NONE, "NONE", 0, "None", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
/* operators use this so it can store the args given but defer running
|
||||
* it until the operator runs where these values are used to setup the
|
||||
* default args for that operator instance */
|
||||
static PyObject *bpy_prop_deferred_return(void *func, PyObject *kw)
|
||||
/* PyObject's */
|
||||
static PyObject *pymeth_BoolProperty = NULL;
|
||||
static PyObject *pymeth_BoolVectorProperty = NULL;
|
||||
static PyObject *pymeth_IntProperty = NULL;
|
||||
static PyObject *pymeth_IntVectorProperty = NULL;
|
||||
static PyObject *pymeth_FloatProperty = NULL;
|
||||
static PyObject *pymeth_FloatVectorProperty = NULL;
|
||||
static PyObject *pymeth_StringProperty = NULL;
|
||||
static PyObject *pymeth_EnumProperty = NULL;
|
||||
static PyObject *pymeth_PointerProperty = NULL;
|
||||
static PyObject *pymeth_CollectionProperty = NULL;
|
||||
static PyObject *pymeth_RemoveProperty = NULL;
|
||||
|
||||
|
||||
/* operators and classes use this so it can store the args given but defer
|
||||
* running it until the operator runs where these values are used to setup
|
||||
* the default args for that operator instance */
|
||||
static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
|
||||
{
|
||||
PyObject *ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEM(ret, 0, PyCapsule_New(func, NULL, NULL));
|
||||
if(kw==NULL) kw= PyDict_New();
|
||||
else Py_INCREF(kw);
|
||||
PyTuple_SET_ITEM(ret, 0, func);
|
||||
Py_INCREF(func);
|
||||
|
||||
if(kw==NULL)
|
||||
kw= PyDict_New();
|
||||
else
|
||||
Py_INCREF(kw);
|
||||
|
||||
PyTuple_SET_ITEM(ret, 1, kw);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* this define runs at the start of each function and deals with
|
||||
* returning a deferred property (to be registed later) */
|
||||
#define BPY_PROPDEF_HEAD(_func) \
|
||||
if (PyTuple_GET_SIZE(args) == 1) { \
|
||||
PyObject *ret; \
|
||||
self= PyTuple_GET_ITEM(args, 0); \
|
||||
args= PyTuple_New(0); \
|
||||
ret= BPy_##_func(self, args, kw); \
|
||||
Py_DECREF(args); \
|
||||
return ret; \
|
||||
} \
|
||||
else if (PyTuple_GET_SIZE(args) > 1) { \
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
|
||||
return NULL; \
|
||||
} \
|
||||
srna= srna_from_self(self, #_func"(...):"); \
|
||||
if(srna==NULL) { \
|
||||
if(PyErr_Occurred()) \
|
||||
return NULL; \
|
||||
return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \
|
||||
} \
|
||||
|
||||
|
||||
#if 0
|
||||
static int bpy_struct_id_used(StructRNA *srna, char *identifier)
|
||||
{
|
||||
@@ -102,7 +145,7 @@ static int bpy_struct_id_used(StructRNA *srna, char *identifier)
|
||||
|
||||
/* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna allong
|
||||
* This isnt incorrect since its a python object - but be careful */
|
||||
char BPy_BoolProperty_doc[] =
|
||||
static char BPy_BoolProperty_doc[] =
|
||||
".. function:: BoolProperty(name=\"\", description=\"\", default=False, options={'ANIMATABLE'}, subtype='NONE')\n"
|
||||
"\n"
|
||||
" Returns a new boolean property definition.\n"
|
||||
@@ -112,20 +155,13 @@ char BPy_BoolProperty_doc[] =
|
||||
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
||||
" :type subtype: string";
|
||||
|
||||
PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(BoolProperty)
|
||||
|
||||
srna= srna_from_self(self, "BoolProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", NULL};
|
||||
char *id=NULL, *name="", *description="";
|
||||
int def=0;
|
||||
@@ -161,14 +197,12 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_BoolProperty, kw);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
char BPy_BoolVectorProperty_doc[] =
|
||||
static char BPy_BoolVectorProperty_doc[] =
|
||||
".. function:: BoolVectorProperty(name=\"\", description=\"\", default=(False, False, False), options={'ANIMATABLE'}, subtype='NONE', size=3)\n"
|
||||
"\n"
|
||||
" Returns a new vector boolean property definition.\n"
|
||||
@@ -177,20 +211,13 @@ char BPy_BoolVectorProperty_doc[] =
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string";
|
||||
PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(BoolVectorProperty)
|
||||
|
||||
srna= srna_from_self(self, "BoolVectorProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", "size", NULL};
|
||||
char *id=NULL, *name="", *description="";
|
||||
int def[PYRNA_STACK_ARRAY]={0};
|
||||
@@ -237,14 +264,12 @@ PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_BoolVectorProperty, kw);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
char BPy_IntProperty_doc[] =
|
||||
static char BPy_IntProperty_doc[] =
|
||||
".. function:: IntProperty(name=\"\", description=\"\", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, options={'ANIMATABLE'}, subtype='NONE')\n"
|
||||
"\n"
|
||||
" Returns a new int property definition.\n"
|
||||
@@ -253,20 +278,13 @@ char BPy_IntProperty_doc[] =
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
||||
" :type subtype: string";
|
||||
PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(IntProperty)
|
||||
|
||||
srna= srna_from_self(self, "IntProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", NULL};
|
||||
char *id=NULL, *name="", *description="";
|
||||
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def=0;
|
||||
@@ -303,14 +321,11 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_IntProperty, kw);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
char BPy_IntVectorProperty_doc[] =
|
||||
static char BPy_IntVectorProperty_doc[] =
|
||||
".. function:: IntVectorProperty(name=\"\", description=\"\", default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, options={'ANIMATABLE'}, subtype='NONE', size=3)\n"
|
||||
"\n"
|
||||
" Returns a new vector int property definition.\n"
|
||||
@@ -319,20 +334,13 @@ char BPy_IntVectorProperty_doc[] =
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string";
|
||||
PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(IntVectorProperty)
|
||||
|
||||
srna= srna_from_self(self, "IntVectorProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", NULL};
|
||||
char *id=NULL, *name="", *description="";
|
||||
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def[PYRNA_STACK_ARRAY]={0};
|
||||
@@ -344,7 +352,7 @@ PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
char *pysubtype= NULL;
|
||||
int subtype= PROP_NONE;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOiiiiO!si:IntVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &PySet_Type, &pyopts, &pysubtype, &size))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOiiiiiO!si:IntVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype, &size))
|
||||
return NULL;
|
||||
|
||||
if(RNA_def_property_free_identifier(srna, id) == -1) {
|
||||
@@ -380,15 +388,12 @@ PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_IntVectorProperty, kw);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
char BPy_FloatProperty_doc[] =
|
||||
static char BPy_FloatProperty_doc[] =
|
||||
".. function:: FloatProperty(name=\"\", description=\"\", default=0.0, min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', unit='NONE')\n"
|
||||
"\n"
|
||||
" Returns a new float property definition.\n"
|
||||
@@ -399,20 +404,13 @@ char BPy_FloatProperty_doc[] =
|
||||
" :type subtype: string\n"
|
||||
" :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n"
|
||||
" :type unit: string\n";
|
||||
PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(FloatProperty)
|
||||
|
||||
srna= srna_from_self(self, "FloatProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", NULL};
|
||||
char *id=NULL, *name="", *description="";
|
||||
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def=0.0f;
|
||||
@@ -457,14 +455,11 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_FloatProperty, kw);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
char BPy_FloatVectorProperty_doc[] =
|
||||
static char BPy_FloatVectorProperty_doc[] =
|
||||
".. function:: FloatVectorProperty(name=\"\", description=\"\", default=(0.0, 0.0, 0.0), min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', size=3)\n"
|
||||
"\n"
|
||||
" Returns a new vector float property definition.\n"
|
||||
@@ -473,20 +468,13 @@ char BPy_FloatVectorProperty_doc[] =
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string";
|
||||
PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(FloatVectorProperty)
|
||||
|
||||
srna= srna_from_self(self, "FloatVectorProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "size", NULL};
|
||||
char *id=NULL, *name="", *description="";
|
||||
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def[PYRNA_STACK_ARRAY]={0.0f};
|
||||
@@ -534,14 +522,11 @@ PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_FloatVectorProperty, kw);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
char BPy_StringProperty_doc[] =
|
||||
static char BPy_StringProperty_doc[] =
|
||||
".. function:: StringProperty(name=\"\", description=\"\", default=\"\", maxlen=0, options={'ANIMATABLE'}, subtype='NONE')\n"
|
||||
"\n"
|
||||
" Returns a new string property definition.\n"
|
||||
@@ -550,20 +535,13 @@ char BPy_StringProperty_doc[] =
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILENAME', 'NONE'].\n"
|
||||
" :type subtype: string";
|
||||
PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(StringProperty)
|
||||
|
||||
srna= srna_from_self(self, "StringProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default", "maxlen", "options", "subtype", NULL};
|
||||
char *id=NULL, *name="", *description="", *def="";
|
||||
int maxlen=0;
|
||||
@@ -599,11 +577,8 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_StringProperty, kw);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, int *defvalue)
|
||||
@@ -652,7 +627,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, in
|
||||
return items;
|
||||
}
|
||||
|
||||
char BPy_EnumProperty_doc[] =
|
||||
static char BPy_EnumProperty_doc[] =
|
||||
".. function:: EnumProperty(items, name=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n"
|
||||
"\n"
|
||||
" Returns a new enumerator property definition.\n"
|
||||
@@ -661,20 +636,13 @@ char BPy_EnumProperty_doc[] =
|
||||
" :type options: set\n"
|
||||
" :arg items: The items that make up this enumerator.\n"
|
||||
" :type items: sequence of string triplets";
|
||||
PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
srna= srna_from_self(self, "EnumProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
BPY_PROPDEF_HEAD(EnumProperty)
|
||||
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "items", "name", "description", "default", "options", NULL};
|
||||
char *id=NULL, *name="", *description="", *def="";
|
||||
int defvalue=0;
|
||||
@@ -706,12 +674,8 @@ PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
MEM_freeN(eitems);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_EnumProperty, kw);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix)
|
||||
@@ -736,7 +700,7 @@ static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix
|
||||
return srna;
|
||||
}
|
||||
|
||||
char BPy_PointerProperty_doc[] =
|
||||
static char BPy_PointerProperty_doc[] =
|
||||
".. function:: PointerProperty(items, type=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n"
|
||||
"\n"
|
||||
" Returns a new pointer property definition.\n"
|
||||
@@ -745,20 +709,13 @@ char BPy_PointerProperty_doc[] =
|
||||
" :type options: set\n"
|
||||
" :arg type: Dynamic type from :mod:`bpy.types`.\n"
|
||||
" :type type: class";
|
||||
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(PointerProperty)
|
||||
|
||||
srna= srna_from_self(self, "PointerProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL};
|
||||
char *id=NULL, *name="", *description="";
|
||||
PropertyRNA *prop;
|
||||
@@ -788,15 +745,11 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_PointerProperty, kw);
|
||||
}
|
||||
return NULL;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
char BPy_CollectionProperty_doc[] =
|
||||
static char BPy_CollectionProperty_doc[] =
|
||||
".. function:: CollectionProperty(items, type=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n"
|
||||
"\n"
|
||||
" Returns a new collection property definition.\n"
|
||||
@@ -805,20 +758,13 @@ char BPy_CollectionProperty_doc[] =
|
||||
" :type options: set\n"
|
||||
" :arg type: Dynamic type from :mod:`bpy.types`.\n"
|
||||
" :type type: class";
|
||||
PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) > 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
||||
return NULL;
|
||||
}
|
||||
BPY_PROPDEF_HEAD(CollectionProperty)
|
||||
|
||||
srna= srna_from_self(self, "CollectionProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
}
|
||||
else if(srna) {
|
||||
if(srna) {
|
||||
static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL};
|
||||
char *id=NULL, *name="", *description="";
|
||||
PropertyRNA *prop;
|
||||
@@ -848,25 +794,34 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
}
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else { /* operators defer running this function */
|
||||
return bpy_prop_deferred_return((void *)BPy_CollectionProperty, kw);
|
||||
}
|
||||
return NULL;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
char BPy_RemoveProperty_doc[] =
|
||||
static char BPy_RemoveProperty_doc[] =
|
||||
".. function:: RemoveProperty(attr)\n"
|
||||
"\n"
|
||||
" Removes a dynamically defined property.\n"
|
||||
"\n"
|
||||
" :arg attr: Property name.\n"
|
||||
" :type attr: string";
|
||||
PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
if(PyTuple_GET_SIZE(args) == 1) {
|
||||
PyObject *ret;
|
||||
self= PyTuple_GET_ITEM(args, 0);
|
||||
args= PyTuple_New(0);
|
||||
ret= BPy_RemoveProperty(self, args, kw);
|
||||
Py_DECREF(args);
|
||||
return ret;
|
||||
}
|
||||
else if (PyTuple_GET_SIZE(args) > 1) {
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
|
||||
return NULL;
|
||||
}
|
||||
|
||||
srna= srna_from_self(self, "RemoveProperty(...):");
|
||||
if(srna==NULL && PyErr_Occurred()) {
|
||||
return NULL; /* self's type was compatible but error getting the srna */
|
||||
@@ -887,9 +842,8 @@ PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property.", id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static struct PyMethodDef props_methods[] = {
|
||||
@@ -904,8 +858,7 @@ static struct PyMethodDef props_methods[] = {
|
||||
{"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, BPy_PointerProperty_doc},
|
||||
{"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, BPy_CollectionProperty_doc},
|
||||
|
||||
/* only useful as a bpy_struct method */
|
||||
/* {"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, BPy_RemoveProperty_doc}, */
|
||||
{"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, BPy_RemoveProperty_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -922,6 +875,8 @@ static struct PyModuleDef props_module = {
|
||||
PyObject *BPY_rna_props( void )
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule_dict;
|
||||
|
||||
submodule= PyModule_Create(&props_module);
|
||||
PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule);
|
||||
|
||||
@@ -929,6 +884,23 @@ PyObject *BPY_rna_props( void )
|
||||
* module with a new ref like PyDict_New, since they are passed to
|
||||
* PyModule_AddObject which steals a ref */
|
||||
Py_INCREF(submodule);
|
||||
|
||||
/* api needs the PyObjects internally */
|
||||
submodule_dict= PyModule_GetDict(submodule);
|
||||
|
||||
#define ASSIGN_STATIC(_name) pymeth_##_name = PyDict_GetItemString(submodule_dict, #_name)
|
||||
|
||||
ASSIGN_STATIC(BoolProperty);
|
||||
ASSIGN_STATIC(BoolVectorProperty);
|
||||
ASSIGN_STATIC(IntProperty);
|
||||
ASSIGN_STATIC(IntVectorProperty);
|
||||
ASSIGN_STATIC(FloatProperty);
|
||||
ASSIGN_STATIC(FloatVectorProperty);
|
||||
ASSIGN_STATIC(StringProperty);
|
||||
ASSIGN_STATIC(EnumProperty);
|
||||
ASSIGN_STATIC(PointerProperty);
|
||||
ASSIGN_STATIC(CollectionProperty);
|
||||
ASSIGN_STATIC(RemoveProperty);
|
||||
|
||||
return submodule;
|
||||
}
|
||||
|
||||
@@ -29,32 +29,6 @@
|
||||
|
||||
PyObject *BPY_rna_props( void );
|
||||
|
||||
/* functions for setting up new props - experemental */
|
||||
PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
|
||||
PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||
|
||||
extern char BPy_BoolProperty_doc[];
|
||||
extern char BPy_BoolVectorProperty_doc[];
|
||||
extern char BPy_IntProperty_doc[];
|
||||
extern char BPy_IntVectorProperty_doc[];
|
||||
extern char BPy_FloatProperty_doc[];
|
||||
extern char BPy_FloatVectorProperty_doc[];
|
||||
extern char BPy_StringProperty_doc[];
|
||||
extern char BPy_EnumProperty_doc[];
|
||||
extern char BPy_PointerProperty_doc[];
|
||||
extern char BPy_CollectionProperty_doc[];\
|
||||
extern char BPy_RemoveProperty_doc[];
|
||||
|
||||
#define PYRNA_STACK_ARRAY 32
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "float.h" /* FLT_MIN/MAX */
|
||||
|
||||
#include "RNA_enum_types.h"
|
||||
#include "RNA_define.h" /* RNA_def_property_free_identifier */
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BKE_utildefines.h"
|
||||
@@ -61,6 +62,7 @@ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, Po
|
||||
static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self);
|
||||
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
|
||||
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
|
||||
static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
|
||||
|
||||
/* bpyrna vector/euler/quat callbacks */
|
||||
static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
|
||||
@@ -402,8 +404,7 @@ static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
return Py_INCREF(res), res;
|
||||
}
|
||||
|
||||
static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
|
||||
@@ -432,8 +433,7 @@ static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
return Py_INCREF(res), res;
|
||||
}
|
||||
|
||||
/*----------------------repr--------------------------------------------*/
|
||||
@@ -1019,7 +1019,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *p
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
if(data) *((char**)data)= param; /*XXX, this assignes a pointer, wouldnt it be better to copy??? */
|
||||
if(data) *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
|
||||
else RNA_property_string_set(ptr, prop, param);
|
||||
}
|
||||
#ifdef USE_STRING_COERCE
|
||||
@@ -2480,7 +2480,11 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
|
||||
PropertyRNA *prop;
|
||||
FunctionRNA *func;
|
||||
|
||||
if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
|
||||
if(name == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string");
|
||||
ret = NULL;
|
||||
}
|
||||
else if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
|
||||
/* annoying exception, maybe we need to have different types for this... */
|
||||
if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idprops_check(self->ptr.type)) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
|
||||
@@ -2583,12 +2587,69 @@ static int pyrna_struct_pydict_contains(PyObject *self, PyObject *pyname)
|
||||
#endif
|
||||
|
||||
//--------------- setattr-------------------------------------------
|
||||
static int pyrna_is_deferred_prop(PyObject *value)
|
||||
{
|
||||
return PyTuple_CheckExact(value) && PyTuple_GET_SIZE(value)==2 && PyCallable_Check(PyTuple_GET_ITEM(value, 0)) && PyDict_CheckExact(PyTuple_GET_ITEM(value, 1));
|
||||
}
|
||||
|
||||
static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *pyname)
|
||||
{
|
||||
return PyType_Type.tp_getattro(cls, pyname);
|
||||
}
|
||||
|
||||
static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value)
|
||||
{
|
||||
StructRNA *srna= srna_from_self(cls, "");
|
||||
|
||||
if(srna == NULL) {
|
||||
if(value && pyrna_is_deferred_prop(value)) {
|
||||
PyErr_Format(PyExc_AttributeError, "pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s'", ((PyTypeObject *)cls)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* srna_from_self may set an error */
|
||||
PyErr_Clear();
|
||||
return PyType_Type.tp_setattro(cls, attr, value);
|
||||
}
|
||||
|
||||
if(value) {
|
||||
/* check if the value is a property */
|
||||
if(pyrna_is_deferred_prop(value)) {
|
||||
int ret= deferred_register_prop(srna, attr, value);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
/* pass through, when the value isn't assigned it still works but gets confusing from script writers POV */
|
||||
}
|
||||
else {
|
||||
/* remove existing property if its set or we also end up with confusement */
|
||||
char *attr_str= _PyUnicode_AsString(attr);
|
||||
RNA_def_property_free_identifier(srna, attr_str); /* ignore on failier */
|
||||
}
|
||||
}
|
||||
else { /* __delattr__ */
|
||||
/* first find if this is a registered property */
|
||||
char *attr_str= _PyUnicode_AsString(attr);
|
||||
int ret= RNA_def_property_free_identifier(srna, attr_str);
|
||||
if (ret == -1) {
|
||||
PyErr_Format(PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property.", attr_str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* fallback to standard py, delattr/setattr */
|
||||
return PyType_Type.tp_setattro(cls, attr, value);
|
||||
}
|
||||
|
||||
static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObject *value )
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
PropertyRNA *prop= NULL;
|
||||
|
||||
if (name[0] != '_' && (prop= RNA_struct_find_property(&self->ptr, name))) {
|
||||
if(name == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string");
|
||||
return -1;
|
||||
}
|
||||
else if (name[0] != '_' && (prop= RNA_struct_find_property(&self->ptr, name))) {
|
||||
if (!RNA_property_editable_flag(&self->ptr, prop)) {
|
||||
PyErr_Format( PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) );
|
||||
return -1;
|
||||
@@ -2660,7 +2721,11 @@ static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
|
||||
if(name[0] != '_') {
|
||||
if(name == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string");
|
||||
return NULL;
|
||||
}
|
||||
else if(name[0] != '_') {
|
||||
PyObject *ret;
|
||||
PropertyRNA *prop;
|
||||
FunctionRNA *func;
|
||||
@@ -2693,12 +2758,15 @@ static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyna
|
||||
PropertyRNA *prop;
|
||||
PointerRNA r_ptr;
|
||||
|
||||
if(value == NULL) {
|
||||
if(name == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string");
|
||||
return -1;
|
||||
}
|
||||
else if(value == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
|
||||
else if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
|
||||
if ((prop = RNA_struct_find_property(&r_ptr, name))) {
|
||||
/* pyrna_py_to_prop sets its own exceptions */
|
||||
return pyrna_py_to_prop(&r_ptr, prop, NULL, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
|
||||
@@ -2726,7 +2794,6 @@ static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self)
|
||||
|
||||
static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value)
|
||||
{
|
||||
PyObject *ret;
|
||||
int key= PyLong_AsSsize_t(value);
|
||||
|
||||
if (key==-1 && PyErr_Occurred()) {
|
||||
@@ -2739,15 +2806,11 @@ static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyOb
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = Py_None;
|
||||
Py_INCREF(ret);
|
||||
|
||||
return ret;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObject *args)
|
||||
{
|
||||
PyObject *ret;
|
||||
int key=0, pos=0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ii", &key, &pos)) {
|
||||
@@ -2760,10 +2823,7 @@ static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObje
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = Py_None;
|
||||
Py_INCREF(ret);
|
||||
|
||||
return ret;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self)
|
||||
@@ -2902,8 +2962,7 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
|
||||
return BPy_IDGroup_WrapData(self->ptr.id.data, idprop);
|
||||
}
|
||||
|
||||
Py_INCREF(def);
|
||||
return def;
|
||||
return Py_INCREF(def), def;
|
||||
}
|
||||
|
||||
static char pyrna_struct_as_pointer_doc[] =
|
||||
@@ -2911,7 +2970,7 @@ static char pyrna_struct_as_pointer_doc[] =
|
||||
"\n"
|
||||
" Returns the memory address which holds a pointer to blenders internal data\n"
|
||||
"\n"
|
||||
" :return: capsule with a name set from the struct type.\n"
|
||||
" :return: int (memory address).\n"
|
||||
" :rtype: int\n"
|
||||
"\n"
|
||||
" .. note:: This is intended only for advanced script writers who need to pass blender data to their own C/Python modules.\n";
|
||||
@@ -2933,9 +2992,8 @@ static PyObject *pyrna_prop_get(BPy_PropertyRNA *self, PyObject *args)
|
||||
|
||||
if(RNA_property_collection_lookup_string(&self->ptr, self->prop, key, &newptr))
|
||||
return pyrna_struct_CreatePyObject(&newptr);
|
||||
|
||||
Py_INCREF(def);
|
||||
return def;
|
||||
|
||||
return Py_INCREF(def), def;
|
||||
}
|
||||
|
||||
static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
|
||||
@@ -3251,21 +3309,6 @@ static struct PyMethodDef pyrna_struct_methods[] = {
|
||||
/* experemental */
|
||||
{"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL},
|
||||
{"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL},
|
||||
|
||||
/* class methods, only valid for subclasses */
|
||||
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_BoolProperty_doc},
|
||||
{"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_BoolVectorProperty_doc},
|
||||
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_IntProperty_doc},
|
||||
{"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_IntVectorProperty_doc},
|
||||
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_FloatProperty_doc},
|
||||
{"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_FloatVectorProperty_doc},
|
||||
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_StringProperty_doc},
|
||||
{"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_EnumProperty_doc},
|
||||
{"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_PointerProperty_doc},
|
||||
{"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_CollectionProperty_doc},
|
||||
|
||||
{"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_RemoveProperty_doc},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -3742,6 +3785,42 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
/* subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass */
|
||||
/* note: tp_base member is set to &PyType_Type on init */
|
||||
PyTypeObject pyrna_struct_meta_idprop_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"bpy_struct_meta_idprop", /* tp_name */
|
||||
sizeof(PyHeapTypeObject), /* tp_basicsize */ // XXX, would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
NULL, /* tp_dealloc */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
NULL, /* 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; */
|
||||
NULL, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
(getattrofunc) pyrna_struct_meta_idprop_getattro, /* getattrofunc tp_getattro; */
|
||||
(setattrofunc) pyrna_struct_meta_idprop_setattro, /* 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; */
|
||||
};
|
||||
|
||||
|
||||
/*-----------------------BPy_StructRNA method def------------------------------*/
|
||||
PyTypeObject pyrna_struct_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
@@ -4147,7 +4226,6 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
PyObject *item;
|
||||
PyObject *newclass_dict= ((PyTypeObject *)newclass)->tp_dict;
|
||||
|
||||
Py_INCREF(newclass);
|
||||
|
||||
@@ -4165,9 +4243,10 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
||||
RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr);
|
||||
item = pyrna_struct_CreatePyObject(&ptr);
|
||||
|
||||
//item = PyCapsule_New(srna, NULL, NULL);
|
||||
PyDict_SetItemString(newclass_dict, "bl_rna", item);
|
||||
/* note, must set the class not the __dict__ else the internal slots are not updated correctly */
|
||||
PyObject_SetAttrString(newclass, "bl_rna", item);
|
||||
Py_DECREF(item);
|
||||
|
||||
/* done with rna instance */
|
||||
}
|
||||
|
||||
@@ -4199,9 +4278,10 @@ static PyObject* pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dict
|
||||
|
||||
/* check if we have a native python subclass, use it when it exists
|
||||
* return a borrowed reference */
|
||||
static PyObject *bpy_types_dict= NULL;
|
||||
|
||||
static PyObject* pyrna_srna_ExternalType(StructRNA *srna)
|
||||
{
|
||||
PyObject *bpy_types_dict= NULL;
|
||||
const char *idname= RNA_struct_identifier(srna);
|
||||
PyObject *newclass;
|
||||
|
||||
@@ -4214,7 +4294,6 @@ static PyObject* pyrna_srna_ExternalType(StructRNA *srna)
|
||||
fprintf(stderr, "pyrna_srna_ExternalType: failed to find 'bpy_types' module\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bpy_types_dict = PyModule_GetDict(bpy_types); // borrow
|
||||
Py_DECREF(bpy_types); // fairly safe to assume the dict is kept
|
||||
}
|
||||
@@ -4276,16 +4355,24 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
|
||||
|
||||
/* Assume RNA_struct_py_type_get(srna) was already checked */
|
||||
PyObject *py_base= pyrna_srna_PyBase(srna);
|
||||
|
||||
PyObject *metaclass;
|
||||
const char *idname= RNA_struct_identifier(srna);
|
||||
|
||||
|
||||
/* remove __doc__ for now */
|
||||
// const char *descr= RNA_struct_ui_description(srna);
|
||||
// if(!descr) descr= "(no docs)";
|
||||
// "__doc__",descr
|
||||
|
||||
|
||||
if(RNA_struct_idprops_check(srna) && !PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type)) {
|
||||
metaclass= (PyObject *)&pyrna_struct_meta_idprop_Type;
|
||||
}
|
||||
else {
|
||||
metaclass= (PyObject *)&PyType_Type;
|
||||
}
|
||||
|
||||
/* always use O not N when calling, N causes refcount errors */
|
||||
newclass = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sss()}", idname, py_base, "__module__","bpy.types", "__slots__");
|
||||
newclass = PyObject_CallFunction(metaclass, "s(O){sss()}", idname, py_base, "__module__","bpy.types", "__slots__");
|
||||
|
||||
/* newclass will now have 2 ref's, ???, probably 1 is internal since decrefing here segfaults */
|
||||
|
||||
/* PyC_ObSpit("new class ref", newclass); */
|
||||
@@ -4299,6 +4386,7 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
|
||||
}
|
||||
else {
|
||||
/* this should not happen */
|
||||
printf("Error registering '%s'\n", idname);
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
@@ -4403,7 +4491,12 @@ void BPY_rna_init(void)
|
||||
mathutils_rna_array_cb_index= Mathutils_RegisterCallback(&mathutils_rna_array_cb);
|
||||
mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb);
|
||||
#endif
|
||||
|
||||
|
||||
/* metaclass */
|
||||
pyrna_struct_meta_idprop_Type.tp_base= &PyType_Type;
|
||||
if( PyType_Ready( &pyrna_struct_meta_idprop_Type ) < 0 )
|
||||
return;
|
||||
|
||||
if( PyType_Ready( &pyrna_struct_Type ) < 0 )
|
||||
return;
|
||||
|
||||
@@ -4463,8 +4556,12 @@ static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA *self, PyObject *pynam
|
||||
PointerRNA newptr;
|
||||
PyObject *ret;
|
||||
char *name= _PyUnicode_AsString(pyname);
|
||||
|
||||
if(strcmp(name, "register")==0) {
|
||||
|
||||
if(name == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string");
|
||||
ret = NULL;
|
||||
}
|
||||
else if(strcmp(name, "register")==0) {
|
||||
/* this is called so often, make an exception and save a full lookup on all types */
|
||||
ret= PyObject_GenericGetAttr((PyObject *)self, pyname);
|
||||
}
|
||||
@@ -4604,29 +4701,32 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
|
||||
return pyrna_struct_as_srna(self, 0, error_prefix);
|
||||
}
|
||||
|
||||
static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key, PyObject *dummy_args)
|
||||
static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item)
|
||||
{
|
||||
/* We only care about results from C which
|
||||
* are for sure types, save some time with error */
|
||||
if(PyTuple_CheckExact(item) && PyTuple_GET_SIZE(item)==2) {
|
||||
if(pyrna_is_deferred_prop(item)) {
|
||||
|
||||
PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
|
||||
PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
|
||||
PyObject *py_func, *py_kw, *py_srna_cobject, *py_ret;
|
||||
|
||||
if(PyArg_ParseTuple(item, "O!O!", &PyCapsule_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
|
||||
if(PyArg_ParseTuple(item, "OO!", &py_func, &PyDict_Type, &py_kw)) {
|
||||
PyObject *args_fake;
|
||||
|
||||
if(*_PyUnicode_AsString(key)=='_') {
|
||||
PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: %.200s could not register because the property starts with an '_'\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
|
||||
return -1;
|
||||
}
|
||||
pyfunc = PyCapsule_GetPointer(py_func_ptr, NULL);
|
||||
py_srna_cobject = PyCapsule_New(srna, NULL, NULL);
|
||||
|
||||
/* not 100% nice :/, modifies the dict passed, should be ok */
|
||||
PyDict_SetItemString(py_kw, "attr", key);
|
||||
|
||||
args_fake= PyTuple_New(1);
|
||||
PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject);
|
||||
|
||||
py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
|
||||
Py_DECREF(py_srna_cobject);
|
||||
py_ret = PyObject_Call(py_func, args_fake, py_kw);
|
||||
|
||||
Py_DECREF(args_fake); /* free's py_srna_cobject too */
|
||||
|
||||
if(py_ret) {
|
||||
Py_DECREF(py_ret);
|
||||
@@ -4657,12 +4757,9 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
|
||||
{
|
||||
PyObject *item, *key;
|
||||
PyObject *order;
|
||||
PyObject *dummy_args;
|
||||
Py_ssize_t pos = 0;
|
||||
int ret;
|
||||
|
||||
dummy_args = PyTuple_New(0);
|
||||
|
||||
if( !PyDict_CheckExact(class_dict) &&
|
||||
(order= PyDict_GetItemString(class_dict, "order")) &&
|
||||
PyList_CheckExact(order)
|
||||
@@ -4670,22 +4767,20 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
|
||||
for(pos= 0; pos<PyList_GET_SIZE(order); pos++) {
|
||||
key= PyList_GET_ITEM(order, pos);
|
||||
item= PyDict_GetItem(class_dict, key);
|
||||
ret= deferred_register_prop(srna, item, key, dummy_args);
|
||||
ret= deferred_register_prop(srna, key, item);
|
||||
if(ret==-1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (PyDict_Next(class_dict, &pos, &key, &item)) {
|
||||
ret= deferred_register_prop(srna, item, key, dummy_args);
|
||||
ret= deferred_register_prop(srna, key, item);
|
||||
|
||||
if(ret==-1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(dummy_args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "RNA_types.h"
|
||||
#include "BKE_idprop.h"
|
||||
|
||||
extern PyTypeObject pyrna_struct_meta_idprop_Type;
|
||||
extern PyTypeObject pyrna_struct_Type;
|
||||
extern PyTypeObject pyrna_prop_Type;
|
||||
extern PyTypeObject pyrna_prop_array_Type;
|
||||
|
||||
Reference in New Issue
Block a user