merge with trunk at r21785, and also fixed stupid ngon normals bug
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_util.h"
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
@@ -65,7 +66,7 @@ static void bpy_init_modules( void )
|
||||
/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
|
||||
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() ); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
|
||||
PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experimental, consider this a test, especially PyCObject is not meant to be permanent
|
||||
|
||||
/* add the module so we can import it */
|
||||
@@ -159,28 +160,8 @@ void BPY_start_python_path(void)
|
||||
/* set the environment path */
|
||||
printf("found bundled python: %s\n", py_path_bundle);
|
||||
|
||||
#if (defined(WIN32) || defined(WIN64))
|
||||
#if defined(FREE_WINDOWS)
|
||||
{
|
||||
char py_path[FILE_MAXDIR + 11] = "";
|
||||
sprintf(py_path, "PYTHONPATH=%s", py_path_bundle);
|
||||
putenv(py_path);
|
||||
}
|
||||
#else
|
||||
_putenv_s("PYTHONPATH", py_path_bundle);
|
||||
#endif
|
||||
#else
|
||||
#ifdef __sgi
|
||||
{
|
||||
char py_path[FILE_MAXDIR + 11] = "";
|
||||
sprintf(py_path, "PYTHONPATH=%s", py_path_bundle);
|
||||
putenv(py_path);
|
||||
}
|
||||
#else
|
||||
setenv("PYTHONPATH", py_path_bundle, 1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
BLI_setenv("PYTHONHOME", py_path_bundle);
|
||||
BLI_setenv("PYTHONPATH", py_path_bundle);
|
||||
}
|
||||
|
||||
|
||||
@@ -441,6 +422,26 @@ int BPY_run_python_script_space(const char *modulename, const char *func)
|
||||
#include "PIL_time.h"
|
||||
#endif
|
||||
|
||||
/* for use by BPY_run_ui_scripts only */
|
||||
static int bpy_import_module(char *modname, int reload)
|
||||
{
|
||||
PyObject *mod= PyImport_ImportModuleLevel(modname, 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 */
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX this is temporary, need a proper script registration system for 2.5 */
|
||||
void BPY_run_ui_scripts(bContext *C, int reload)
|
||||
{
|
||||
@@ -452,11 +453,10 @@ void BPY_run_ui_scripts(bContext *C, int reload)
|
||||
char *file_extension;
|
||||
char *dirname;
|
||||
char path[FILE_MAX];
|
||||
char *dirs[] = {"io", "ui", NULL};
|
||||
int a;
|
||||
char *dirs[] = {"ui", "io", NULL};
|
||||
int a, err;
|
||||
|
||||
PyGILState_STATE gilstate;
|
||||
PyObject *mod;
|
||||
PyObject *sys_path;
|
||||
|
||||
gilstate = PyGILState_Ensure();
|
||||
@@ -486,27 +486,35 @@ void BPY_run_ui_scripts(bContext *C, int reload)
|
||||
while((de = readdir(dir)) != NULL) {
|
||||
/* We could stat the file but easier just to let python
|
||||
* import it and complain if theres a problem */
|
||||
err = 0;
|
||||
|
||||
file_extension = strstr(de->d_name, ".py");
|
||||
|
||||
if(file_extension && file_extension[3] == '\0') {
|
||||
BLI_strncpy(path, de->d_name, (file_extension - de->d_name) + 1); /* 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);
|
||||
fprintf(stderr, "unable to import \"%s\" %s/%s\n", path, dirname, de->d_name);
|
||||
if (de->d_name[0] == '.') {
|
||||
/* do nothing, probably .svn */
|
||||
}
|
||||
else if ((file_extension = strstr(de->d_name, ".py"))) {
|
||||
/* normal py files? */
|
||||
if(file_extension && file_extension[3] == '\0') {
|
||||
de->d_name[(file_extension - de->d_name)] = '\0';
|
||||
err= bpy_import_module(de->d_name, reload);
|
||||
}
|
||||
}
|
||||
#ifndef __linux__
|
||||
else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exists(path))) {
|
||||
#else
|
||||
else if(de->d_type==DT_DIR) {
|
||||
BLI_join_dirfile(path, dirname, de->d_name);
|
||||
#endif
|
||||
/* support packages */
|
||||
BLI_join_dirfile(path, path, "__init__.py");
|
||||
|
||||
if(BLI_exists(path)) {
|
||||
err= bpy_import_module(de->d_name, reload);
|
||||
}
|
||||
}
|
||||
|
||||
if(err==-1) {
|
||||
BPy_errors_to_report(NULL);
|
||||
fprintf(stderr, "unable to import %s/%s\n", dirname, de->d_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
/**
|
||||
* $Id: bpy_operator.c 21554 2009-07-13 08:33:51Z campbellbarton $
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* msdfdsfdsodify it under the terms of the GNU General Public License
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
@@ -23,65 +23,79 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/* Note, this module is not to be used directly by the user.
|
||||
* its accessed from blender with bpy.__ops__
|
||||
* */
|
||||
|
||||
#include "bpy_operator.h"
|
||||
#include "bpy_operator_wrap.h"
|
||||
#include "bpy_rna.h" /* for setting arg props only - pyrna_py_to_prop() */
|
||||
#include "bpy_compat.h"
|
||||
#include "bpy_util.h"
|
||||
|
||||
//#include "blendef.h"
|
||||
#include "BLI_dynstr.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
//#include "BKE_idprop.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
extern ListBase global_ops; /* evil, temp use */
|
||||
|
||||
static PyObject *pyop_base_dir(PyObject *self);
|
||||
static PyObject *pyop_base_rna(PyObject *self, PyObject *pyname);
|
||||
static struct PyMethodDef pyop_base_methods[] = {
|
||||
{"__dir__", (PyCFunction)pyop_base_dir, METH_NOARGS, ""},
|
||||
{"__rna__", (PyCFunction)pyop_base_rna, METH_O, ""},
|
||||
{"add", (PyCFunction)PYOP_wrap_add, METH_O, ""},
|
||||
{"remove", (PyCFunction)PYOP_wrap_remove, METH_O, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
/* 'self' stores the operator string */
|
||||
static PyObject *pyop_base_call( PyObject * self, PyObject * args, PyObject * kw)
|
||||
static PyObject *pyop_call( PyObject * self, PyObject * args)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
int error_val = 0;
|
||||
PointerRNA ptr;
|
||||
|
||||
char *opname;
|
||||
PyObject *kw= NULL;
|
||||
|
||||
// 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();
|
||||
|
||||
char *opname = _PyUnicode_AsString(self);
|
||||
|
||||
if (PyTuple_Size(args)) {
|
||||
PyErr_SetString( PyExc_AttributeError, "All operator args must be keywords");
|
||||
switch(PyTuple_Size(args)) {
|
||||
case 2:
|
||||
kw = PyTuple_GET_ITEM(args, 1);
|
||||
|
||||
if(!PyDict_Check(kw)) {
|
||||
PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected second arg to be a dict");
|
||||
return NULL;
|
||||
}
|
||||
/* pass through */
|
||||
case 1:
|
||||
opname = _PyUnicode_AsString(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
if(opname==NULL) {
|
||||
PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected the first arg to be a string");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected a string and optional dict");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ot= WM_operatortype_find(opname, 1);
|
||||
|
||||
if (ot == NULL) {
|
||||
PyErr_Format( PyExc_SystemError, "Operator \"%s\"could not be found", opname);
|
||||
PyErr_Format( PyExc_SystemError, "bpy.__ops__.call: operator \"%s\"could not be found", opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ot->poll && (ot->poll(C) == 0)) {
|
||||
PyErr_SetString( PyExc_SystemError, "Operator poll() function failed, context is incorrect");
|
||||
PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WM_operator_properties_create(&ptr, opname);
|
||||
/* WM_operator_properties_create(&ptr, opname); */
|
||||
/* Save another lookup */
|
||||
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
|
||||
|
||||
error_val= pyrna_pydict_to_props(&ptr, kw, "Converting py args to operator properties: ");
|
||||
if(kw && PyDict_Size(kw))
|
||||
error_val= pyrna_pydict_to_props(&ptr, kw, "Converting py args to operator properties: ");
|
||||
|
||||
|
||||
if (error_val==0) {
|
||||
ReportList reports;
|
||||
@@ -118,101 +132,34 @@ static PyObject *pyop_base_call( PyObject * self, PyObject * args, PyObject * k
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef pyop_base_call_meth[] = {
|
||||
{"__op_call__", (PyCFunction)pyop_base_call, METH_VARARGS|METH_KEYWORDS, "generic operator calling function"}
|
||||
};
|
||||
|
||||
|
||||
//---------------getattr--------------------------------------------
|
||||
static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname )
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
PyObject *ret;
|
||||
wmOperatorType *ot;
|
||||
|
||||
/* First look for the operator, then our own methods if that fails.
|
||||
* when methods are searched first, PyObject_GenericGetAttr will raise an error
|
||||
* each time we want to call an operator, we could clear the error but I prefer
|
||||
* not to since calling operators is a lot more common then adding and removing. - Campbell */
|
||||
|
||||
if ((ot= WM_operatortype_find(name, 1))) {
|
||||
ret = PyCFunction_New( pyop_base_call_meth, pyname); /* set the name string as self, PyCFunction_New incref's self */
|
||||
}
|
||||
else if ((ret = PyObject_GenericGetAttr((PyObject *)self, pyname))) {
|
||||
/* do nothing, this accounts for methoddef's add and remove
|
||||
* An exception is raised when PyObject_GenericGetAttr fails
|
||||
* but its ok because its overwritten below */
|
||||
}
|
||||
else {
|
||||
PyErr_Format( PyExc_AttributeError, "Operator \"%s\" not found", name);
|
||||
ret= NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *pyop_base_dir(PyObject *self)
|
||||
static PyObject *pyop_dir(PyObject *self)
|
||||
{
|
||||
PyObject *list = PyList_New(0), *name;
|
||||
wmOperatorType *ot;
|
||||
PyMethodDef *meth;
|
||||
|
||||
for(ot= WM_operatortype_first(); ot; ot= ot->next) {
|
||||
name = PyUnicode_FromString(ot->idname);
|
||||
PyList_Append(list, name);
|
||||
Py_DECREF(name);
|
||||
}
|
||||
|
||||
for(meth=pyop_base_methods; meth->ml_name; meth++) {
|
||||
name = PyUnicode_FromString(meth->ml_name);
|
||||
PyList_Append(list, name);
|
||||
Py_DECREF(name);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static PyObject *pyop_base_rna(PyObject *self, PyObject *pyname)
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
wmOperatorType *ot;
|
||||
|
||||
if ((ot= WM_operatortype_find(name, 1))) {
|
||||
BPy_StructRNA *pyrna;
|
||||
PointerRNA ptr;
|
||||
|
||||
/* XXX POINTER - if this 'ot' is python generated, it could be free'd */
|
||||
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
|
||||
|
||||
pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); /* were not really using &ptr, overwite next */
|
||||
//pyrna->freeptr= 1;
|
||||
return (PyObject *)pyrna;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_AttributeError, "Operator \"%s\" not found", name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PyTypeObject pyop_base_Type = {NULL};
|
||||
|
||||
PyObject *BPY_operator_module( void )
|
||||
{
|
||||
PyObject *ob;
|
||||
static PyMethodDef pyop_call_meth = {"call", (PyCFunction) pyop_call, METH_VARARGS, NULL};
|
||||
static PyMethodDef pyop_dir_meth = {"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL};
|
||||
static PyMethodDef pyop_add_meth = {"add", (PyCFunction) PYOP_wrap_add, METH_O, NULL};
|
||||
static PyMethodDef pyop_remove_meth = {"remove", (PyCFunction) PYOP_wrap_remove, METH_O, NULL};
|
||||
|
||||
pyop_base_Type.tp_name = "OperatorBase";
|
||||
pyop_base_Type.tp_basicsize = sizeof( BPy_OperatorBase );
|
||||
pyop_base_Type.tp_getattro = ( getattrofunc )pyop_base_getattro;
|
||||
pyop_base_Type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
pyop_base_Type.tp_methods = pyop_base_methods;
|
||||
|
||||
if( PyType_Ready( &pyop_base_Type ) < 0 )
|
||||
return NULL;
|
||||
PyObject *submodule = PyModule_New("bpy.__ops__");
|
||||
PyDict_SetItemString(PySys_GetObject("modules"), "bpy.__ops__", submodule);
|
||||
|
||||
//submodule = Py_InitModule3( "operator", M_rna_methods, "rna module" );
|
||||
ob = PyObject_NEW( BPy_OperatorBase, &pyop_base_Type );
|
||||
Py_INCREF(ob);
|
||||
PyModule_AddObject( submodule, "call", PyCFunction_New(&pyop_call_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "dir", PyCFunction_New(&pyop_dir_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "add", PyCFunction_New(&pyop_add_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "remove", PyCFunction_New(&pyop_remove_meth, NULL) );
|
||||
|
||||
return ob;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
/**
|
||||
* $Id: bpy_operator_wrap.c 21440 2009-07-08 21:31:28Z blendix $
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -44,8 +44,10 @@
|
||||
|
||||
#define PYOP_ATTR_PROP "__props__"
|
||||
#define PYOP_ATTR_UINAME "__label__"
|
||||
#define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */
|
||||
#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 */
|
||||
|
||||
static struct BPY_flag_def pyop_ret_flags[] = {
|
||||
{"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
|
||||
@@ -190,6 +192,8 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
#if 0 /* only for testing */
|
||||
|
||||
/* print operator return value */
|
||||
if (mode != PYOP_POLL) {
|
||||
char flag_str[100];
|
||||
@@ -210,11 +214,12 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
||||
|
||||
/* get class name */
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
|
||||
Py_DECREF(item);
|
||||
strcpy(class_name, _PyUnicode_AsString(item));
|
||||
Py_DECREF(item);
|
||||
|
||||
fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "execute" : "invoke", flag_str);
|
||||
}
|
||||
#endif
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
bpy_import_main_set(NULL);
|
||||
@@ -245,15 +250,14 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
PyObject *props, *item;
|
||||
|
||||
/* identifiers */
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
|
||||
Py_DECREF(item);
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME_BL);
|
||||
ot->idname= _PyUnicode_AsString(item);
|
||||
|
||||
Py_DECREF(item);
|
||||
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
|
||||
if (item) {
|
||||
Py_DECREF(item);
|
||||
ot->name= _PyUnicode_AsString(item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
else {
|
||||
ot->name= ot->idname;
|
||||
@@ -261,8 +265,8 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
}
|
||||
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
|
||||
Py_DECREF(item);
|
||||
ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"";
|
||||
Py_DECREF(item);
|
||||
|
||||
/* api callbacks, detailed checks dont on adding */
|
||||
if (PyObject_HasAttrString(py_class, "invoke"))
|
||||
@@ -274,13 +278,22 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
|
||||
ot->pyop_data= userdata;
|
||||
|
||||
/* flags */
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_REGISTER);
|
||||
if (item) {
|
||||
ot->flag= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0;
|
||||
Py_DECREF(item);
|
||||
}
|
||||
else {
|
||||
ot->flag= OPTYPE_REGISTER; /* unspesified, leave on for now to help debug */
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
|
||||
|
||||
if (props) {
|
||||
PyObject *dummy_args = PyTuple_New(0);
|
||||
int i;
|
||||
|
||||
Py_DECREF(props);
|
||||
|
||||
for(i=0; i<PyList_Size(props); i++) {
|
||||
PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
|
||||
@@ -310,6 +323,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
// expect a tuple with a CObject and a dict
|
||||
}
|
||||
Py_DECREF(dummy_args);
|
||||
Py_DECREF(props);
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
@@ -324,32 +338,44 @@ 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', 0, 0},
|
||||
{PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK},
|
||||
{"execute", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{"invoke", 'f', 3, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{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},
|
||||
{"poll", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
// in python would be...
|
||||
//PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
|
||||
base_class = PyObject_GetAttrStringArgs(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), 2, "types", "Operator");
|
||||
Py_DECREF(base_class);
|
||||
|
||||
if(BPY_class_validate("Operator", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
|
||||
return NULL; /* BPY_class_validate sets the error */
|
||||
}
|
||||
Py_DECREF(base_class);
|
||||
|
||||
/* class name is used for operator ID - this can be changed later if we want */
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
|
||||
Py_DECREF(item);
|
||||
idname = _PyUnicode_AsString(item);
|
||||
|
||||
|
||||
/* annoying conversion! */
|
||||
WM_operator_bl_idname(idname_bl, idname);
|
||||
Py_DECREF(item);
|
||||
|
||||
item= PyUnicode_FromString(idname_bl);
|
||||
PyObject_SetAttrString(py_class, PYOP_ATTR_IDNAME_BL, item);
|
||||
idname = _PyUnicode_AsString(item);
|
||||
Py_DECREF(item);
|
||||
/* end annoying conversion! */
|
||||
|
||||
|
||||
/* remove if it already exists */
|
||||
if ((ot=WM_operatortype_exists(idname))) {
|
||||
@@ -362,7 +388,6 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
|
||||
/* If we have properties set, check its a list of dicts */
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
|
||||
if (item) {
|
||||
Py_DECREF(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 */
|
||||
@@ -372,6 +397,7 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Py_DECREF(item);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: bpy_rna.c 21564 2009-07-13 19:33:59Z campbellbarton $
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -367,7 +367,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
ret = pyrna_prop_CreatePyObject(ptr, prop);
|
||||
break;
|
||||
default:
|
||||
PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type);
|
||||
PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type);
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -392,7 +392,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi
|
||||
if (strcmp(arg_name, "rna_type")==0) continue;
|
||||
|
||||
if (kw==NULL) {
|
||||
PyErr_Format( PyExc_AttributeError, "%.200s: no keywords, expected \"%.200s\"", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
PyErr_Format( PyExc_TypeError, "%.200s: no keywords, expected \"%.200s\"", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
error_val= -1;
|
||||
break;
|
||||
}
|
||||
@@ -400,7 +400,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi
|
||||
item= PyDict_GetItemString(kw, arg_name);
|
||||
|
||||
if (item == NULL) {
|
||||
PyErr_Format( PyExc_AttributeError, "%.200s: keyword \"%.200s\" missing", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
PyErr_Format( PyExc_TypeError, "%.200s: keyword \"%.200s\" missing", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
error_val = -1; /* pyrna_py_to_prop sets the error */
|
||||
break;
|
||||
}
|
||||
@@ -424,7 +424,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi
|
||||
arg_name= NULL;
|
||||
}
|
||||
|
||||
PyErr_Format( PyExc_AttributeError, "%.200s: keyword \"%.200s\" unrecognized", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
PyErr_Format( PyExc_TypeError, "%.200s: keyword \"%.200s\" unrecognized", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
error_val = -1;
|
||||
}
|
||||
|
||||
@@ -436,9 +436,16 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
PyObject *pyrna_func_to_py(BPy_StructRNA *pyrna, FunctionRNA *func)
|
||||
{
|
||||
static PyMethodDef func_meth = {"<generic rna function>", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"};
|
||||
PyObject *self= PyTuple_New(2);
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
|
||||
if(func==NULL) {
|
||||
PyErr_Format( PyExc_RuntimeError, "%.200s: type attempted to get NULL function", RNA_struct_identifier(pyrna->ptr.type));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self= PyTuple_New(2);
|
||||
|
||||
PyTuple_SET_ITEM(self, 0, (PyObject *)pyrna);
|
||||
Py_INCREF(pyrna);
|
||||
|
||||
@@ -482,7 +489,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
/* done getting the length */
|
||||
|
||||
if (py_len != len) {
|
||||
PyErr_Format(PyExc_AttributeError, "python sequence length %d did not match the RNA array length %d.", py_len, len);
|
||||
PyErr_Format(PyExc_TypeError, "python sequence length %d did not match the RNA array length %d.", py_len, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -492,7 +499,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
{
|
||||
int *param_arr;
|
||||
if(data) param_arr= (int*)data;
|
||||
else param_arr= MEM_mallocN(sizeof(char) * len, "pyrna bool array");
|
||||
else param_arr= MEM_mallocN(sizeof(int) * len, "pyrna bool array");
|
||||
|
||||
|
||||
/* collect the variables before assigning, incase one of them is incorrect */
|
||||
@@ -647,7 +654,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
else RNA_property_enum_set(ptr, prop, val);
|
||||
} else {
|
||||
char *enum_str= pyrna_enum_as_string(ptr, prop);
|
||||
PyErr_Format(PyExc_AttributeError, "enum \"%.200s\" not found in (%.200s)", param, enum_str);
|
||||
PyErr_Format(PyExc_TypeError, "enum \"%.200s\" not found in (%.200s)", param, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return -1;
|
||||
}
|
||||
@@ -1807,7 +1814,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
|
||||
PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble( ((float*)data)[a] ));
|
||||
break;
|
||||
default:
|
||||
PyErr_Format(PyExc_AttributeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
|
||||
PyErr_Format(PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -1889,7 +1896,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
|
||||
PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -1904,25 +1911,42 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
FunctionRNA *self_func= PyCObject_AsVoidPtr(PyTuple_GET_ITEM(self, 1));
|
||||
|
||||
PointerRNA funcptr;
|
||||
ParameterList *parms;
|
||||
ParameterList parms;
|
||||
ParameterIterator iter;
|
||||
PropertyRNA *pret, *parm;
|
||||
PyObject *ret, *item;
|
||||
int i, tlen, flag, err= 0;
|
||||
const char *tid, *fid, *pid;
|
||||
int i, args_len, parms_len, flag, err= 0, kw_tot= 0;
|
||||
const char *parm_id;
|
||||
void *retdata= NULL;
|
||||
|
||||
/* Should never happen but it does in rare cases */
|
||||
if(self_ptr==NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "rna functions internal rna pointer is NULL, this is a bug. aborting");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(self_func==NULL) {
|
||||
PyErr_Format(PyExc_RuntimeError, "%.200s.???(): rna function internal function is NULL, this is a bug. aborting", RNA_struct_identifier(self_ptr->type));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* setup */
|
||||
RNA_pointer_create(NULL, &RNA_Function, self_func, &funcptr);
|
||||
|
||||
pret= RNA_function_return(self_func);
|
||||
tlen= PyTuple_GET_SIZE(args);
|
||||
args_len= PyTuple_GET_SIZE(args);
|
||||
|
||||
parms= RNA_parameter_list_create(self_ptr, self_func);
|
||||
RNA_parameter_list_begin(parms, &iter);
|
||||
RNA_parameter_list_create(&parms, self_ptr, self_func);
|
||||
RNA_parameter_list_begin(&parms, &iter);
|
||||
parms_len = RNA_parameter_list_size(&parms);
|
||||
|
||||
if(args_len + (kw ? PyDict_Size(kw):0) > parms_len) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): takes at most %d arguments, got %d", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parms_len, args_len);
|
||||
err= -1;
|
||||
}
|
||||
|
||||
/* parse function parameters */
|
||||
for (i= 0; iter.valid; RNA_parameter_list_next(&iter)) {
|
||||
for (i= 0; iter.valid && err==0; RNA_parameter_list_next(&iter)) {
|
||||
parm= iter.parm;
|
||||
|
||||
if (parm==pret) {
|
||||
@@ -1930,27 +1954,27 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
continue;
|
||||
}
|
||||
|
||||
pid= RNA_property_identifier(parm);
|
||||
parm_id= RNA_property_identifier(parm);
|
||||
flag= RNA_property_flag(parm);
|
||||
item= NULL;
|
||||
|
||||
if ((i < tlen) && (flag & PROP_REQUIRED)) {
|
||||
if ((i < args_len) && (flag & PROP_REQUIRED)) {
|
||||
item= PyTuple_GET_ITEM(args, i);
|
||||
i++;
|
||||
}
|
||||
else if (kw != NULL)
|
||||
item= PyDict_GetItemString(kw, pid); /* borrow ref */
|
||||
else if (kw != NULL) {
|
||||
item= PyDict_GetItemString(kw, parm_id); /* borrow ref */
|
||||
if(item)
|
||||
kw_tot++; /* make sure invalid keywords are not given */
|
||||
}
|
||||
|
||||
if (item==NULL) {
|
||||
if(flag & PROP_REQUIRED) {
|
||||
tid= RNA_struct_identifier(self_ptr->type);
|
||||
fid= RNA_function_identifier(self_func);
|
||||
|
||||
PyErr_Format(PyExc_AttributeError, "%.200s.%.200s(): required parameter \"%.200s\" not specified", tid, fid, pid);
|
||||
PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): required parameter \"%.200s\" not specified", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parm_id);
|
||||
err= -1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
else /* PyDict_GetItemString wont raise an error */
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1960,6 +1984,73 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Check if we gave args that dont exist in the function
|
||||
* printing the error is slow but it should only happen when developing.
|
||||
* the if below is quick, checking if it passed less keyword args then we gave */
|
||||
if(kw && (PyDict_Size(kw) > kw_tot)) {
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
|
||||
DynStr *bad_args= BLI_dynstr_new();
|
||||
DynStr *good_args= BLI_dynstr_new();
|
||||
|
||||
char *arg_name, *bad_args_str, *good_args_str;
|
||||
int found= 0, first=1;
|
||||
|
||||
while (PyDict_Next(kw, &pos, &key, &value)) {
|
||||
|
||||
arg_name= _PyUnicode_AsString(key);
|
||||
found= 0;
|
||||
|
||||
if(arg_name==NULL) { /* unlikely the argname is not a string but ignore if it is*/
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
/* Search for arg_name */
|
||||
RNA_parameter_list_begin(&parms, &iter);
|
||||
for(; iter.valid; RNA_parameter_list_next(&iter)) {
|
||||
parm= iter.parm;
|
||||
if (strcmp(arg_name, RNA_property_identifier(parm))==0) {
|
||||
found= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RNA_parameter_list_end(&iter);
|
||||
|
||||
if(!found) {
|
||||
BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name);
|
||||
first= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* list good args */
|
||||
first= 1;
|
||||
|
||||
RNA_parameter_list_begin(&parms, &iter);
|
||||
for(; iter.valid; RNA_parameter_list_next(&iter)) {
|
||||
parm= iter.parm;
|
||||
BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
|
||||
first= 0;
|
||||
}
|
||||
RNA_parameter_list_end(&iter);
|
||||
|
||||
|
||||
bad_args_str= BLI_dynstr_get_cstring(bad_args);
|
||||
good_args_str= BLI_dynstr_get_cstring(good_args);
|
||||
|
||||
PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): was called with invalid keyword arguments(s) (%s), expected (%s)", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), bad_args_str, good_args_str);
|
||||
|
||||
BLI_dynstr_free(bad_args);
|
||||
BLI_dynstr_free(good_args);
|
||||
MEM_freeN(bad_args_str);
|
||||
MEM_freeN(good_args_str);
|
||||
|
||||
err= -1;
|
||||
}
|
||||
|
||||
ret= NULL;
|
||||
if (err==0) {
|
||||
/* call function */
|
||||
@@ -1967,20 +2058,26 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
bContext *C= BPy_GetContext();
|
||||
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
RNA_function_call(C, &reports, self_ptr, self_func, parms);
|
||||
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
|
||||
|
||||
err= (BPy_reports_to_error(&reports))? -1: 0;
|
||||
BKE_reports_clear(&reports);
|
||||
|
||||
/* return value */
|
||||
if(err==0)
|
||||
if(pret)
|
||||
if(err==0) {
|
||||
if(pret) {
|
||||
ret= pyrna_param_to_py(&funcptr, pret, retdata);
|
||||
|
||||
/* possible there is an error in conversion */
|
||||
if(ret==NULL)
|
||||
err= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
RNA_parameter_list_end(&iter);
|
||||
RNA_parameter_list_free(parms);
|
||||
RNA_parameter_list_free(&parms);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -2185,6 +2282,15 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
||||
/* done with rna instance */
|
||||
}
|
||||
|
||||
static struct PyMethodDef pyrna_struct_subtype_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}
|
||||
};
|
||||
|
||||
|
||||
PyObject* pyrna_srna_Subtype(StructRNA *srna)
|
||||
{
|
||||
PyObject *newclass = NULL;
|
||||
@@ -2261,6 +2367,17 @@ PyObject* pyrna_srna_Subtype(StructRNA *srna)
|
||||
if (newclass) {
|
||||
pyrna_subtype_set_rna(newclass, srna);
|
||||
// PyObSpit("NewStructRNA Type: ", (PyObject *)newclass);
|
||||
|
||||
/* attach functions into the class
|
||||
* so you can do... bpy.types.Scene.SomeFunction()
|
||||
*/
|
||||
{
|
||||
PyMethodDef *ml;
|
||||
for(ml= pyrna_struct_subtype_methods; ml->ml_name; ml++){
|
||||
PyObject_SetAttrString(newclass, ml->ml_name, PyCFunction_New(ml, newclass));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* this should not happen */
|
||||
@@ -2294,7 +2411,6 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
|
||||
else {
|
||||
fprintf(stderr, "Could not make type\n");
|
||||
pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
|
||||
Py_INCREF(pyrna);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2316,7 +2432,6 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
|
||||
BPy_PropertyRNA *pyrna;
|
||||
|
||||
pyrna = ( BPy_PropertyRNA * ) PyObject_NEW( BPy_PropertyRNA, &pyrna_prop_Type );
|
||||
Py_INCREF(pyrna);
|
||||
|
||||
if( !pyrna ) {
|
||||
PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_rna object" );
|
||||
@@ -2389,7 +2504,7 @@ static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA * self, PyObject *pyna
|
||||
return ret;
|
||||
}
|
||||
else { /* Override the error */
|
||||
PyErr_Format(PyExc_AttributeError, "bpy.types.%.200s not a valid RNA_Struct", _PyUnicode_AsString(pyname));
|
||||
PyErr_Format(PyExc_AttributeError, "bpy.types.%.200s RNA_Struct does not exist", _PyUnicode_AsString(pyname));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -2436,8 +2551,7 @@ PyObject *BPY_rna_types(void)
|
||||
}
|
||||
|
||||
self= (BPy_BaseTypeRNA *)PyObject_NEW( BPy_BaseTypeRNA, &pyrna_basetype_Type );
|
||||
Py_INCREF(self);
|
||||
|
||||
|
||||
/* avoid doing this lookup for every getattr */
|
||||
RNA_blender_rna_pointer_create(&self->ptr);
|
||||
self->prop = RNA_struct_find_property(&self->ptr, "structs");
|
||||
@@ -2456,7 +2570,7 @@ static struct PyMethodDef props_methods[] = {
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
static struct PyModuleDef props_module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bpyprops",
|
||||
"bpy.props",
|
||||
"",
|
||||
-1,/* multiple "initialization" just copies the module dict. */
|
||||
props_methods,
|
||||
@@ -2466,16 +2580,13 @@ static struct PyModuleDef props_module = {
|
||||
|
||||
PyObject *BPY_rna_props( void )
|
||||
{
|
||||
PyObject *submodule, *mod;
|
||||
PyObject *submodule;
|
||||
#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 */
|
||||
@@ -2493,6 +2604,7 @@ 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="";
|
||||
float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f;
|
||||
PropertyRNA *prop;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
|
||||
return NULL;
|
||||
@@ -2504,8 +2616,26 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
|
||||
if (self && PyCObject_Check(self)) {
|
||||
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
||||
RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
|
||||
prop= RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
|
||||
RNA_def_property_duplicate_pointers(prop);
|
||||
Py_RETURN_NONE;
|
||||
} else if(self && PyType_Check(self)) {
|
||||
PyObject *pyob= PyObject_GetAttrString(self, "__rna__");
|
||||
|
||||
if(pyob && BPy_StructRNA_Check(pyob)) {
|
||||
BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob;
|
||||
|
||||
if(py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) {
|
||||
if(RNA_struct_is_ID(py_srna->ptr.data)) {
|
||||
prop= RNA_def_float(py_srna->ptr.data, id, def, min, max, name, description, soft_min, soft_max);
|
||||
RNA_def_property_duplicate_pointers(prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, "only works on ID types");
|
||||
return NULL;
|
||||
} else {
|
||||
PyObject *ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_FloatProperty, NULL));
|
||||
@@ -2520,6 +2650,7 @@ 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="";
|
||||
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, def=0;
|
||||
PropertyRNA *prop;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
|
||||
return NULL;
|
||||
@@ -2531,8 +2662,26 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
|
||||
if (self && PyCObject_Check(self)) {
|
||||
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
||||
RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max);
|
||||
prop= RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max);
|
||||
RNA_def_property_duplicate_pointers(prop);
|
||||
Py_RETURN_NONE;
|
||||
} else if(self && PyType_Check(self)) {
|
||||
PyObject *pyob= PyObject_GetAttrString(self, "__rna__");
|
||||
|
||||
if(pyob && BPy_StructRNA_Check(pyob)) {
|
||||
BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob;
|
||||
|
||||
if(py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) {
|
||||
if(RNA_struct_is_ID(py_srna->ptr.data)) {
|
||||
prop= RNA_def_int(py_srna->ptr.data, id, def, min, max, name, description, soft_min, soft_max);
|
||||
RNA_def_property_duplicate_pointers(prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, "only works on ID types");
|
||||
return NULL;
|
||||
} else {
|
||||
PyObject *ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_IntProperty, NULL));
|
||||
@@ -2547,6 +2696,7 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
static char *kwlist[] = {"attr", "name", "description", "default", NULL};
|
||||
char *id, *name="", *description="";
|
||||
int def=0;
|
||||
PropertyRNA *prop;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def))
|
||||
return NULL;
|
||||
@@ -2555,11 +2705,29 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
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_boolean(srna, id, def, name, description);
|
||||
prop= RNA_def_boolean(srna, id, def, name, description);
|
||||
RNA_def_property_duplicate_pointers(prop);
|
||||
Py_RETURN_NONE;
|
||||
} else if(self && PyType_Check(self)) {
|
||||
PyObject *pyob= PyObject_GetAttrString(self, "__rna__");
|
||||
|
||||
if(pyob && BPy_StructRNA_Check(pyob)) {
|
||||
BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob;
|
||||
|
||||
if(py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) {
|
||||
if(RNA_struct_is_ID(py_srna->ptr.data)) {
|
||||
prop= RNA_def_boolean(py_srna->ptr.data, id, def, name, description);
|
||||
RNA_def_property_duplicate_pointers(prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, "only works on ID types");
|
||||
return NULL;
|
||||
} else {
|
||||
PyObject *ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_BoolProperty, NULL));
|
||||
@@ -2574,6 +2742,7 @@ 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;
|
||||
PropertyRNA *prop;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssis:StringProperty", kwlist, &id, &name, &description, &maxlen, &def))
|
||||
return NULL;
|
||||
@@ -2585,8 +2754,26 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
|
||||
if (self && PyCObject_Check(self)) {
|
||||
StructRNA *srna = PyCObject_AsVoidPtr(self);
|
||||
RNA_def_string(srna, id, def, maxlen, name, description);
|
||||
prop= RNA_def_string(srna, id, def, maxlen, name, description);
|
||||
RNA_def_property_duplicate_pointers(prop);
|
||||
Py_RETURN_NONE;
|
||||
} else if(self && PyType_Check(self)) {
|
||||
PyObject *pyob= PyObject_GetAttrString(self, "__rna__");
|
||||
|
||||
if(pyob && BPy_StructRNA_Check(pyob)) {
|
||||
BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob;
|
||||
|
||||
if(py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) {
|
||||
if(RNA_struct_is_ID(py_srna->ptr.data)) {
|
||||
prop= RNA_def_string(py_srna->ptr.data, id, def, maxlen, name, description);
|
||||
RNA_def_property_duplicate_pointers(prop);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, "only works on ID types");
|
||||
return NULL;
|
||||
} else {
|
||||
PyObject *ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_StringProperty, NULL));
|
||||
@@ -2632,7 +2819,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
|
||||
if (base_class) {
|
||||
if (!PyObject_IsSubclass(py_class, base_class)) {
|
||||
PyObject *name= PyObject_GetAttrString(base_class, "__name__");
|
||||
PyErr_Format( PyExc_AttributeError, "expected %.200s subclass of class \"%.200s\"", class_type, name ? _PyUnicode_AsString(name):"<UNKNOWN>");
|
||||
PyErr_Format( PyExc_TypeError, "expected %.200s subclass of class \"%.200s\"", class_type, name ? _PyUnicode_AsString(name):"<UNKNOWN>");
|
||||
Py_XDECREF(name);
|
||||
return -1;
|
||||
}
|
||||
@@ -2670,7 +2857,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
|
||||
fitem= item; /* py 3.x */
|
||||
|
||||
if (PyFunction_Check(fitem)==0) {
|
||||
PyErr_Format( PyExc_AttributeError, "expected %.200s class \"%.200s\" attribute to be a function", class_type, RNA_function_identifier(func));
|
||||
PyErr_Format( PyExc_TypeError, "expected %.200s class \"%.200s\" attribute to be a function", class_type, RNA_function_identifier(func));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2798,12 +2985,12 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
|
||||
}
|
||||
else {
|
||||
Py_DECREF(py_class_instance);
|
||||
PyErr_Format(PyExc_AttributeError, "could not find function %.200s in %.200s to execute callback.", RNA_function_identifier(func), RNA_struct_identifier(ptr->type));
|
||||
PyErr_Format(PyExc_TypeError, "could not find function %.200s in %.200s to execute callback.", RNA_function_identifier(func), RNA_struct_identifier(ptr->type));
|
||||
err= -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_AttributeError, "could not create instance of %.200s to call callback function %.200s.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func));
|
||||
PyErr_Format(PyExc_RuntimeError, "could not create instance of %.200s to call callback function %.200s.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func));
|
||||
err= -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: bpy_ui.c 21611 2009-07-16 00:50:27Z campbellbarton $
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -557,7 +557,7 @@ PyObject *BPY_ui_module( void )
|
||||
PyModule_AddObject( mod, "SCRIPT", PyLong_FromSsize_t(SPACE_SCRIPT) );
|
||||
PyModule_AddObject( mod, "TIME", PyLong_FromSsize_t(SPACE_TIME) );
|
||||
PyModule_AddObject( mod, "NODE", PyLong_FromSsize_t(SPACE_NODE) );
|
||||
//PyModule_AddObject( mod, "CONSOLE", PyLong_FromSsize_t(SPACE_CONSOLE) );
|
||||
PyModule_AddObject( mod, "CONSOLE", PyLong_FromSsize_t(SPACE_CONSOLE) );
|
||||
|
||||
/* INCREF since its its assumed that all these functions return the
|
||||
* module with a new ref like PyDict_New, since they are passed to
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: bpy_util.c 21526 2009-07-11 13:57:56Z campbellbarton $
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -304,12 +304,21 @@ int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_c
|
||||
PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute to be a string", class_type, class_attrs->name);
|
||||
return -1;
|
||||
}
|
||||
if(class_attrs->len != -1 && class_attrs->len < PyUnicode_GetSize(item)) {
|
||||
PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute string to be shorter then %d", class_type, class_attrs->name, class_attrs->len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'l':
|
||||
if (PyList_Check(item)==0) {
|
||||
PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute to be a list", class_type, class_attrs->name);
|
||||
return -1;
|
||||
}
|
||||
if(class_attrs->len != -1 && class_attrs->len < PyList_GET_SIZE(item)) {
|
||||
PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute list to be shorter then %d", class_type, class_attrs->name, class_attrs->len);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if (PyMethod_Check(item))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: bpy_util.h 21094 2009-06-23 00:09:26Z gsrb3d $
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -59,6 +59,7 @@ typedef struct BPY_class_attr_check {
|
||||
const char *name; /* name of the class attribute */
|
||||
char type; /* 's' = string, 'f' = function, 'l' = list, (add as needed) */
|
||||
int arg_count; /* only for function types, -1 for undefined, includes self arg */
|
||||
int len; /* only for string types currently */
|
||||
int flag; /* other options */
|
||||
} BPY_class_attr_check;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user