merge with 2.5 at r22793

This commit is contained in:
Joseph Eagar
2009-08-26 10:27:04 +00:00
994 changed files with 59413 additions and 26223 deletions

View File

@@ -1,5 +1,5 @@
#
# $Id: Makefile 21094 2009-06-23 00:09:26Z gsrb3d $
# $Id$
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
@@ -43,7 +43,7 @@ CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
# PreProcessor stuff
CPPFLAGS += -I$(NAN_GHOST)/include
CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include $(NAN_SDLCFLAGS)
CPPFLAGS += $(NAN_SDLCFLAGS)
# modules
CPPFLAGS += -I../../editors/include

View File

@@ -0,0 +1,235 @@
/**
*
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Contributor(s): Arystanbek Dyussenov
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "Python.h"
#include "bpy_rna.h"
#include "RNA_access.h"
#include "BLI_string.h"
#include "MEM_guardedalloc.h"
typedef void (*ItemConvertFunc)(PyObject *, char *);
typedef int (*ItemTypeCheckFunc)(PyObject *);
typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *);
/* Ensures that a python sequence has an expected number of items/sub-items and items are of expected type. */
static int pyrna_validate_array(PyObject *seq, unsigned short dim, unsigned short totdim, unsigned short dim_size[],
ItemTypeCheckFunc check_item_type, const char *item_type_str, char *error_str, int error_str_size)
{
int i;
if (dim < totdim) {
for (i= 0; i < PySequence_Length(seq); i++) {
PyObject *item;
int ok= 1;
item= PySequence_GetItem(seq, i);
if (!PySequence_Check(item)) {
BLI_snprintf(error_str, error_str_size, "expected a %d-dimensional sequence of %s", (int)totdim, item_type_str);
ok= 0;
}
else if (PySequence_Length(item) != dim_size[dim - 1]) {
BLI_snprintf(error_str, error_str_size, "dimension %d should contain %d items", (int)dim, (int)dim_size[dim - 1]);
ok= 0;
}
if (!pyrna_validate_array(item, dim + 1, totdim, dim_size, check_item_type, item_type_str, error_str, error_str_size)) {
ok= 0;
}
Py_DECREF(item);
if (!ok)
return 0;
}
}
else {
for (i= 0; i < PySequence_Length(seq); i++) {
PyObject *item= PySequence_GetItem(seq, i);
if (!check_item_type(item)) {
Py_DECREF(item);
BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str);
return 0;
}
Py_DECREF(item);
}
}
return 1;
}
/* Returns the number of items in a single- or multi-dimensional sequence. */
static int pyrna_count_items(PyObject *seq)
{
int totitem= 0;
if (PySequence_Check(seq)) {
int i;
for (i= 0; i < PySequence_Length(seq); i++) {
PyObject *item= PySequence_GetItem(seq, i);
totitem += pyrna_count_items(item);
Py_DECREF(item);
}
}
else
totitem= 1;
return totitem;
}
static int pyrna_apply_array_length(PointerRNA *ptr, PropertyRNA *prop, int totitem, char *error_str, int error_str_size)
{
if (RNA_property_flag(prop) & PROP_DYNAMIC) {
/* length can be flexible */
if (RNA_property_array_length(ptr, prop) != totitem) {
if (!RNA_property_dynamic_array_set_length(ptr, prop, totitem)) {
BLI_snprintf(error_str, error_str_size, "%s.%s: array length cannot be changed to %d", RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), totitem);
return 0;
}
}
}
else {
/* length is a constraint */
int len= RNA_property_array_length(ptr, prop);
if (totitem != len) {
BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len);
return 0;
}
}
return 1;
}
static char *pyrna_py_to_array(PyObject *seq, unsigned short dim, unsigned short totdim, char *data, unsigned int item_size, ItemConvertFunc convert_item)
{
unsigned int i;
for (i= 0; i < PySequence_Length(seq); i++) {
PyObject *item= PySequence_GetItem(seq, i);
if (dim < totdim) {
data= pyrna_py_to_array(item, dim + 1, totdim, data, item_size, convert_item);
}
else {
convert_item(item, data);
data += item_size;
}
Py_DECREF(item);
}
return data;
}
static int pyrna_py_to_array_generic(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size,
ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array)
{
unsigned short totdim, dim_size[100];
int totitem;
char *data= NULL;
totdim= RNA_property_array_dimension(prop, dim_size);
if (!pyrna_validate_array(py, 1, totdim, dim_size, check_item_type, item_type_str, error_str, error_str_size))
return 0;
totitem= pyrna_count_items(py);
if (!pyrna_apply_array_length(ptr, prop, totitem, error_str, error_str_size))
return 0;
if (totitem) {
if (!param_data || RNA_property_flag(prop) & PROP_DYNAMIC)
data= MEM_callocN(item_size * totitem, "pyrna primitive type array");
else
data= param_data;
pyrna_py_to_array(py, 1, totdim, data, item_size, convert_item);
if (param_data) {
if (RNA_property_flag(prop) & PROP_DYNAMIC) {
/* not freeing allocated mem, RNA_parameter_list_free will do this */
*(char**)param_data= data;
}
}
else {
/* NULL can only pass through in case RNA property arraylength is 0 (impossible?) */
rna_set_array(ptr, prop, data);
MEM_freeN(data);
}
}
return 1;
}
static void pyrna_py_to_float(PyObject *py, char *data)
{
*(float*)data= (float)PyFloat_AsDouble(py);
}
static void pyrna_py_to_int(PyObject *py, char *data)
{
*(int*)data= (int)PyLong_AsSsize_t(py);
}
static void pyrna_py_to_boolean(PyObject *py, char *data)
{
*(int*)data= (int)PyObject_IsTrue(py);
}
static int py_float_check(PyObject *py)
{
return PyFloat_Check(py);
}
static int py_int_check(PyObject *py)
{
return PyLong_Check(py);
}
static int py_bool_check(PyObject *py)
{
return PyBool_Check(py);
}
int pyrna_py_to_float_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
{
return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size,
py_float_check, "float", sizeof(float), pyrna_py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array);
}
int pyrna_py_to_int_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
{
return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size,
py_int_check, "int", sizeof(int), pyrna_py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array);
}
int pyrna_py_to_boolean_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
{
return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size,
py_bool_check, "boolean", sizeof(int), pyrna_py_to_boolean, (RNA_SetArrayFunc)RNA_property_boolean_set_array);
}

View File

@@ -1,126 +0,0 @@
/**
* $Id: bpy_compat.h 21427 2009-07-08 14:26:43Z ton $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
/* This file is only to contain definitions to functions that enable
* the python api to compile with different python versions.
* no utility functions please
*/
#ifndef BPY_COMPAT_H__
#define BPY_COMPAT_H__
/* if you are NOT using python 3.0 - define these */
#if PY_VERSION_HEX < 0x03000000
#define _PyUnicode_AsString PyString_AsString
#undef PyUnicode_Check
#define PyUnicode_Check PyString_Check
#define PyLong_FromSsize_t PyInt_FromLong
#define PyLong_AsSsize_t PyInt_AsLong
#undef PyLong_Check
#define PyLong_Check PyInt_Check
#ifdef PyUnicode_FromString
#undef PyUnicode_FromString
#endif
#define PyUnicode_FromString PyString_FromString
#ifdef PyUnicode_FromFormat
#undef PyUnicode_FromFormat
#endif
#define PyUnicode_FromFormat PyString_FromFormat
#endif
#ifndef Py_REFCNT
#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
#endif
#ifndef Py_TYPE
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif
#ifndef Py_TYPE
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
#endif
/* older then python 2.6 - define these */
// #if (PY_VERSION_HEX < 0x02060000)
// #endif
/* older then python 2.5 - define these */
#if (PY_VERSION_HEX < 0x02050000)
#define Py_ssize_t ssize_t
typedef Py_ssize_t (*lenfunc)(PyObject *);
#ifndef Py_RETURN_NONE
#define Py_RETURN_NONE return Py_BuildValue("O", Py_None)
#endif
#ifndef Py_RETURN_FALSE
#define Py_RETURN_FALSE return PyBool_FromLong(0)
#endif
#ifndef Py_RETURN_TRUE
#define Py_RETURN_TRUE return PyBool_FromLong(1)
#endif
#define PyInt_FromSsize_t PyInt_FromLong
#define PyNumber_AsSsize_t(ob, exc) PyInt_AsLong(ob)
#define PyIndex_Check(ob) PyInt_Check(ob)
#endif
#if PY_VERSION_HEX < 0x03000000
#ifndef ssizeargfunc
#define ssizeargfunc intargfunc
#endif
#ifndef ssizessizeargfunc
#define ssizessizeargfunc intintargfunc
#endif
#ifndef ssizeobjargproc
#define ssizeobjargproc intobjargproc
#endif
#ifndef ssizessizeobjargproc
#define ssizessizeobjargproc intintobjargproc
#endif
#endif
/* defined in bpy_util.c */
#if PY_VERSION_HEX < 0x03000000
PyObject *Py_CmpToRich(int op, int cmp);
#endif
#ifndef Py_CmpToRich
PyObject *Py_CmpToRich(int op, int cmp); /* bpy_util.c */
#endif
#endif /* BPY_COMPAT_H__ */

View File

@@ -14,8 +14,6 @@
#include "compile.h" /* for the PyCodeObject */
#include "eval.h" /* for PyEval_EvalCode */
#include "bpy_compat.h"
#include "bpy_rna.h"
#include "bpy_operator.h"
#include "bpy_ui.h"
@@ -45,6 +43,80 @@
#include "../generic/BGL.h"
/* for internal use, when starting and ending python scripts */
/* incase a python script triggers another python call, stop bpy_context_clear from invalidating */
static int py_call_level= 0;
// only for tests
#define TIME_PY_RUN
#ifdef TIME_PY_RUN
#include "PIL_time.h"
static int bpy_timer_count = 0;
static double bpy_timer; /* time since python starts */
static double bpy_timer_run; /* time for each python script run */
static double bpy_timer_run_tot; /* accumulate python runs */
#endif
void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
{
py_call_level++;
if(gilstate)
*gilstate = PyGILState_Ensure();
if(py_call_level==1) {
BPY_update_modules(); /* can give really bad results if this isnt here */
if(C) { // XXX - should always be true.
BPy_SetContext(C);
bpy_import_main_set(CTX_data_main(C));
}
else {
fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n");
}
#ifdef TIME_PY_RUN
if(bpy_timer_count==0) {
/* record time from the beginning */
bpy_timer= PIL_check_seconds_timer();
bpy_timer_run = bpy_timer_run_tot = 0.0;
}
bpy_timer_run= PIL_check_seconds_timer();
bpy_timer_count++;
#endif
}
}
void bpy_context_clear(bContext *C, PyGILState_STATE *gilstate)
{
py_call_level--;
if(gilstate)
PyGILState_Release(*gilstate);
if(py_call_level < 0) {
fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n");
}
else if(py_call_level==0) {
// XXX - Calling classes currently wont store the context :\, cant set NULL because of this. but this is very flakey still.
//BPy_SetContext(NULL);
//bpy_import_main_set(NULL);
#ifdef TIME_PY_RUN
bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run;
bpy_timer_count++;
#endif
}
}
void BPY_free_compiled_text( struct Text *text )
{
if( text->compiled ) {
@@ -75,23 +147,22 @@ static void bpy_init_modules( void )
/* stand alone utility modules not related to blender directly */
Geometry_Init("Geometry");
Mathutils_Init("Mathutils");
BGL_Init("BGL");
Geometry_Init();
Mathutils_Init();
BGL_Init();
}
#if (PY_VERSION_HEX < 0x02050000)
PyObject *PyImport_ImportModuleLevel(char *name, void *a, void *b, void *c, int d)
{
return PyImport_ImportModule(name);
}
#endif
void BPY_update_modules( void )
{
#if 0 // slow, this runs all the time poll, draw etc 100's of time a sec.
PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
PyModule_AddObject( mod, "data", BPY_rna_module() );
PyModule_AddObject( mod, "types", BPY_rna_types() );
PyModule_AddObject( mod, "types", BPY_rna_types() ); // atm this does not need updating
#endif
/* refreshes the main struct */
BPY_update_rna_module();
}
/*****************************************************************************
@@ -106,9 +177,6 @@ static PyObject *CreateGlobalDictionary( bContext *C )
PyDict_SetItemString( dict, "__name__", item );
Py_DECREF(item);
// XXX - evil, need to access context
BPy_SetContext(C);
// XXX - put somewhere more logical
{
PyMethodDef *ml;
@@ -173,9 +241,10 @@ void BPY_start_python( int argc, char **argv )
Py_Initialize( );
#if (PY_VERSION_HEX < 0x03000000)
PySys_SetArgv( argc, argv);
#else
/*convert argv to wchar_t*/
// PySys_SetArgv( argc, argv); // broken in py3, not a huge deal
/*temporarily set argv*/
/* sigh, why do python guys not have a char** version anymore? :( */
{
int i;
@@ -187,7 +256,6 @@ void BPY_start_python( int argc, char **argv )
PySys_SetObject("argv", py_argv);
Py_DECREF(py_argv);
}
#endif
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads();
@@ -205,38 +273,57 @@ void BPY_start_python( int argc, char **argv )
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item);
}
pyrna_alloc_types();
py_tstate = PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate);
}
void BPY_end_python( void )
{
// fprintf(stderr, "Ending Python!\n");
PyGILState_Ensure(); /* finalizing, no need to grab the state */
// free other python data.
//BPY_rna_free_types();
pyrna_free_types();
/* clear all python data from structs */
Py_Finalize( );
return;
#ifdef TIME_PY_RUN
// measure time since py started
bpy_timer = PIL_check_seconds_timer() - bpy_timer;
printf("*bpy stats* - ");
printf("tot exec: %d, ", bpy_timer_count);
printf("tot run: %.4fsec, ", bpy_timer_run_tot);
if(bpy_timer_count>0)
printf("average run: %.6fsec, ", (bpy_timer_run_tot/bpy_timer_count));
if(bpy_timer>0.0)
printf("tot usage %.4f%%", (bpy_timer_run_tot/bpy_timer)*100.0);
printf("\n");
// fprintf(stderr, "Ending Python Done!\n");
#endif
}
/* Can run a file or text block */
int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
{
PyObject *py_dict, *py_result;
PyObject *py_dict, *py_result= NULL;
PyGILState_STATE gilstate;
if (fn==NULL && text==NULL) {
return 0;
}
//BPY_start_python();
gilstate = PyGILState_Ensure();
BPY_update_modules(); /* can give really bad results if this isnt here */
bpy_import_main_set(CTX_data_main(C));
bpy_context_set(C, &gilstate);
py_dict = CreateGlobalDictionary(C);
@@ -251,13 +338,11 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
MEM_freeN( buf );
if( PyErr_Occurred( ) ) {
BPy_errors_to_report(reports);
BPY_free_compiled_text( text );
PyGILState_Release(gilstate);
return 0;
}
}
py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict );
if(text->compiled)
py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict );
} else {
#if 0
@@ -287,10 +372,9 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
}
Py_DECREF(py_dict);
PyGILState_Release(gilstate);
bpy_import_main_set(NULL);
//BPY_end_python();
bpy_context_clear(C, &gilstate);
return py_result ? 1:0;
}
@@ -473,12 +557,7 @@ void BPY_run_ui_scripts(bContext *C, int reload)
PyGILState_STATE gilstate;
PyObject *sys_path;
gilstate = PyGILState_Ensure();
// XXX - evil, need to access context
BPy_SetContext(C);
bpy_import_main_set(CTX_data_main(C));
bpy_context_set(C, &gilstate);
sys_path= PySys_GetObject("path"); /* borrow */
PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */
@@ -537,12 +616,14 @@ void BPY_run_ui_scripts(bContext *C, int reload)
PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */
bpy_import_main_set(NULL);
bpy_context_clear(C, &gilstate);
PyGILState_Release(gilstate);
#ifdef TIME_REGISTRATION
printf("script time %f\n", (PIL_check_seconds_timer()-time));
#endif
/* reset the timer so as not to take loading into the stats */
bpy_timer_count = 0;
}
/* ****************************************** */
@@ -740,3 +821,56 @@ float BPY_pydriver_eval (ChannelDriver *driver)
return result;
}
int BPY_button_eval(bContext *C, char *expr, double *value)
{
PyGILState_STATE gilstate;
PyObject *dict, *retval;
int error_ret = 0;
if (!value || !expr || expr[0]=='\0') return -1;
bpy_context_set(C, &gilstate);
dict= CreateGlobalDictionary(C);
retval = PyRun_String(expr, Py_eval_input, dict, dict);
if (retval == NULL) {
error_ret= -1;
}
else {
double val;
if(PyTuple_Check(retval)) {
/* Users my have typed in 10km, 2m
* add up all values */
int i;
val= 0.0;
for(i=0; i<PyTuple_GET_SIZE(retval); i++) {
val+= PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i));
}
}
else {
val = PyFloat_AsDouble(retval);
}
Py_DECREF(retval);
if(val==-1 && PyErr_Occurred()) {
error_ret= -1;
}
else {
*value= val;
}
}
if(error_ret) {
BPy_errors_to_report(CTX_wm_reports(C));
}
Py_DECREF(dict);
bpy_context_clear(C, &gilstate);
return error_ret;
}

View File

@@ -30,7 +30,6 @@
#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 "WM_api.h"

View File

@@ -37,7 +37,6 @@
#include "RNA_define.h"
#include "bpy_rna.h"
#include "bpy_compat.h"
#include "bpy_util.h"
#include "../generic/bpy_internal_import.h" // our own imports
@@ -93,11 +92,9 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
PointerRNA ptr_event;
PyObject *py_operator;
PyGILState_STATE gilstate = PyGILState_Ensure();
PyGILState_STATE gilstate;
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_context_set(C, &gilstate);
args = PyTuple_New(1);
PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg
@@ -221,8 +218,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
}
#endif
PyGILState_Release(gilstate);
bpy_import_main_set(NULL);
bpy_context_clear(C, &gilstate);
return ret_flag;
}
@@ -299,7 +295,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
item = PyList_GET_ITEM(props, i);
if (PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
if (PyArg_ParseTuple(item, "O!O!:PYTHON_OT_wrapper", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
@@ -309,6 +305,8 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
if (py_ret) {
Py_DECREF(py_ret);
} else {
fprintf(stderr, "BPy Operator \"%s\" registration error: %s item %d could not run\n", ot->idname, PYOP_ATTR_PROP, i);
PyLineSpit();
PyErr_Print();
PyErr_Clear();
}

View File

@@ -23,7 +23,6 @@
*/
#include "bpy_rna.h"
#include "bpy_compat.h"
#include "bpy_util.h"
//#include "blendef.h"
#include "BLI_dynstr.h"
@@ -133,6 +132,8 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
#endif
static StructRNA *pyrna_struct_as_srna(PyObject *self);
static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
{
return (a->ptr.data==b->ptr.data) ? 0 : -1;
@@ -245,7 +246,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
{
PyObject *ret;
int type = RNA_property_type(prop);
int len = RNA_property_array_length(prop);
int len = RNA_property_array_length(ptr, prop);
if (len > 0) {
/* resolve the array from a new pytype */
@@ -256,7 +257,11 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
/* return a mathutils vector where possible */
if(RNA_property_type(prop)==PROP_FLOAT) {
switch(RNA_property_subtype(prop)) {
case PROP_VECTOR:
case PROP_TRANSLATION:
case PROP_DIRECTION:
case PROP_VELOCITY:
case PROP_ACCELERATION:
case PROP_XYZ:
if(len>=2 && len <= 4) {
PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE);
Py_DECREF(ret); /* the vector owns now */
@@ -275,7 +280,8 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
ret= mat_cb; /* return the matrix instead */
}
break;
case PROP_ROTATION:
case PROP_EULER:
case PROP_QUATERNION:
if(len==3) { /* euler */
PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
Py_DECREF(ret); /* the matrix owns now */
@@ -463,128 +469,43 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
{
/* XXX hard limits should be checked here */
int type = RNA_property_type(prop);
int len = RNA_property_array_length(prop);
int len = RNA_property_array_length(ptr, prop);
if (len > 0) {
PyObject *item;
int py_len = -1;
int i;
char error_str[512];
int ok= 1;
#ifdef USE_MATHUTILS
if(MatrixObject_Check(value)) {
MatrixObject *mat = (MatrixObject*)value;
if(!BaseMath_ReadCallback(mat))
return -1;
py_len = mat->rowSize * mat->colSize;
} else /* continue... */
#endif
if (PySequence_Check(value)) {
py_len= (int)PySequence_Length(value);
}
else {
if (!PySequence_Check(value)) {
PyErr_Format(PyExc_TypeError, "%.200s RNA array assignment expected a sequence instead of %.200s instance.", error_prefix, Py_TYPE(value)->tp_name);
return -1;
}
/* done getting the length */
if (py_len != len) {
PyErr_Format(PyExc_TypeError, "%.200s python sequence length %d did not match the RNA array length %d.", error_prefix, py_len, len);
return -1;
}
/* for arrays we have a limited number of types */
switch (type) {
case PROP_BOOLEAN:
{
int *param_arr;
if(data) param_arr= (int*)data;
else param_arr= MEM_mallocN(sizeof(int) * len, "pyrna bool array");
/* collect the variables before assigning, incase one of them is incorrect */
for (i=0; i<len; i++) {
item = PySequence_GetItem(value, i);
param_arr[i] = PyObject_IsTrue( item );
Py_DECREF(item);
if (param_arr[i] < 0) {
if(data==NULL)
MEM_freeN(param_arr);
PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence is not a boolean", error_prefix);
return -1;
}
}
if(data==NULL) {
RNA_property_boolean_set_array(ptr, prop, param_arr);
MEM_freeN(param_arr);
}
ok= pyrna_py_to_boolean_array(value, ptr, prop, data, error_str, sizeof(error_str));
break;
}
case PROP_INT:
{
int *param_arr;
if(data) param_arr= (int*)data;
else param_arr= MEM_mallocN(sizeof(int) * len, "pyrna int array");
/* collect the variables */
for (i=0; i<len; i++) {
item = PySequence_GetItem(value, i);
param_arr[i] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */
Py_DECREF(item);
}
if (PyErr_Occurred()) {
if(data==NULL)
MEM_freeN(param_arr);
PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence could not be used as an int", error_prefix);
return -1;
}
if(data==NULL) {
RNA_property_int_set_array(ptr, prop, param_arr);
MEM_freeN(param_arr);
}
ok= pyrna_py_to_int_array(value, ptr, prop, data, error_str, sizeof(error_str));
break;
}
case PROP_FLOAT:
{
float *param_arr;
if(data) param_arr = (float*)data;
else param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float array");
#ifdef USE_MATHUTILS
if(MatrixObject_Check(value) && RNA_property_subtype(prop) == PROP_MATRIX) {
MatrixObject *mat = (MatrixObject*)value;
memcpy(param_arr, mat->contigPtr, sizeof(float) * len);
} else /* continue... */
#endif
{
/* collect the variables */
for (i=0; i<len; i++) {
item = PySequence_GetItem(value, i);
param_arr[i] = (float)PyFloat_AsDouble(item); /* deal with any errors later */
Py_DECREF(item);
}
}
if (PyErr_Occurred()) {
if(data==NULL)
MEM_freeN(param_arr);
PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence could not be used as a float", error_prefix);
return -1;
}
if(data==NULL) {
RNA_property_float_set_array(ptr, prop, param_arr);
MEM_freeN(param_arr);
}
ok= pyrna_py_to_float_array(value, ptr, prop, data, error_str, sizeof(error_str));
break;
}
if (!ok) {
PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str);
return -1;
}
} else {
}
else {
/* Normal Property (not an array) */
/* see if we can coorce into a python type - PropertyType */
@@ -856,7 +777,7 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
len = RNA_property_collection_length(&self->ptr, self->prop);
} else {
len = RNA_property_array_length(self->prop);
len = RNA_property_array_length(&self->ptr, self->prop);
if (len==0) { /* not an array*/
PyErr_SetString(PyExc_AttributeError, "len() only available for collection RNA types");
@@ -882,7 +803,7 @@ static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynu
}
static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum)
{
int len= RNA_property_array_length(self->prop);
int len= RNA_property_array_length(&self->ptr, self->prop);
if(keynum < 0) keynum += len;
@@ -904,10 +825,6 @@ static PyObject *prop_subscript_collection_str(BPy_PropertyRNA * self, char *key
}
/* static PyObject *prop_subscript_array_str(BPy_PropertyRNA * self, char *keyname) */
#if PY_VERSION_HEX >= 0x03000000
static PyObject *prop_subscript_collection_slice(BPy_PropertyRNA * self, int start, int stop)
{
PointerRNA newptr;
@@ -942,7 +859,6 @@ static PyObject *prop_subscript_array_slice(BPy_PropertyRNA * self, int start, i
return list;
}
#endif
static PyObject *prop_subscript_collection(BPy_PropertyRNA * self, PyObject *key)
{
@@ -956,7 +872,6 @@ static PyObject *prop_subscript_collection(BPy_PropertyRNA * self, PyObject *key
return prop_subscript_collection_int(self, i);
}
#if PY_VERSION_HEX >= 0x03000000
else if (PySlice_Check(key)) {
int len= RNA_property_collection_length(&self->ptr, self->prop);
Py_ssize_t start, stop, step, slicelength;
@@ -975,7 +890,6 @@ static PyObject *prop_subscript_collection(BPy_PropertyRNA * self, PyObject *key
return NULL;
}
}
#endif
else {
PyErr_Format(PyExc_TypeError, "invalid rna key, key must be a string or an int instead of %.200s instance.", Py_TYPE(key)->tp_name);
return NULL;
@@ -993,9 +907,8 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA * self, PyObject *key)
return NULL;
return prop_subscript_array_int(self, PyLong_AsSsize_t(key));
}
#if PY_VERSION_HEX >= 0x03000000
else if (PySlice_Check(key)) {
int len= RNA_property_array_length(self->prop);
int len= RNA_property_array_length(&self->ptr, self->prop);
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
@@ -1012,7 +925,6 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA * self, PyObject *key)
return NULL;
}
}
#endif
else {
PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
return NULL;
@@ -1023,7 +935,7 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
{
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
return prop_subscript_collection(self, key);
} else if (RNA_property_array_length(self->prop)) { /* arrays are currently fixed length, zero length means its not an array */
} else if (RNA_property_array_length(&self->ptr, self->prop)) { /* arrays are currently fixed length, zero length means its not an array */
return prop_subscript_array(self, key);
} else {
PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
@@ -1032,7 +944,6 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
}
#if PY_VERSION_HEX >= 0x03000000
static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int end, PyObject *value)
{
int count;
@@ -1049,12 +960,11 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int
return 0;
}
#endif
static int prop_subscript_ass_array_int(BPy_PropertyRNA * self, int keynum, PyObject *value)
{
int len= RNA_property_array_length(self->prop);
int len= RNA_property_array_length(&self->ptr, self->prop);
if(keynum < 0) keynum += len;
@@ -1087,9 +997,8 @@ static int pyrna_prop_ass_subscript( BPy_PropertyRNA * self, PyObject *key, PyOb
return prop_subscript_ass_array_int(self, i, value);
}
#if PY_VERSION_HEX >= 0x03000000
else if (PySlice_Check(key)) {
int len= RNA_property_array_length(self->prop);
int len= RNA_property_array_length(&self->ptr, self->prop);
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
@@ -1106,7 +1015,6 @@ static int pyrna_prop_ass_subscript( BPy_PropertyRNA * self, PyObject *key, PyOb
return -1;
}
}
#endif
else {
PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
return -1;
@@ -1458,7 +1366,39 @@ static PyObject *pyrna_prop_get(BPy_PropertyRNA *self, PyObject *args)
}
#if (PY_VERSION_HEX >= 0x03000000) /* foreach needs py3 */
static PyObject *pyrna_prop_add(BPy_PropertyRNA *self, PyObject *args)
{
PointerRNA newptr;
RNA_property_collection_add(&self->ptr, self->prop, &newptr);
if(!newptr.data) {
PyErr_SetString( PyExc_TypeError, "add() not supported for this collection");
return NULL;
}
else {
return pyrna_struct_CreatePyObject(&newptr);
}
}
static PyObject *pyrna_prop_remove(BPy_PropertyRNA *self, PyObject *args)
{
PyObject *ret;
int key= 0;
if (!PyArg_ParseTuple(args, "i:remove", &key))
return NULL;
if(!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
PyErr_SetString( PyExc_TypeError, "remove() not supported for this collection");
return NULL;
}
ret = Py_None;
Py_INCREF(ret);
return ret;
}
static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
/* values to assign */
RawPropertyType *raw_type, int *attr_tot, int *attr_signed )
@@ -1471,7 +1411,7 @@ static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
prop = RNA_struct_find_property(&itemptr, attr);
*raw_type= RNA_property_raw_type(prop);
*attr_tot = RNA_property_array_length(prop);
*attr_tot = RNA_property_array_length(&itemptr, prop);
*attr_signed= (RNA_property_subtype(prop)==PROP_UNSIGNED) ? FALSE:TRUE;
break;
}
@@ -1510,7 +1450,7 @@ static int foreach_parse_args(
if (RNA_property_type(self->prop) == PROP_COLLECTION)
array_tot = RNA_property_collection_length(&self->ptr, self->prop);
else
array_tot = RNA_property_array_length(self->prop);
array_tot = RNA_property_array_length(&self->ptr, self->prop);
target_tot= array_tot * (*attr_tot);
@@ -1693,7 +1633,6 @@ static PyObject *pyrna_prop_foreach_set(BPy_PropertyRNA *self, PyObject *args)
{
return foreach_getset(self, args, 1);
}
#endif /* #if (PY_VERSION_HEX >= 0x03000000) */
/* A bit of a kludge, make a list out of a collection or array,
* then return the lists iter function, not especially fast but convenient for now */
@@ -1704,7 +1643,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
if (ret==NULL) {
/* collection did not work, try array */
int len = RNA_property_array_length(self->prop);
int len = RNA_property_array_length(&self->ptr, self->prop);
if (len) {
int i;
@@ -1744,11 +1683,13 @@ static struct PyMethodDef pyrna_prop_methods[] = {
{"get", (PyCFunction)pyrna_prop_get, METH_VARARGS, NULL},
#if (PY_VERSION_HEX >= 0x03000000)
{"add", (PyCFunction)pyrna_prop_add, METH_VARARGS, NULL},
{"remove", (PyCFunction)pyrna_prop_remove, METH_VARARGS, NULL},
/* array accessor function */
{"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL},
{"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL},
#endif
{NULL, NULL, 0, NULL}
};
@@ -1793,7 +1734,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
{
PyObject *ret;
int type = RNA_property_type(prop);
int len = RNA_property_array_length(prop);
int len = RNA_property_array_length(ptr, prop);
int a;
@@ -2112,13 +2053,7 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
/*-----------------------BPy_StructRNA method def------------------------------*/
PyTypeObject pyrna_struct_Type = {
#if (PY_VERSION_HEX >= 0x02060000)
PyVarObject_HEAD_INIT(NULL, 0)
#else
/* python 2.5 and below */
PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /* ob_size */
#endif
"StructRNA", /* tp_name */
sizeof( BPy_StructRNA ), /* tp_basicsize */
0, /* tp_itemsize */
@@ -2197,14 +2132,7 @@ PyTypeObject pyrna_struct_Type = {
/*-----------------------BPy_PropertyRNA method def------------------------------*/
PyTypeObject pyrna_prop_Type = {
#if (PY_VERSION_HEX >= 0x02060000)
PyVarObject_HEAD_INIT(NULL, 0)
#else
/* python 2.5 and below */
PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /* ob_size */
#endif
"PropertyRNA", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
0, /* tp_itemsize */
@@ -2287,7 +2215,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
PyObject *item;
Py_INCREF(newclass);
if (RNA_struct_py_type_get(srna))
PyObSpit("RNA WAS SET - ", RNA_struct_py_type_get(srna));
@@ -2297,18 +2225,47 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
/* Not 100% needed but useful,
* having an instance within a type looks wrong however this instance IS an rna type */
/* python deals with the curcular ref */
RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr);
item = pyrna_struct_CreatePyObject(&ptr);
//item = PyCObject_FromVoidPtr(srna, NULL);
PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", item);
Py_DECREF(item);
/* done with rna instance */
}
/*
static StructRNA *srna_from_self(PyObject *self);
PyObject *BPy_GetStructRNA(PyObject *self)
{
StructRNA *srna= pyrna_struct_as_srna(self);
PointerRNA ptr;
PyObject *ret;
RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr);
ret= pyrna_struct_CreatePyObject(&ptr);
if(ret) {
return ret;
}
else {
Py_RETURN_NONE;
}
}
*/
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, ""},
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""},
// {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""},
{NULL, NULL, 0, NULL}
};
@@ -2343,18 +2300,26 @@ PyObject* pyrna_srna_Subtype(StructRNA *srna)
if(base && base != srna) {
/*/printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); */
py_base= pyrna_srna_Subtype(base);
Py_DECREF(py_base); /* srna owns, this is only to pass as an arg */
}
if(py_base==NULL) {
py_base= (PyObject *)&pyrna_struct_Type;
Py_INCREF(py_base);
}
newclass = PyObject_CallFunction( (PyObject*)&PyType_Type, "s(N){ssss}", idname, py_base, "__module__","bpy.types", "__doc__",descr);
/* always use O not N when calling, N causes refcount errors */
newclass = PyObject_CallFunction( (PyObject*)&PyType_Type, "s(O){ssss}", idname, py_base, "__module__","bpy.types", "__doc__",descr);
/* newclass will now have 2 ref's, ???, probably 1 is internal since decrefing here segfaults */
/* PyObSpit("new class ref", newclass); */
if (newclass) {
/* srna owns one, and the other is owned by the caller */
pyrna_subtype_set_rna(newclass, srna);
// PyObSpit("NewStructRNA Type: ", (PyObject *)newclass);
Py_DECREF(newclass); /* let srna own */
/* attach functions into the class
* so you can do... bpy.types.Scene.SomeFunction()
@@ -2377,9 +2342,21 @@ PyObject* pyrna_srna_Subtype(StructRNA *srna)
return newclass;
}
/* use for subtyping so we know which srna is used for a PointerRNA */
static StructRNA *srna_from_ptr(PointerRNA *ptr)
{
if(ptr->type == &RNA_Struct) {
return ptr->data;
}
else {
return ptr->type;
}
}
/* always returns a new ref, be sure to decref when done */
PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
{
return pyrna_srna_Subtype((ptr->type == &RNA_Struct) ? ptr->data : ptr->type);
return pyrna_srna_Subtype(srna_from_ptr(ptr));
}
/*-----------------------CreatePyObject---------------------------------*/
@@ -2395,6 +2372,7 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
if (tp) {
pyrna = (BPy_StructRNA *) tp->tp_alloc(tp, 0);
Py_DECREF(tp); /* srna owns, cant hold a ref */
}
else {
fprintf(stderr, "Could not make type\n");
@@ -2432,8 +2410,11 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
return ( PyObject * ) pyrna;
}
/* bpy.data from python */
static PointerRNA *rna_module_ptr= NULL;
PyObject *BPY_rna_module( void )
{
BPy_StructRNA *pyrna;
PointerRNA ptr;
#ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once.
@@ -2453,8 +2434,15 @@ PyObject *BPY_rna_module( void )
/* for now, return the base RNA type rather then a real module */
RNA_main_pointer_create(G.main, &ptr);
pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
return pyrna_struct_CreatePyObject(&ptr);
rna_module_ptr= &pyrna->ptr;
return (PyObject *)pyrna;
}
void BPY_update_rna_module(void)
{
RNA_main_pointer_create(G.main, rna_module_ptr);
}
#if 0
@@ -2500,8 +2488,8 @@ static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA * self, PyObject *pyna
static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self);
static struct PyMethodDef pyrna_basetype_methods[] = {
{"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""},
{"register", (PyCFunction)pyrna_basetype_register, METH_VARARGS, ""},
{"unregister", (PyCFunction)pyrna_basetype_unregister, METH_VARARGS, ""},
{"register", (PyCFunction)pyrna_basetype_register, METH_O, ""},
{"unregister", (PyCFunction)pyrna_basetype_unregister, METH_O, ""},
{NULL, NULL, 0, NULL}
};
@@ -2548,14 +2536,16 @@ PyObject *BPY_rna_types(void)
}
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, ""},
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""},
{NULL, NULL, 0, NULL}
};
#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef props_module = {
PyModuleDef_HEAD_INIT,
"bpy.props",
@@ -2564,16 +2554,11 @@ static struct PyModuleDef props_module = {
props_methods,
NULL, NULL, NULL, NULL
};
#endif
PyObject *BPY_rna_props( void )
{
PyObject *submodule;
#if PY_VERSION_HEX >= 0x03000000
submodule= PyModule_Create(&props_module);
#else /* Py2.x */
submodule= Py_InitModule3( "bpy.props", props_methods, "" );
#endif
/* INCREF since its its assumed that all these functions return the
* module with a new ref like PyDict_New, since they are passed to
@@ -2583,18 +2568,92 @@ PyObject *BPY_rna_props( void )
return submodule;
}
static StructRNA *pyrna_struct_as_srna(PyObject *self)
{
BPy_StructRNA *py_srna;
StructRNA *srna;
/* ack, PyObject_GetAttrString wont look up this types tp_dict first :/ */
if(PyType_Check(self)) {
py_srna = (BPy_StructRNA *)PyDict_GetItemString(((PyTypeObject *)self)->tp_dict, "__rna__");
Py_XINCREF(py_srna);
}
if(py_srna==NULL)
py_srna = (BPy_StructRNA*)PyObject_GetAttrString(self, "__rna__");
if(py_srna==NULL) {
PyErr_SetString(PyExc_SystemError, "internal error, self had no __rna__ attribute, should never happen.");
return NULL;
}
if(!BPy_StructRNA_Check(py_srna)) {
PyErr_Format(PyExc_SystemError, "internal error, __rna__ was of type %.200s, instead of %.200s instance.", Py_TYPE(py_srna)->tp_name, pyrna_struct_Type.tp_name);
Py_DECREF(py_srna);
return NULL;
}
if(py_srna->ptr.type != &RNA_Struct) {
PyErr_SetString(PyExc_SystemError, "internal error, __rna__ was not a RNA_Struct type of rna struct.");
Py_DECREF(py_srna);
return NULL;
}
srna= py_srna->ptr.data;
Py_DECREF(py_srna);
return srna;
}
/* Orphan functions, not sure where they should go */
/* get the srna for methods attached to types */
/* */
static StructRNA *srna_from_self(PyObject *self)
{
/* a bit sloppy but would cause a very confusing bug if
* an error happened to be set here */
PyErr_Clear();
if(self==NULL) {
return NULL;
}
else if (PyCObject_Check(self)) {
return PyCObject_AsVoidPtr(self);
}
else if (PyType_Check(self)==0) {
return NULL;
}
/* These cases above not errors, they just mean the type was not compatible
* After this any errors will be raised in the script */
return pyrna_struct_as_srna(self);
}
/* 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 *ret = PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr(func, NULL));
PyTuple_SET_ITEM(ret, 1, kw);
Py_INCREF(kw);
return ret;
}
/* 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 */
PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
static char *kwlist[] = {"attr", "name", "description", "default", NULL};
char *id, *name="", *description="";
float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f;
int def=0;
PropertyRNA *prop;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def))
return NULL;
if (PyTuple_Size(args) > 0) {
@@ -2602,34 +2661,17 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
if (self && PyCObject_Check(self)) {
StructRNA *srna = PyCObject_AsVoidPtr(self);
prop= RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
srna= srna_from_self(self);
if(srna==NULL && PyErr_Occurred()) {
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
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_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));
PyTuple_SET_ITEM(ret, 1, kw);
Py_INCREF(kw);
return ret;
}
else { /* operators defer running this function */
return bpy_prop_deferred_return((void *)BPy_BoolProperty, kw);
}
}
@@ -2639,7 +2681,8 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
char *id, *name="", *description="";
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, def=0;
PropertyRNA *prop;
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
return NULL;
@@ -2648,80 +2691,47 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
if (self && PyCObject_Check(self)) {
StructRNA *srna = PyCObject_AsVoidPtr(self);
srna= srna_from_self(self);
if(srna==NULL && PyErr_Occurred()) {
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
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));
PyTuple_SET_ITEM(ret, 1, kw);
Py_INCREF(kw);
return ret;
}
else { /* operators defer running this function */
return bpy_prop_deferred_return((void *)BPy_IntProperty, kw);
}
}
PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "name", "description", "default", NULL};
static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
char *id, *name="", *description="";
int def=0;
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|ssi:BoolProperty", kwlist, &id, &name, &description, &def))
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
return NULL;
}
if (self && PyCObject_Check(self)) {
StructRNA *srna = PyCObject_AsVoidPtr(self);
prop= RNA_def_boolean(srna, id, def, name, description);
srna= srna_from_self(self);
if(srna==NULL && PyErr_Occurred()) {
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
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_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));
PyTuple_SET_ITEM(ret, 1, kw);
Py_INCREF(kw);
return ret;
}
else { /* operators defer running this function */
return bpy_prop_deferred_return((void *)BPy_FloatProperty, kw);
}
}
@@ -2731,7 +2741,8 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
char *id, *name="", *description="", *def="";
int maxlen=0;
PropertyRNA *prop;
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssis:StringProperty", kwlist, &id, &name, &description, &maxlen, &def))
return NULL;
@@ -2739,36 +2750,237 @@ PyObject *BPy_StringProperty(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);
srna= srna_from_self(self);
if(srna==NULL && PyErr_Occurred()) {
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
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__");
}
else { /* operators defer running this function */
return bpy_prop_deferred_return((void *)BPy_StringProperty, kw);
}
}
if(pyob && BPy_StructRNA_Check(pyob)) {
BPy_StructRNA *py_srna= (BPy_StructRNA*)pyob;
static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, int *defvalue)
{
EnumPropertyItem *items= NULL;
PyObject *item;
int seq_len, i, totitem= 0;
if(!PySequence_Check(value)) {
PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items");
return NULL;
}
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;
}
}
seq_len = PySequence_Length(value);
for(i=0; i<seq_len; i++) {
EnumPropertyItem tmp= {0, "", 0, "", ""};
item= PySequence_GetItem(value, i);
if(item==NULL || PyTuple_Check(item)==0) {
PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items");
if(items) MEM_freeN(items);
Py_XDECREF(item);
return NULL;
}
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));
PyTuple_SET_ITEM(ret, 1, kw);
Py_INCREF(kw);
return ret;
if(!PyArg_ParseTuple(item, "sss", &tmp.identifier, &tmp.name, &tmp.description)) {
PyErr_SetString(PyExc_TypeError, "expected an identifier, name and description in the tuple");
Py_DECREF(item);
return NULL;
}
tmp.value= i;
RNA_enum_item_add(&items, &totitem, &tmp);
if(def[0] && strcmp(def, tmp.identifier) == 0)
*defvalue= tmp.value;
Py_DECREF(item);
}
if(!def[0])
*defvalue= 0;
RNA_enum_item_end(&items, &totitem);
return items;
}
PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "items", "name", "description", "default", NULL};
char *id, *name="", *description="", *def="";
int defvalue=0;
PyObject *items= Py_None;
EnumPropertyItem *eitems;
PropertyRNA *prop;
StructRNA *srna;
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sss:EnumProperty", kwlist, &id, &items, &name, &description, &def))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
return NULL;
}
srna= srna_from_self(self);
if(srna==NULL && PyErr_Occurred()) {
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
eitems= enum_items_from_py(items, def, &defvalue);
if(!eitems)
return NULL;
prop= RNA_def_enum(srna, id, eitems, defvalue, name, description);
RNA_def_property_duplicate_pointers(prop);
MEM_freeN(eitems);
Py_RETURN_NONE;
}
else { /* operators defer running this function */
return bpy_prop_deferred_return((void *)BPy_EnumProperty, kw);
}
}
static StructRNA *pointer_type_from_py(PyObject *value)
{
StructRNA *srna;
srna= srna_from_self(value);
if(!srna) {
PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup");
return NULL;
}
if(!RNA_struct_is_a(srna, &RNA_IDPropertyGroup)) {
PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup");
return NULL;
}
return srna;
}
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "type", "name", "description", NULL};
char *id, *name="", *description="";
PropertyRNA *prop;
StructRNA *srna, *ptype;
PyObject *type= Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:PointerProperty", kwlist, &id, &type, &name, &description))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
return NULL;
}
srna= srna_from_self(self);
if(srna==NULL && PyErr_Occurred()) {
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
ptype= pointer_type_from_py(type);
if(!ptype)
return NULL;
prop= RNA_def_pointer_runtime(srna, id, ptype, name, description);
RNA_def_property_duplicate_pointers(prop);
Py_RETURN_NONE;
}
else { /* operators defer running this function */
return bpy_prop_deferred_return((void *)BPy_PointerProperty, kw);
}
return NULL;
}
PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
{
static char *kwlist[] = {"attr", "type", "name", "description", NULL};
char *id, *name="", *description="";
PropertyRNA *prop;
StructRNA *srna, *ptype;
PyObject *type= Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:CollectionProperty", kwlist, &id, &type, &name, &description))
return NULL;
if (PyTuple_Size(args) > 0) {
PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
return NULL;
}
srna= srna_from_self(self);
if(srna==NULL && PyErr_Occurred()) {
return NULL; /* self's type was compatible but error getting the srna */
}
else if(srna) {
ptype= pointer_type_from_py(type);
if(!ptype)
return NULL;
prop= RNA_def_collection_runtime(srna, id, ptype, name, description);
RNA_def_property_duplicate_pointers(prop);
Py_RETURN_NONE;
}
else { /* operators defer running this function */
return bpy_prop_deferred_return((void *)BPy_CollectionProperty, kw);
}
return NULL;
}
static int deferred_register_props(PyObject *py_class, StructRNA *srna)
{
PyObject *props, *dummy_args, *item;
int i;
props= PyObject_GetAttrString(py_class, "__props__");
if(!props) {
PyErr_Clear();
return 1;
}
dummy_args = PyTuple_New(0);
for(i=0; i<PyList_Size(props); i++) {
PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
item = PyList_GET_ITEM(props, i);
if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL);
py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
Py_DECREF(py_srna_cobject);
if(py_ret) {
Py_DECREF(py_ret);
}
else {
Py_DECREF(dummy_args);
return 0;
}
}
else {
PyErr_Clear();
PyErr_SetString(PyExc_AttributeError, "expected list of dicts for __props__.");
Py_DECREF(dummy_args);
return 0;
}
}
Py_DECREF(dummy_args);
return 1;
}
/*-------------------- Type Registration ------------------------*/
@@ -2918,9 +3130,10 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
void *retdata= NULL;
int err= 0, i, flag;
PyGILState_STATE gilstate = PyGILState_Ensure();
PyGILState_STATE gilstate;
BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solution for this.
bContext *C= BPy_GetContext(); // XXX - NEEDS FIXING, QUITE BAD.
bpy_context_set(C, &gilstate);
py_class= RNA_struct_py_type_get(ptr->type);
@@ -2996,57 +3209,103 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
PyErr_Clear();
}
PyGILState_Release(gilstate);
bpy_context_clear(C, &gilstate);
return err;
}
static void bpy_class_free(void *pyob_ptr)
{
PyObject *self= (PyObject *)pyob_ptr;
PyGILState_STATE gilstate;
gilstate = PyGILState_Ensure();
PyDict_Clear(((PyTypeObject*)self)->tp_dict);
if(G.f&G_DEBUG) {
if(((PyObject *)pyob_ptr)->ob_refcnt > 1)
PyObSpit("zombie class - ref should be 1", (PyObject *)pyob_ptr);
if(self->ob_refcnt > 1) {
PyObSpit("zombie class - ref should be 1", self);
}
}
Py_DECREF((PyObject *)pyob_ptr);
PyGILState_Release(gilstate);
}
PyObject *pyrna_basetype_register(PyObject *self, PyObject *args)
void pyrna_alloc_types(void)
{
PyGILState_STATE gilstate;
PointerRNA ptr;
PropertyRNA *prop;
gilstate = PyGILState_Ensure();
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create(&ptr);
prop = RNA_struct_find_property(&ptr, "structs");
RNA_PROP_BEGIN(&ptr, itemptr, prop) {
Py_DECREF(pyrna_struct_Subtype(&itemptr));
}
RNA_PROP_END;
PyGILState_Release(gilstate);
}
void pyrna_free_types(void)
{
PointerRNA ptr;
PropertyRNA *prop;
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create(&ptr);
prop = RNA_struct_find_property(&ptr, "structs");
RNA_PROP_BEGIN(&ptr, itemptr, prop) {
StructRNA *srna= srna_from_ptr(&itemptr);
void *py_ptr= RNA_struct_py_type_get(srna);
if(py_ptr) {
#if 0 // XXX - should be able to do this but makes python crash on exit
bpy_class_free(py_ptr);
#endif
RNA_struct_py_type_set(srna, NULL);
}
}
RNA_PROP_END;
}
/* Note! MemLeak XXX
*
* There is currently a bug where moving registering a python class does
* not properly manage refcounts from the python class, since the srna owns
* the python class this should not be so tricky but changing the references as
* youd expect when changing ownership crashes blender on exit so I had to comment out
* the decref. This is not so bad because the leak only happens when re-registering (hold F8)
* - Should still be fixed - Campbell
* */
PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class)
{
bContext *C= NULL;
PyObject *py_class, *item;
ReportList reports;
StructRegisterFunc reg;
BPy_StructRNA *py_srna;
StructRNA *srna;
StructRNA *srna_new;
PyObject *item;
const char *identifier= "";
if(!PyArg_ParseTuple(args, "O:register", &py_class))
srna= pyrna_struct_as_srna(py_class);
if(srna==NULL)
return NULL;
if(!PyType_Check(py_class)) {
PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no a Type object).");
return NULL;
}
/* check we got an __rna__ attribute */
item= PyObject_GetAttrString(py_class, "__rna__");
if(!item || !BPy_StructRNA_Check(item)) {
Py_XDECREF(item);
PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no __rna__ property).");
return NULL;
}
/* check the __rna__ attribute has the right type */
Py_DECREF(item);
py_srna= (BPy_StructRNA*)item;
if(py_srna->ptr.type != &RNA_Struct) {
PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (not a Struct).");
return NULL;
}
/* check that we have a register callback for this type */
reg= RNA_struct_register(py_srna->ptr.data);
reg= RNA_struct_register(srna);
if(!reg) {
PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no register supported).");
@@ -3056,11 +3315,19 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *args)
/* get the context, so register callback can do necessary refreshes */
C= BPy_GetContext();
/* call the register callback */
/* call the register callback with reports & identifier */
BKE_reports_init(&reports, RPT_STORE);
srna= reg(C, &reports, py_class, bpy_class_validate, bpy_class_call, bpy_class_free);
if(!srna) {
item= PyObject_GetAttrString(py_class, "__name__");
if(item) {
identifier= _PyUnicode_AsString(item);
Py_DECREF(item); /* no need to keep a ref, the class owns it */
}
srna_new= reg(C, &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free);
if(!srna_new) {
BPy_reports_to_error(&reports);
BKE_reports_clear(&reports);
return NULL;
@@ -3068,44 +3335,32 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *args)
BKE_reports_clear(&reports);
pyrna_subtype_set_rna(py_class, srna); /* takes a ref to py_class */
pyrna_subtype_set_rna(py_class, srna_new); /* takes a ref to py_class */
/* old srna still references us, keep the check incase registering somehow can free it */
if(RNA_struct_py_type_get(srna)) {
RNA_struct_py_type_set(srna, NULL);
// Py_DECREF(py_class); // shuld be able to do this XXX since the old rna adds a new ref.
}
if(!deferred_register_props(py_class, srna_new))
return NULL;
Py_RETURN_NONE;
}
PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args)
PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class)
{
bContext *C= NULL;
PyObject *py_class, *item;
BPy_StructRNA *py_srna;
StructUnregisterFunc unreg;
StructRNA *srna;
if(!PyArg_ParseTuple(args, "O:unregister", &py_class))
srna= pyrna_struct_as_srna(py_class);
if(srna==NULL)
return NULL;
if(!PyType_Check(py_class)) {
PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no a Type object).");
return NULL;
}
/* check we got an __rna__ attribute */
item= PyDict_GetItemString(((PyTypeObject*)py_class)->tp_dict, "__rna__"); /* borrow ref */
if(!item || !BPy_StructRNA_Check(item)) {
PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no __rna__ property).");
return NULL;
}
/* check the __rna__ attribute has the right type */
py_srna= (BPy_StructRNA*)item;
if(py_srna->ptr.type != &RNA_Struct) {
PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (not a Struct).");
return NULL;
}
/* check that we have a unregister callback for this type */
unreg= RNA_struct_unregister(py_srna->ptr.data);
unreg= RNA_struct_unregister(srna);
if(!unreg) {
PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no unregister supported).");
@@ -3114,13 +3369,9 @@ PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args)
/* get the context, so register callback can do necessary refreshes */
C= BPy_GetContext();
/* call unregister */
unreg(C, py_srna->ptr.data);
/* remove reference to old type */
Py_DECREF(py_class);
unreg(C, srna); /* calls bpy_class_free, this decref's py_class */
Py_RETURN_NONE;
}

View File

@@ -61,6 +61,7 @@ typedef struct {
#define BPy_BaseTypeRNA BPy_PropertyRNA
PyObject *BPY_rna_module( void );
void BPY_update_rna_module( void );
/*PyObject *BPY_rna_doc( void );*/
PyObject *BPY_rna_types( void );
PyObject *BPY_rna_props( void );
@@ -74,13 +75,25 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop);
/* functions for setting up new props - experemental */
PyObject *BPy_FloatProperty(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_IntProperty(PyObject *self, PyObject *args, PyObject *kw);
PyObject *BPy_FloatProperty(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);
/* function for registering types */
PyObject *pyrna_basetype_register(PyObject *self, PyObject *args);
PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args);
/* called before stopping python */
void pyrna_alloc_types(void);
void pyrna_free_types(void);
/* primitive type conversion */
int pyrna_py_to_boolean_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size);
int pyrna_py_to_int_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size);
int pyrna_py_to_float_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size);
#endif

View File

@@ -26,7 +26,6 @@
#include "bpy_util.h"
#include "bpy_rna.h" /* for rna buttons */
#include "bpy_operator.h" /* for setting button operator properties */
#include "bpy_compat.h"
#include "WM_types.h" /* for WM_OP_INVOKE_DEFAULT & friends */
@@ -47,7 +46,6 @@ static struct PyMethodDef ui_methods[] = {
{NULL, NULL, 0, NULL}
};
#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef ui_module = {
PyModuleDef_HEAD_INIT,
"bpy.ui",
@@ -56,16 +54,11 @@ static struct PyModuleDef ui_module = {
ui_methods,
NULL, NULL, NULL, NULL
};
#endif
PyObject *BPY_ui_module( void )
{
PyObject *submodule, *mod;
#if PY_VERSION_HEX >= 0x03000000
PyObject *submodule;
submodule= PyModule_Create(&ui_module);
#else /* Py2.x */
submodule= Py_InitModule3( "bpy.ui", ui_methods, "" );
#endif
/* INCREF since its its assumed that all these functions return the
* module with a new ref like PyDict_New, since they are passed to

View File

@@ -124,7 +124,6 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag)
/* Copied from pythons 3's Object.c */
#ifndef Py_CmpToRich
PyObject *
Py_CmpToRich(int op, int cmp)
{
@@ -160,7 +159,6 @@ Py_CmpToRich(int op, int cmp)
Py_INCREF(res);
return res;
}
#endif
/* for debugging */
void PyObSpit(char *name, PyObject *var) {
@@ -170,7 +168,7 @@ void PyObSpit(char *name, PyObject *var) {
}
else {
PyObject_Print(var, stderr, 0);
fprintf(stderr, " ref:%d ", var->ob_refcnt);
fprintf(stderr, " ref:%d ", (int)var->ob_refcnt);
fprintf(stderr, " ptr:%p", (void *)var);
fprintf(stderr, " type:");
@@ -373,11 +371,7 @@ PyObject *BPY_exception_buffer(void)
* string_io = StringIO.StringIO()
*/
#if PY_VERSION_HEX < 0x03000000
if(! (string_io_mod= PyImport_ImportModule("StringIO")) ) {
#else
if(! (string_io_mod= PyImport_ImportModule("io")) ) {
#endif
goto error_cleanup;
} else if (! (string_io = PyObject_CallMethod(string_io_mod, "StringIO", NULL))) {
goto error_cleanup;

View File

@@ -27,7 +27,10 @@
#ifndef BPY_UTIL_H
#define BPY_UTIL_H
#include "bpy_compat.h"
#if PY_VERSION_HEX < 0x03010000
#error "Python versions below 3.1 are not supported anymore, you'll need to update your python."
#endif
#include "RNA_types.h" /* for EnumPropertyItem only */
struct EnumPropertyItem;
@@ -47,6 +50,8 @@ void PyObSpit(char *name, PyObject *var);
void PyLineSpit(void);
void BPY_getFileAndNum(char **filename, int *lineno);
PyObject *Py_CmpToRich(int op, int cmp);
PyObject *BPY_exception_buffer(void);
/* own python like utility function */
@@ -72,7 +77,7 @@ int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_c
char *BPy_enum_as_string(struct EnumPropertyItem *item);
#define BLANK_PYTHON_TYPE {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
/* error reporting */
int BPy_reports_to_error(struct ReportList *reports);
@@ -82,4 +87,8 @@ int BPy_errors_to_report(struct ReportList *reports);
struct bContext *BPy_GetContext(void);
void BPy_SetContext(struct bContext *C);
extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate);
extern void bpy_context_clear(struct bContext *C, PyGILState_STATE *gilstate);
#endif