2.5 Python
Merging changes made by Arystanbek in the soc-2009-kazanbas branch, plus some things modified and added by me. * Operator exec is called execute in python now, due to conflicts with python exec keyword. * Operator invoke/execute now get context argument. * Fix crash executing operators due to bpy_import_main_set not being set with Main pointer. * The bpy.props module now has the FloatProperty/IntProperty/ StringProperty/BoolProperty functions to define RNA properties for operators. * Operators now have an __operator__ property to get the actual RNA operator pointers, this is only temporary though. * bpy.ops.add now allows the operator to be already registered, it will simply overwrite the existing one. * Both the ui and io directories are now scanned and run on startup.
This commit is contained in:
32
SConstruct
32
SConstruct
@@ -468,27 +468,17 @@ if env['OURPLATFORM']!='darwin':
|
|||||||
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
|
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
|
||||||
|
|
||||||
if env['WITH_BF_PYTHON']:
|
if env['WITH_BF_PYTHON']:
|
||||||
#-- .blender/scripts
|
#-- .blender/scripts, .blender/ui, .blender/io
|
||||||
scriptpath='release/scripts'
|
scriptpaths=['release/scripts', 'release/ui', 'release/io']
|
||||||
for dp, dn, df in os.walk(scriptpath):
|
for scriptpath in scriptpaths:
|
||||||
if 'CVS' in dn:
|
for dp, dn, df in os.walk(scriptpath):
|
||||||
dn.remove('CVS')
|
if 'CVS' in dn:
|
||||||
if '.svn' in dn:
|
dn.remove('CVS')
|
||||||
dn.remove('.svn')
|
if '.svn' in dn:
|
||||||
dir=env['BF_INSTALLDIR']+'/.blender/scripts'+dp[len(scriptpath):]
|
dn.remove('.svn')
|
||||||
source=[dp+os.sep+f for f in df]
|
dir=env['BF_INSTALLDIR']+'/.blender/'+os.path.basename(scriptpath)+dp[len(scriptpath):]
|
||||||
scriptinstall.append(env.Install(dir=dir,source=source))
|
source=[dp+os.sep+f for f in df]
|
||||||
|
scriptinstall.append(env.Install(dir=dir,source=source))
|
||||||
#-- .blender/ui
|
|
||||||
scriptpath='release/ui'
|
|
||||||
for dp, dn, df in os.walk(scriptpath):
|
|
||||||
if 'CVS' in dn:
|
|
||||||
dn.remove('CVS')
|
|
||||||
if '.svn' in dn:
|
|
||||||
dn.remove('.svn')
|
|
||||||
dir=env['BF_INSTALLDIR']+'/.blender/ui'+dp[len(scriptpath):]
|
|
||||||
source=[dp+os.sep+f for f in df]
|
|
||||||
scriptinstall.append(env.Install(dir=dir,source=source))
|
|
||||||
|
|
||||||
#-- icons
|
#-- icons
|
||||||
if env['OURPLATFORM']=='linux2':
|
if env['OURPLATFORM']=='linux2':
|
||||||
|
@@ -59,6 +59,7 @@ static void bpy_init_modules( void )
|
|||||||
PyModule_AddObject( mod, "data", BPY_rna_module() );
|
PyModule_AddObject( mod, "data", BPY_rna_module() );
|
||||||
/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
|
/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
|
||||||
PyModule_AddObject( mod, "types", BPY_rna_types() );
|
PyModule_AddObject( mod, "types", BPY_rna_types() );
|
||||||
|
PyModule_AddObject( mod, "props", BPY_rna_props() );
|
||||||
PyModule_AddObject( mod, "ops", BPY_operator_module() );
|
PyModule_AddObject( mod, "ops", BPY_operator_module() );
|
||||||
PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
|
PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
|
||||||
|
|
||||||
@@ -103,6 +104,7 @@ static PyObject *CreateGlobalDictionary( bContext *C )
|
|||||||
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||||
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||||
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||||
|
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -369,71 +371,77 @@ void BPY_run_ui_scripts(bContext *C, int reload)
|
|||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
char *file_extension;
|
char *file_extension;
|
||||||
|
char *dirname;
|
||||||
char path[FILE_MAX];
|
char path[FILE_MAX];
|
||||||
char *dirname= BLI_gethome_folder("ui");
|
char *dirs[] = {"io", "ui", NULL};
|
||||||
int filelen; /* filename length */
|
int a, filelen; /* filename length */
|
||||||
|
|
||||||
PyGILState_STATE gilstate;
|
PyGILState_STATE gilstate;
|
||||||
PyObject *mod;
|
PyObject *mod;
|
||||||
PyObject *sys_path_orig;
|
PyObject *sys_path_orig;
|
||||||
PyObject *sys_path_new;
|
PyObject *sys_path_new;
|
||||||
|
|
||||||
if(!dirname)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dir = opendir(dirname);
|
|
||||||
|
|
||||||
if(!dir)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gilstate = PyGILState_Ensure();
|
gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
/* backup sys.path */
|
|
||||||
sys_path_orig= PySys_GetObject("path");
|
|
||||||
Py_INCREF(sys_path_orig); /* dont free it */
|
|
||||||
|
|
||||||
sys_path_new= PyList_New(1);
|
|
||||||
PyList_SET_ITEM(sys_path_new, 0, PyUnicode_FromString(dirname));
|
|
||||||
PySys_SetObject("path", sys_path_new);
|
|
||||||
Py_DECREF(sys_path_new);
|
|
||||||
|
|
||||||
// XXX - evil, need to access context
|
// XXX - evil, need to access context
|
||||||
BPy_SetContext(C);
|
BPy_SetContext(C);
|
||||||
bpy_import_main_set(CTX_data_main(C));
|
bpy_import_main_set(CTX_data_main(C));
|
||||||
|
|
||||||
while((de = readdir(dir)) != NULL) {
|
for(a=0; dirs[a]; a++) {
|
||||||
/* We could stat the file but easier just to let python
|
dirname= BLI_gethome_folder(dirs[a]);
|
||||||
* import it and complain if theres a problem */
|
|
||||||
|
|
||||||
file_extension = strstr(de->d_name, ".py");
|
if(!dirname)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(file_extension && *(file_extension + 3) == '\0') {
|
dir = opendir(dirname);
|
||||||
filelen = strlen(de->d_name);
|
|
||||||
BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
|
|
||||||
|
|
||||||
mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0);
|
if(!dir)
|
||||||
if (mod) {
|
continue;
|
||||||
if (reload) {
|
|
||||||
PyObject *mod_orig= mod;
|
/* backup sys.path */
|
||||||
mod= PyImport_ReloadModule(mod);
|
sys_path_orig= PySys_GetObject("path");
|
||||||
Py_DECREF(mod_orig);
|
Py_INCREF(sys_path_orig); /* dont free it */
|
||||||
|
|
||||||
|
sys_path_new= PyList_New(1);
|
||||||
|
PyList_SET_ITEM(sys_path_new, 0, PyUnicode_FromString(dirname));
|
||||||
|
PySys_SetObject("path", sys_path_new);
|
||||||
|
Py_DECREF(sys_path_new);
|
||||||
|
|
||||||
|
while((de = readdir(dir)) != NULL) {
|
||||||
|
/* We could stat the file but easier just to let python
|
||||||
|
* import it and complain if theres a problem */
|
||||||
|
|
||||||
|
file_extension = strstr(de->d_name, ".py");
|
||||||
|
|
||||||
|
if(file_extension && *(file_extension + 3) == '\0') {
|
||||||
|
filelen = strlen(de->d_name);
|
||||||
|
BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
|
||||||
|
|
||||||
|
mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0);
|
||||||
|
if (mod) {
|
||||||
|
if (reload) {
|
||||||
|
PyObject *mod_orig= mod;
|
||||||
|
mod= PyImport_ReloadModule(mod);
|
||||||
|
Py_DECREF(mod_orig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mod) {
|
||||||
|
Py_DECREF(mod); /* could be NULL from reloading */
|
||||||
|
} else {
|
||||||
|
BPy_errors_to_report(NULL); // TODO - reports
|
||||||
|
fprintf(stderr, "unable to import \"%s\" %s/%s\n", path, dirname, de->d_name);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(mod) {
|
|
||||||
Py_DECREF(mod); /* could be NULL from reloading */
|
|
||||||
} else {
|
|
||||||
BPy_errors_to_report(NULL); // TODO - reports
|
|
||||||
fprintf(stderr, "unable to import \"%s\" %s/%s\n", path, dirname, de->d_name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
PySys_SetObject("path", sys_path_orig);
|
||||||
|
Py_DECREF(sys_path_orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
|
|
||||||
PySys_SetObject("path", sys_path_orig);
|
|
||||||
Py_DECREF(sys_path_orig);
|
|
||||||
|
|
||||||
bpy_import_main_set(NULL);
|
bpy_import_main_set(NULL);
|
||||||
|
|
||||||
PyGILState_Release(gilstate);
|
PyGILState_Release(gilstate);
|
||||||
|
@@ -40,6 +40,8 @@
|
|||||||
#include "bpy_compat.h"
|
#include "bpy_compat.h"
|
||||||
#include "bpy_util.h"
|
#include "bpy_util.h"
|
||||||
|
|
||||||
|
#include "../generic/bpy_internal_import.h" // our own imports
|
||||||
|
|
||||||
#define PYOP_ATTR_PROP "__props__"
|
#define PYOP_ATTR_PROP "__props__"
|
||||||
#define PYOP_ATTR_UINAME "__label__"
|
#define PYOP_ATTR_UINAME "__label__"
|
||||||
#define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */
|
#define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */
|
||||||
@@ -177,10 +179,13 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
|||||||
PyObject *ret= NULL, *py_class_instance, *item= NULL;
|
PyObject *ret= NULL, *py_class_instance, *item= NULL;
|
||||||
int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
|
int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
|
||||||
PointerRNA ptr_context;
|
PointerRNA ptr_context;
|
||||||
PyObject *py_context;
|
PointerRNA ptr_operator;
|
||||||
|
PyObject *py_operator;
|
||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
|
bpy_import_main_set(CTX_data_main(C));
|
||||||
|
|
||||||
BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
|
BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
|
||||||
|
|
||||||
args = PyTuple_New(1);
|
args = PyTuple_New(1);
|
||||||
@@ -214,19 +219,28 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
|||||||
RNA_property_collection_end(&iter);
|
RNA_property_collection_end(&iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set operator pointer RNA as instance "__operator__" attribute */
|
||||||
|
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) {
|
if (mode==PYOP_INVOKE) {
|
||||||
item= PyObject_GetAttrString(py_class, "invoke");
|
item= PyObject_GetAttrString(py_class, "invoke");
|
||||||
args = PyTuple_New(2);
|
args = PyTuple_New(3);
|
||||||
PyTuple_SET_ITEM(args, 1, pyop_dict_from_event(event));
|
|
||||||
|
// PyTuple_SET_ITEM "steals" object reference, it is
|
||||||
|
// an object passed shouldn't be DECREF'ed
|
||||||
|
PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
|
||||||
|
PyTuple_SET_ITEM(args, 2, pyop_dict_from_event(event));
|
||||||
}
|
}
|
||||||
else if (mode==PYOP_EXEC) {
|
else if (mode==PYOP_EXEC) {
|
||||||
item= PyObject_GetAttrString(py_class, "exec");
|
item= PyObject_GetAttrString(py_class, "execute");
|
||||||
args = PyTuple_New(2);
|
args = PyTuple_New(2);
|
||||||
|
|
||||||
RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
|
PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
|
||||||
py_context = pyrna_struct_CreatePyObject(&ptr_context);
|
|
||||||
PyTuple_SET_ITEM(args, 1, py_context);
|
|
||||||
}
|
}
|
||||||
else if (mode==PYOP_POLL) {
|
else if (mode==PYOP_POLL) {
|
||||||
item= PyObject_GetAttrString(py_class, "poll");
|
item= PyObject_GetAttrString(py_class, "poll");
|
||||||
@@ -259,6 +273,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
|||||||
/* the returned value could not be converted into a flag */
|
/* the returned value could not be converted into a flag */
|
||||||
BPy_errors_to_report(op->reports);
|
BPy_errors_to_report(op->reports);
|
||||||
|
|
||||||
|
ret_flag = OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
/* there is no need to copy the py keyword dict modified by
|
/* there is no need to copy the py keyword dict modified by
|
||||||
* pyot->py_invoke(), back to the operator props since they are just
|
* pyot->py_invoke(), back to the operator props since they are just
|
||||||
@@ -271,7 +286,34 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
|||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* print operator return value */
|
||||||
|
if (mode != PYOP_POLL) {
|
||||||
|
char flag_str[100];
|
||||||
|
char class_name[100];
|
||||||
|
BPY_flag_def *flag_def = pyop_ret_flags;
|
||||||
|
|
||||||
|
strcpy(flag_str, "");
|
||||||
|
|
||||||
|
while(flag_def->name) {
|
||||||
|
if (ret_flag & flag_def->flag) {
|
||||||
|
if(flag_str[1])
|
||||||
|
sprintf(flag_str, "%s | %s", flag_str, flag_def->name);
|
||||||
|
else
|
||||||
|
strcpy(flag_str, flag_def->name);
|
||||||
|
}
|
||||||
|
flag_def++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get class name */
|
||||||
|
item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
|
||||||
|
Py_DECREF(item);
|
||||||
|
strcpy(class_name, _PyUnicode_AsString(item));
|
||||||
|
|
||||||
|
fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "execute" : "invoke", flag_str);
|
||||||
|
}
|
||||||
|
|
||||||
PyGILState_Release(gilstate);
|
PyGILState_Release(gilstate);
|
||||||
|
bpy_import_main_set(NULL);
|
||||||
|
|
||||||
return ret_flag;
|
return ret_flag;
|
||||||
}
|
}
|
||||||
@@ -321,7 +363,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
|||||||
/* api callbacks, detailed checks dont on adding */
|
/* api callbacks, detailed checks dont on adding */
|
||||||
if (PyObject_HasAttrString(py_class, "invoke"))
|
if (PyObject_HasAttrString(py_class, "invoke"))
|
||||||
ot->invoke= PYTHON_OT_invoke;
|
ot->invoke= PYTHON_OT_invoke;
|
||||||
if (PyObject_HasAttrString(py_class, "exec"))
|
if (PyObject_HasAttrString(py_class, "execute"))
|
||||||
ot->exec= PYTHON_OT_exec;
|
ot->exec= PYTHON_OT_exec;
|
||||||
if (PyObject_HasAttrString(py_class, "poll"))
|
if (PyObject_HasAttrString(py_class, "poll"))
|
||||||
ot->poll= PYTHON_OT_poll;
|
ot->poll= PYTHON_OT_poll;
|
||||||
@@ -374,6 +416,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
|||||||
PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
|
PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
|
||||||
{
|
{
|
||||||
PyObject *base_class, *item;
|
PyObject *base_class, *item;
|
||||||
|
wmOperatorType *ot;
|
||||||
|
|
||||||
|
|
||||||
char *idname= NULL;
|
char *idname= NULL;
|
||||||
@@ -384,8 +427,8 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
|
|||||||
{PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL},
|
{PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL},
|
||||||
{PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL},
|
{PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL},
|
||||||
{PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK},
|
{PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK},
|
||||||
{"exec", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
|
{"execute", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
|
||||||
{"invoke", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
|
{"invoke", 'f', 3, BPY_CLASS_ATTR_OPTIONAL},
|
||||||
{"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
|
{"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
|
||||||
{NULL, 0, 0, 0}
|
{NULL, 0, 0, 0}
|
||||||
};
|
};
|
||||||
@@ -404,9 +447,10 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
|
|||||||
Py_DECREF(item);
|
Py_DECREF(item);
|
||||||
idname = _PyUnicode_AsString(item);
|
idname = _PyUnicode_AsString(item);
|
||||||
|
|
||||||
if (WM_operatortype_find(idname)) {
|
/* remove if it already exists */
|
||||||
PyErr_Format( PyExc_AttributeError, "Operator alredy exists with this name \"%s\"", idname);
|
if ((ot=WM_operatortype_find(idname))) {
|
||||||
return NULL;
|
Py_XDECREF((PyObject*)ot->pyop_data);
|
||||||
|
WM_operatortype_remove(idname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have properties set, check its a list of dicts */
|
/* If we have properties set, check its a list of dicts */
|
||||||
|
@@ -1760,7 +1760,44 @@ PyObject *BPY_rna_types(void)
|
|||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct PyMethodDef props_methods[] = {
|
||||||
|
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||||
|
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||||
|
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||||
|
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
static struct PyModuleDef props_module = {
|
||||||
|
PyModuleDef_HEAD_INIT,
|
||||||
|
"bpyprops",
|
||||||
|
"",
|
||||||
|
-1,/* multiple "initialization" just copies the module dict. */
|
||||||
|
props_methods,
|
||||||
|
NULL, NULL, NULL, NULL
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PyObject *BPY_rna_props( void )
|
||||||
|
{
|
||||||
|
PyObject *submodule, *mod;
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
submodule= PyModule_Create(&props_module);
|
||||||
|
#else /* Py2.x */
|
||||||
|
submodule= Py_InitModule3( "bpy.props", props_methods, "" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mod = PyModule_New("props");
|
||||||
|
PyModule_AddObject( submodule, "props", mod );
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
/* Orphan functions, not sure where they should go */
|
/* Orphan functions, not sure where they should go */
|
||||||
|
|
||||||
@@ -1780,7 +1817,7 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self) {
|
if (self && PyCObject_Check(self)) {
|
||||||
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
||||||
RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
|
RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
@@ -1807,7 +1844,7 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self) {
|
if (self && PyCObject_Check(self)) {
|
||||||
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
||||||
RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max);
|
RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
@@ -1834,7 +1871,7 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self) {
|
if (self && PyCObject_Check(self)) {
|
||||||
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
||||||
RNA_def_boolean(srna, id, def, name, description);
|
RNA_def_boolean(srna, id, def, name, description);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
@@ -1847,6 +1884,33 @@ PyObject *BPy_BoolProperty(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="";
|
||||||
|
int maxlen=0;
|
||||||
|
|
||||||
|
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.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self && PyCObject_Check(self)) {
|
||||||
|
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
||||||
|
RNA_def_string(srna, id, def, maxlen, name, description);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
} else {
|
||||||
|
PyObject *ret = PyTuple_New(2);
|
||||||
|
PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_StringProperty, NULL));
|
||||||
|
PyTuple_SET_ITEM(ret, 1, kw);
|
||||||
|
Py_INCREF(kw);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------- Type Registration ------------------------*/
|
/*-------------------- Type Registration ------------------------*/
|
||||||
|
|
||||||
static int rna_function_arg_count(FunctionRNA *func)
|
static int rna_function_arg_count(FunctionRNA *func)
|
||||||
|
@@ -63,6 +63,7 @@ typedef struct {
|
|||||||
PyObject *BPY_rna_module( void );
|
PyObject *BPY_rna_module( void );
|
||||||
/*PyObject *BPY_rna_doc( void );*/
|
/*PyObject *BPY_rna_doc( void );*/
|
||||||
PyObject *BPY_rna_types( void );
|
PyObject *BPY_rna_types( void );
|
||||||
|
PyObject *BPY_rna_props( void );
|
||||||
|
|
||||||
PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr );
|
PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr );
|
||||||
PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop );
|
PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop );
|
||||||
@@ -76,6 +77,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop);
|
|||||||
PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw);
|
PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||||
PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw);
|
PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||||
PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw);
|
PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||||
|
PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw);
|
||||||
|
|
||||||
/* function for registering types */
|
/* function for registering types */
|
||||||
PyObject *pyrna_basetype_register(PyObject *self, PyObject *args);
|
PyObject *pyrna_basetype_register(PyObject *self, PyObject *args);
|
||||||
|
@@ -81,6 +81,7 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag)
|
|||||||
char *cstring;
|
char *cstring;
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
BPY_flag_def *fd;
|
BPY_flag_def *fd;
|
||||||
|
*flag = 0;
|
||||||
|
|
||||||
if (PySequence_Check(seq)) {
|
if (PySequence_Check(seq)) {
|
||||||
i= PySequence_Length(seq);
|
i= PySequence_Length(seq);
|
||||||
@@ -108,6 +109,9 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag)
|
|||||||
error_val= 1;
|
error_val= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*flag == 0)
|
||||||
|
error_val = 1;
|
||||||
|
|
||||||
if (error_val) {
|
if (error_val) {
|
||||||
char *buf = bpy_flag_error_str(flagdef);
|
char *buf = bpy_flag_error_str(flagdef);
|
||||||
PyErr_SetString(PyExc_AttributeError, buf);
|
PyErr_SetString(PyExc_AttributeError, buf);
|
||||||
|
Reference in New Issue
Block a user