merge with 2.5 at r22793
This commit is contained in:
@@ -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
|
||||
|
||||
235
source/blender/python/intern/bpy_array.c
Normal file
235
source/blender/python/intern/bpy_array.c
Normal 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);
|
||||
}
|
||||
@@ -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__ */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user