2008-11-29 13:36:08 +00:00
/**
* $ Id $
*
* * * * * * 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 * * * * *
*/
# include "bpy_rna.h"
2009-04-07 00:49:39 +00:00
# include "bpy_util.h"
2008-11-30 14:00:14 +00:00
//#include "blendef.h"
# include "BLI_dynstr.h"
2009-03-19 19:03:38 +00:00
# include "BLI_listbase.h"
2009-04-19 13:37:59 +00:00
# include "BLI_string.h"
2009-03-16 15:54:43 +00:00
# include "float.h" /* FLT_MIN/MAX */
2009-04-19 13:37:59 +00:00
# include "RNA_access.h"
2009-03-16 15:54:43 +00:00
# include "RNA_define.h" /* for defining our own rna */
2008-11-29 13:36:08 +00:00
# include "MEM_guardedalloc.h"
2009-07-01 13:31:36 +00:00
# include "BKE_utildefines.h"
2009-03-19 19:03:38 +00:00
# include "BKE_context.h"
2008-11-29 13:36:08 +00:00
# include "BKE_global.h" /* evil G.* */
2009-04-19 13:37:59 +00:00
# include "BKE_report.h"
2008-11-29 13:36:08 +00:00
2009-07-08 09:23:49 +00:00
/* only for keyframing */
# include "DNA_scene_types.h"
# include "ED_keyframing.h"
2009-06-22 04:26:48 +00:00
# define USE_MATHUTILS
# ifdef USE_MATHUTILS
# include "../generic/Mathutils.h" /* so we can have mathutils callbacks */
2009-06-25 10:11:37 +00:00
/* bpyrna vector/euler/quat callbacks */
static int mathutils_rna_array_cb_index = - 1 ; /* index for our callbacks */
2009-06-22 04:26:48 +00:00
2009-06-23 13:34:45 +00:00
static int mathutils_rna_generic_check ( BPy_PropertyRNA * self )
2009-06-22 04:26:48 +00:00
{
2009-06-23 12:36:15 +00:00
return self - > prop ? 1 : 0 ;
2009-06-22 04:26:48 +00:00
}
static int mathutils_rna_vector_get ( BPy_PropertyRNA * self , int subtype , float * vec_from )
{
if ( self - > prop = = NULL )
return 0 ;
RNA_property_float_get_array ( & self - > ptr , self - > prop , vec_from ) ;
return 1 ;
}
static int mathutils_rna_vector_set ( BPy_PropertyRNA * self , int subtype , float * vec_to )
{
if ( self - > prop = = NULL )
return 0 ;
RNA_property_float_set_array ( & self - > ptr , self - > prop , vec_to ) ;
return 1 ;
}
static int mathutils_rna_vector_get_index ( BPy_PropertyRNA * self , int subtype , float * vec_from , int index )
{
if ( self - > prop = = NULL )
return 0 ;
vec_from [ index ] = RNA_property_float_get_index ( & self - > ptr , self - > prop , index ) ;
return 1 ;
}
static int mathutils_rna_vector_set_index ( BPy_PropertyRNA * self , int subtype , float * vec_to , int index )
{
if ( self - > prop = = NULL )
return 0 ;
RNA_property_float_set_index ( & self - > ptr , self - > prop , index , vec_to [ index ] ) ;
return 1 ;
}
2009-06-25 10:11:37 +00:00
Mathutils_Callback mathutils_rna_array_cb = {
2009-07-10 18:09:53 +00:00
( BaseMathCheckFunc ) mathutils_rna_generic_check ,
( BaseMathGetFunc ) mathutils_rna_vector_get ,
( BaseMathSetFunc ) mathutils_rna_vector_set ,
( BaseMathGetIndexFunc ) mathutils_rna_vector_get_index ,
( BaseMathSetIndexFunc ) mathutils_rna_vector_set_index
2009-06-22 04:26:48 +00:00
} ;
2009-07-10 18:09:53 +00:00
2009-06-23 13:34:45 +00:00
/* bpyrna matrix callbacks */
static int mathutils_rna_matrix_cb_index = - 1 ; /* index for our callbacks */
static int mathutils_rna_matrix_get ( BPy_PropertyRNA * self , int subtype , float * mat_from )
{
if ( self - > prop = = NULL )
return 0 ;
RNA_property_float_get_array ( & self - > ptr , self - > prop , mat_from ) ;
return 1 ;
}
static int mathutils_rna_matrix_set ( BPy_PropertyRNA * self , int subtype , float * mat_to )
{
if ( self - > prop = = NULL )
return 0 ;
RNA_property_float_set_array ( & self - > ptr , self - > prop , mat_to ) ;
return 1 ;
}
Mathutils_Callback mathutils_rna_matrix_cb = {
2009-07-10 18:09:53 +00:00
( BaseMathCheckFunc ) mathutils_rna_generic_check ,
( BaseMathGetFunc ) mathutils_rna_matrix_get ,
( BaseMathSetFunc ) mathutils_rna_matrix_set ,
( BaseMathGetIndexFunc ) NULL ,
( BaseMathSetIndexFunc ) NULL
2009-06-23 13:34:45 +00:00
} ;
2009-06-22 04:26:48 +00:00
# endif
2008-11-29 13:36:08 +00:00
static int pyrna_struct_compare ( BPy_StructRNA * a , BPy_StructRNA * b )
2009-01-29 09:38:52 +00:00
{
2008-11-29 13:36:08 +00:00
return ( a - > ptr . data = = b - > ptr . data ) ? 0 : - 1 ;
}
static int pyrna_prop_compare ( BPy_PropertyRNA * a , BPy_PropertyRNA * b )
{
return ( a - > prop = = b - > prop & & a - > ptr . data = = b - > ptr . data ) ? 0 : - 1 ;
}
2009-01-29 09:38:52 +00:00
/* For some reason python3 needs these :/ */
static PyObject * pyrna_struct_richcmp ( BPy_StructRNA * a , BPy_StructRNA * b , int op )
{
int cmp_result = - 1 ; /* assume false */
if ( BPy_StructRNA_Check ( a ) & & BPy_StructRNA_Check ( b ) ) {
cmp_result = pyrna_struct_compare ( a , b ) ;
}
return Py_CmpToRich ( op , cmp_result ) ;
}
static PyObject * pyrna_prop_richcmp ( BPy_PropertyRNA * a , BPy_PropertyRNA * b , int op )
{
int cmp_result = - 1 ; /* assume false */
if ( BPy_PropertyRNA_Check ( a ) & & BPy_PropertyRNA_Check ( b ) ) {
cmp_result = pyrna_prop_compare ( a , b ) ;
}
return Py_CmpToRich ( op , cmp_result ) ;
}
2009-04-07 00:49:39 +00:00
2008-11-29 13:36:08 +00:00
/*----------------------repr--------------------------------------------*/
static PyObject * pyrna_struct_repr ( BPy_StructRNA * self )
{
2009-06-24 14:03:55 +00:00
PyObject * pyob ;
char * name ;
2009-03-23 13:28:42 +00:00
/* print name if available */
2009-07-26 18:18:14 +00:00
name = RNA_struct_name_get_alloc ( & self - > ptr , NULL , FALSE ) ;
2009-06-24 14:03:55 +00:00
if ( name ) {
2009-07-09 08:06:26 +00:00
pyob = PyUnicode_FromFormat ( " [BPy_StructRNA \" %.200s \" -> \" %.200s \" ] " , RNA_struct_identifier ( self - > ptr . type ) , name ) ;
2009-06-24 14:03:55 +00:00
MEM_freeN ( name ) ;
return pyob ;
2009-03-23 13:28:42 +00:00
}
2009-07-09 08:06:26 +00:00
return PyUnicode_FromFormat ( " [BPy_StructRNA \" %.200s \" ] " , RNA_struct_identifier ( self - > ptr . type ) ) ;
2008-11-29 13:36:08 +00:00
}
static PyObject * pyrna_prop_repr ( BPy_PropertyRNA * self )
{
2009-06-24 14:03:55 +00:00
PyObject * pyob ;
2009-03-23 13:28:42 +00:00
PointerRNA ptr ;
2009-06-24 14:03:55 +00:00
char * name ;
2009-03-23 13:28:42 +00:00
/* if a pointer, try to print name of pointer target too */
2009-04-19 13:37:59 +00:00
if ( RNA_property_type ( self - > prop ) = = PROP_POINTER ) {
2009-03-23 13:28:42 +00:00
ptr = RNA_property_pointer_get ( & self - > ptr , self - > prop ) ;
2009-07-26 18:18:14 +00:00
name = RNA_struct_name_get_alloc ( & ptr , NULL , FALSE ) ;
2009-03-23 13:28:42 +00:00
2009-06-24 14:03:55 +00:00
if ( name ) {
2009-07-09 08:06:26 +00:00
pyob = PyUnicode_FromFormat ( " [BPy_PropertyRNA \" %.200s \" -> \" %.200s \" -> \" %.200s \" ] " , RNA_struct_identifier ( self - > ptr . type ) , RNA_property_identifier ( self - > prop ) , name ) ;
2009-06-24 14:03:55 +00:00
MEM_freeN ( name ) ;
return pyob ;
2009-03-23 13:28:42 +00:00
}
}
2009-07-09 08:06:26 +00:00
return PyUnicode_FromFormat ( " [BPy_PropertyRNA \" %.200s \" -> \" %.200s \" ] " , RNA_struct_identifier ( self - > ptr . type ) , RNA_property_identifier ( self - > prop ) ) ;
2008-11-29 13:36:08 +00:00
}
2009-04-09 17:31:23 +00:00
2008-12-02 14:36:35 +00:00
static long pyrna_struct_hash ( BPy_StructRNA * self )
{
return ( long ) self - > ptr . data ;
}
2008-12-29 03:24:13 +00:00
/* use our own dealloc so we can free a property if we use one */
static void pyrna_struct_dealloc ( BPy_StructRNA * self )
{
2009-01-08 15:29:09 +00:00
if ( self - > freeptr & & self - > ptr . data ) {
IDP_FreeProperty ( self - > ptr . data ) ;
MEM_freeN ( self - > ptr . data ) ;
self - > ptr . data = NULL ;
2008-12-29 03:24:13 +00:00
}
2009-06-29 12:06:46 +00:00
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
2009-03-16 15:54:43 +00:00
Py_TYPE ( self ) - > tp_free ( self ) ;
2008-12-29 03:24:13 +00:00
return ;
}
2009-04-07 00:49:39 +00:00
2008-12-25 10:48:36 +00:00
static char * pyrna_enum_as_string ( PointerRNA * ptr , PropertyRNA * prop )
{
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
EnumPropertyItem * item ;
char * result ;
2009-07-26 18:18:14 +00:00
int free = FALSE ;
2008-12-25 10:48:36 +00:00
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
RNA_property_enum_items ( BPy_GetContext ( ) , ptr , prop , & item , NULL , & free ) ;
2009-07-13 19:33:59 +00:00
if ( item ) {
result = ( char * ) BPy_enum_as_string ( item ) ;
}
else {
result = " " ;
}
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
if ( free )
MEM_freeN ( item ) ;
return result ;
2008-12-25 10:48:36 +00:00
}
2008-12-02 14:36:35 +00:00
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
PyObject * pyrna_prop_to_py ( PointerRNA * ptr , PropertyRNA * prop )
2008-11-29 13:36:08 +00:00
{
PyObject * ret ;
2009-04-19 13:37:59 +00:00
int type = RNA_property_type ( prop ) ;
int len = RNA_property_array_length ( prop ) ;
2009-03-05 08:53:29 +00:00
2008-11-29 13:36:08 +00:00
if ( len > 0 ) {
/* resolve the array from a new pytype */
2009-06-22 04:26:48 +00:00
PyObject * ret = pyrna_prop_CreatePyObject ( ptr , prop ) ;
# ifdef USE_MATHUTILS
2009-06-25 10:11:37 +00:00
2009-06-22 04:26:48 +00:00
/* return a mathutils vector where possible */
2009-06-23 13:34:45 +00:00
if ( RNA_property_type ( prop ) = = PROP_FLOAT ) {
2009-06-25 10:11:37 +00:00
switch ( RNA_property_subtype ( prop ) ) {
RNA: subtypes and units
* Reviewed subtypes, making them more specific and adding new ones.
* Subtypes now have an associated type of units (length, area, volume,
mass, rotation, time, velocity, acceleration). These are not used
yet anywhere.
* Centralized code that decides the name of array items based on
subtype (XYZ, RGB), was copied in 3 places.
* RNA_def_float etc functions still need to be update, will do this
later together with another change.
2009-08-10 21:31:05 +00:00
case PROP_TRANSLATION :
case PROP_DIRECTION :
case PROP_VELOCITY :
case PROP_ACCELERATION :
case PROP_XYZ :
2009-06-23 13:34:45 +00:00
if ( len > = 2 & & len < = 4 ) {
2009-07-26 18:18:14 +00:00
PyObject * vec_cb = newVectorObject_cb ( ret , len , mathutils_rna_array_cb_index , FALSE ) ;
2009-06-23 13:34:45 +00:00
Py_DECREF ( ret ) ; /* the vector owns now */
ret = vec_cb ; /* return the vector instead */
}
2009-06-25 10:11:37 +00:00
break ;
case PROP_MATRIX :
2009-06-23 13:34:45 +00:00
if ( len = = 16 ) {
2009-07-26 18:18:14 +00:00
PyObject * mat_cb = newMatrixObject_cb ( ret , 4 , 4 , mathutils_rna_matrix_cb_index , FALSE ) ;
2009-06-23 13:34:45 +00:00
Py_DECREF ( ret ) ; /* the matrix owns now */
ret = mat_cb ; /* return the matrix instead */
}
else if ( len = = 9 ) {
2009-07-26 18:18:14 +00:00
PyObject * mat_cb = newMatrixObject_cb ( ret , 3 , 3 , mathutils_rna_matrix_cb_index , FALSE ) ;
2009-06-23 13:34:45 +00:00
Py_DECREF ( ret ) ; /* the matrix owns now */
ret = mat_cb ; /* return the matrix instead */
}
2009-06-25 10:11:37 +00:00
break ;
RNA: subtypes and units
* Reviewed subtypes, making them more specific and adding new ones.
* Subtypes now have an associated type of units (length, area, volume,
mass, rotation, time, velocity, acceleration). These are not used
yet anywhere.
* Centralized code that decides the name of array items based on
subtype (XYZ, RGB), was copied in 3 places.
* RNA_def_float etc functions still need to be update, will do this
later together with another change.
2009-08-10 21:31:05 +00:00
case PROP_EULER :
case PROP_QUATERNION :
2009-06-25 10:11:37 +00:00
if ( len = = 3 ) { /* euler */
2009-07-26 18:18:14 +00:00
PyObject * eul_cb = newEulerObject_cb ( ret , mathutils_rna_array_cb_index , FALSE ) ;
2009-06-25 10:11:37 +00:00
Py_DECREF ( ret ) ; /* the matrix owns now */
ret = eul_cb ; /* return the matrix instead */
}
else if ( len = = 4 ) {
2009-07-26 18:18:14 +00:00
PyObject * quat_cb = newQuaternionObject_cb ( ret , mathutils_rna_array_cb_index , FALSE ) ;
2009-06-25 10:11:37 +00:00
Py_DECREF ( ret ) ; /* the matrix owns now */
ret = quat_cb ; /* return the matrix instead */
}
break ;
2009-06-27 01:10:39 +00:00
default :
break ;
2009-06-23 13:34:45 +00:00
}
2009-06-22 04:26:48 +00:00
}
2009-06-23 13:34:45 +00:00
2009-06-22 04:26:48 +00:00
# endif
return ret ;
2008-11-29 13:36:08 +00:00
}
/* see if we can coorce into a python type - PropertyType */
switch ( type ) {
case PROP_BOOLEAN :
ret = PyBool_FromLong ( RNA_property_boolean_get ( ptr , prop ) ) ;
break ;
case PROP_INT :
2009-03-29 04:34:20 +00:00
ret = PyLong_FromSsize_t ( ( Py_ssize_t ) RNA_property_int_get ( ptr , prop ) ) ;
2008-11-29 13:36:08 +00:00
break ;
case PROP_FLOAT :
ret = PyFloat_FromDouble ( RNA_property_float_get ( ptr , prop ) ) ;
break ;
case PROP_STRING :
{
char * buf ;
buf = RNA_property_string_get_alloc ( ptr , prop , NULL , - 1 ) ;
ret = PyUnicode_FromString ( buf ) ;
MEM_freeN ( buf ) ;
break ;
}
case PROP_ENUM :
2008-12-02 14:36:35 +00:00
{
const char * identifier ;
int val = RNA_property_enum_get ( ptr , prop ) ;
2008-11-29 17:58:17 +00:00
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
if ( RNA_property_enum_identifier ( BPy_GetContext ( ) , ptr , prop , val , & identifier ) ) {
2008-12-02 14:36:35 +00:00
ret = PyUnicode_FromString ( identifier ) ;
2008-11-29 17:58:17 +00:00
} else {
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
EnumPropertyItem * item ;
2009-07-26 18:18:14 +00:00
int free = FALSE ;
2009-07-03 19:56:19 +00:00
/* don't throw error here, can't trust blender 100% to give the
* right values , python code should not generate error for that */
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
RNA_property_enum_items ( BPy_GetContext ( ) , ptr , prop , & item , NULL , & free ) ;
2009-07-13 19:33:59 +00:00
if ( item & & item - > identifier ) {
2009-07-08 09:23:49 +00:00
ret = PyUnicode_FromString ( item - > identifier ) ;
}
else {
/* prefer not fail silently incase of api errors, maybe disable it later */
char error_str [ 128 ] ;
sprintf ( error_str , " RNA Warning: Current value \" %d \" matches no enum " , val ) ;
PyErr_Warn ( PyExc_RuntimeWarning , error_str ) ;
2009-07-03 19:56:19 +00:00
ret = PyUnicode_FromString ( " " ) ;
2009-07-08 09:23:49 +00:00
}
2009-07-03 19:56:19 +00:00
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
if ( free )
MEM_freeN ( item ) ;
2009-07-03 19:56:19 +00:00
/*PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
ret = NULL ; */
2008-11-29 13:36:08 +00:00
}
2008-12-02 14:36:35 +00:00
2008-11-29 13:36:08 +00:00
break ;
}
case PROP_POINTER :
{
PointerRNA newptr ;
2009-02-02 19:57:57 +00:00
newptr = RNA_property_pointer_get ( ptr , prop ) ;
2008-11-29 13:36:08 +00:00
if ( newptr . data ) {
ret = pyrna_struct_CreatePyObject ( & newptr ) ;
} else {
ret = Py_None ;
Py_INCREF ( ret ) ;
}
break ;
}
case PROP_COLLECTION :
2009-03-05 12:09:30 +00:00
ret = pyrna_prop_CreatePyObject ( ptr , prop ) ;
2008-11-29 13:36:08 +00:00
break ;
default :
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " RNA Error: unknown type \" %d \" (pyrna_prop_to_py) " , type ) ;
2008-11-29 13:36:08 +00:00
ret = NULL ;
break ;
}
return ret ;
}
2009-07-30 01:52:00 +00:00
/* This function is used by operators and converting dicts into collections.
* Its takes keyword args and fills them with property values */
int pyrna_pydict_to_props ( PointerRNA * ptr , PyObject * kw , int all_args , const char * error_prefix )
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
{
int error_val = 0 ;
int totkw ;
const char * arg_name = NULL ;
PyObject * item ;
totkw = kw ? PyDict_Size ( kw ) : 0 ;
2009-06-24 21:27:10 +00:00
RNA_STRUCT_BEGIN ( ptr , prop ) {
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
arg_name = RNA_property_identifier ( prop ) ;
if ( strcmp ( arg_name , " rna_type " ) = = 0 ) continue ;
if ( kw = = NULL ) {
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s: no keywords, expected \" %.200s \" " , error_prefix , arg_name ? arg_name : " <UNKNOWN> " ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
error_val = - 1 ;
break ;
}
2009-07-30 01:52:00 +00:00
item = PyDict_GetItemString ( kw , arg_name ) ; /* wont set an error */
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
if ( item = = NULL ) {
2009-07-30 01:52:00 +00:00
if ( all_args ) {
PyErr_Format ( PyExc_TypeError , " %.200s: keyword \" %.200s \" missing " , error_prefix , arg_name ? arg_name : " <UNKNOWN> " ) ;
error_val = - 1 ; /* pyrna_py_to_prop sets the error */
break ;
}
} else {
if ( pyrna_py_to_prop ( ptr , prop , NULL , item , error_prefix ) ) {
error_val = - 1 ;
break ;
}
totkw - - ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
}
}
2009-06-24 21:27:10 +00:00
RNA_STRUCT_END ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
if ( error_val = = 0 & & totkw > 0 ) { /* some keywords were given that were not used :/ */
PyObject * key , * value ;
Py_ssize_t pos = 0 ;
while ( PyDict_Next ( kw , & pos , & key , & value ) ) {
arg_name = _PyUnicode_AsString ( key ) ;
if ( RNA_struct_find_property ( ptr , arg_name ) = = NULL ) break ;
arg_name = NULL ;
}
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s: keyword \" %.200s \" unrecognized " , error_prefix , arg_name ? arg_name : " <UNKNOWN> " ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
error_val = - 1 ;
}
return error_val ;
}
2009-04-09 13:20:48 +00:00
static PyObject * pyrna_func_call ( PyObject * self , PyObject * args , PyObject * kw ) ;
2009-06-25 10:11:37 +00:00
PyObject * pyrna_func_to_py ( BPy_StructRNA * pyrna , FunctionRNA * func )
2009-04-09 17:31:23 +00:00
{
2009-04-09 13:20:48 +00:00
static PyMethodDef func_meth = { " <generic rna function> " , ( PyCFunction ) pyrna_func_call , METH_VARARGS | METH_KEYWORDS , " python rna function " } ;
2009-07-17 12:26:40 +00:00
PyObject * self ;
2009-04-09 13:20:48 +00:00
PyObject * ret ;
2009-07-17 12:26:40 +00:00
if ( func = = NULL ) {
PyErr_Format ( PyExc_RuntimeError , " %.200s: type attempted to get NULL function " , RNA_struct_identifier ( pyrna - > ptr . type ) ) ;
return NULL ;
}
2009-06-25 10:11:37 +00:00
2009-07-17 12:26:40 +00:00
self = PyTuple_New ( 2 ) ;
2009-06-25 10:11:37 +00:00
PyTuple_SET_ITEM ( self , 0 , ( PyObject * ) pyrna ) ;
Py_INCREF ( pyrna ) ;
2009-04-09 13:20:48 +00:00
PyTuple_SET_ITEM ( self , 1 , PyCObject_FromVoidPtr ( ( void * ) func , NULL ) ) ;
ret = PyCFunction_New ( & func_meth , self ) ;
Py_DECREF ( self ) ;
return ret ;
2009-04-07 00:49:39 +00:00
}
2008-11-29 17:58:17 +00:00
2009-04-16 13:21:18 +00:00
2009-07-23 13:48:15 +00:00
int pyrna_py_to_prop ( PointerRNA * ptr , PropertyRNA * prop , void * data , PyObject * value , const char * error_prefix )
2008-11-29 17:58:17 +00:00
{
2009-04-16 13:21:18 +00:00
/* XXX hard limits should be checked here */
2009-04-19 13:37:59 +00:00
int type = RNA_property_type ( prop ) ;
int len = RNA_property_array_length ( prop ) ;
2008-11-29 17:58:17 +00:00
if ( len > 0 ) {
2008-11-30 03:52:07 +00:00
PyObject * item ;
2009-06-23 17:10:46 +00:00
int py_len = - 1 ;
2008-11-30 03:52:07 +00:00
int i ;
2008-11-29 17:58:17 +00:00
2009-06-23 17:10:46 +00:00
# ifdef USE_MATHUTILS
if ( MatrixObject_Check ( value ) ) {
MatrixObject * mat = ( MatrixObject * ) value ;
2009-06-25 10:11:37 +00:00
if ( ! BaseMath_ReadCallback ( mat ) )
2009-06-23 17:10:46 +00:00
return - 1 ;
py_len = mat - > rowSize * mat - > colSize ;
2009-06-25 10:11:37 +00:00
} else /* continue... */
2009-06-23 17:10:46 +00:00
# endif
if ( PySequence_Check ( value ) ) {
py_len = ( int ) PySequence_Length ( value ) ;
}
else {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s RNA array assignment expected a sequence instead of %.200s instance. " , error_prefix , Py_TYPE ( value ) - > tp_name ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
2008-11-29 17:58:17 +00:00
}
2009-06-23 17:10:46 +00:00
/* done getting the length */
2008-11-30 03:52:07 +00:00
2009-06-23 17:10:46 +00:00
if ( py_len ! = len ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s python sequence length %d did not match the RNA array length %d. " , error_prefix , py_len , len ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
2008-11-29 17:58:17 +00:00
}
2008-11-30 03:52:07 +00:00
/* for arrays we have a limited number of types */
switch ( type ) {
case PROP_BOOLEAN :
{
2009-04-16 13:21:18 +00:00
int * param_arr ;
if ( data ) param_arr = ( int * ) data ;
2009-07-19 09:33:27 +00:00
else param_arr = MEM_mallocN ( sizeof ( int ) * len , " pyrna bool array " ) ;
2009-04-16 13:21:18 +00:00
2008-11-30 03:52:07 +00:00
/* 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 ) {
2009-04-16 13:21:18 +00:00
if ( data = = NULL )
MEM_freeN ( param_arr ) ;
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_AttributeError , " %.200s one or more of the values in the sequence is not a boolean " , error_prefix ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
}
}
2009-04-16 13:21:18 +00:00
if ( data = = NULL ) {
RNA_property_boolean_set_array ( ptr , prop , param_arr ) ;
MEM_freeN ( param_arr ) ;
}
2008-11-30 03:52:07 +00:00
break ;
2008-11-29 17:58:17 +00:00
}
2008-11-30 03:52:07 +00:00
case PROP_INT :
{
2009-04-16 13:21:18 +00:00
int * param_arr ;
if ( data ) param_arr = ( int * ) data ;
else param_arr = MEM_mallocN ( sizeof ( int ) * len , " pyrna int array " ) ;
2008-11-30 03:52:07 +00:00
2009-04-16 13:21:18 +00:00
/* collect the variables */
2008-11-30 03:52:07 +00:00
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 ( ) ) {
2009-04-16 13:21:18 +00:00
if ( data = = NULL )
MEM_freeN ( param_arr ) ;
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_AttributeError , " %.200s one or more of the values in the sequence could not be used as an int " , error_prefix ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
}
2009-04-16 13:21:18 +00:00
if ( data = = NULL ) {
RNA_property_int_set_array ( ptr , prop , param_arr ) ;
MEM_freeN ( param_arr ) ;
}
2008-11-30 03:52:07 +00:00
break ;
}
case PROP_FLOAT :
{
2009-04-16 13:21:18 +00:00
float * param_arr ;
if ( data ) param_arr = ( float * ) data ;
else param_arr = MEM_mallocN ( sizeof ( float ) * len , " pyrna float array " ) ;
2009-06-23 17:10:46 +00:00
# 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 ) ;
2009-06-25 10:11:37 +00:00
} else /* continue... */
2009-06-23 17:10:46 +00:00
# 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 ) ;
}
2008-11-30 03:52:07 +00:00
}
2009-06-23 17:10:46 +00:00
2008-11-30 03:52:07 +00:00
if ( PyErr_Occurred ( ) ) {
2009-04-16 13:21:18 +00:00
if ( data = = NULL )
MEM_freeN ( param_arr ) ;
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_AttributeError , " %.200s one or more of the values in the sequence could not be used as a float " , error_prefix ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
}
2009-04-16 13:21:18 +00:00
if ( data = = NULL ) {
RNA_property_float_set_array ( ptr , prop , param_arr ) ;
MEM_freeN ( param_arr ) ;
}
2008-11-30 03:52:07 +00:00
break ;
}
}
} else {
/* Normal Property (not an array) */
2008-11-29 17:58:17 +00:00
2008-11-30 03:52:07 +00:00
/* see if we can coorce into a python type - PropertyType */
switch ( type ) {
case PROP_BOOLEAN :
{
int param = PyObject_IsTrue ( value ) ;
2008-11-29 17:58:17 +00:00
2008-11-30 03:52:07 +00:00
if ( param < 0 ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected True/False or 0/1 " , error_prefix ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
} else {
2009-04-16 13:21:18 +00:00
if ( data ) * ( ( int * ) data ) = param ;
else RNA_property_boolean_set ( ptr , prop , param ) ;
2008-11-30 03:52:07 +00:00
}
break ;
}
case PROP_INT :
{
int param = PyLong_AsSsize_t ( value ) ;
if ( PyErr_Occurred ( ) ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected an int type " , error_prefix ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
} else {
2009-04-16 13:21:18 +00:00
if ( data ) * ( ( int * ) data ) = param ;
else RNA_property_int_set ( ptr , prop , param ) ;
2008-11-30 03:52:07 +00:00
}
break ;
}
case PROP_FLOAT :
{
float param = PyFloat_AsDouble ( value ) ;
if ( PyErr_Occurred ( ) ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a float type " , error_prefix ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
} else {
2009-04-16 13:21:18 +00:00
if ( data ) * ( ( float * ) data ) = param ;
else RNA_property_float_set ( ptr , prop , param ) ;
2008-11-30 03:52:07 +00:00
}
break ;
}
case PROP_STRING :
{
char * param = _PyUnicode_AsString ( value ) ;
2008-11-29 17:58:17 +00:00
2008-11-30 03:52:07 +00:00
if ( param = = NULL ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a string type " , error_prefix ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
} else {
2009-04-16 13:21:18 +00:00
if ( data ) * ( ( char * * ) data ) = param ;
else RNA_property_string_set ( ptr , prop , param ) ;
2008-11-29 17:58:17 +00:00
}
2008-11-30 03:52:07 +00:00
break ;
}
case PROP_ENUM :
{
char * param = _PyUnicode_AsString ( value ) ;
2008-11-29 17:58:17 +00:00
2008-11-30 03:52:07 +00:00
if ( param = = NULL ) {
2008-12-25 10:48:36 +00:00
char * enum_str = pyrna_enum_as_string ( ptr , prop ) ;
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a string enum type in (%.200s) " , error_prefix , enum_str ) ;
2008-12-25 10:48:36 +00:00
MEM_freeN ( enum_str ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
2008-11-29 17:58:17 +00:00
} else {
2008-12-02 14:36:35 +00:00
int val ;
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
if ( RNA_property_enum_value ( BPy_GetContext ( ) , ptr , prop , param , & val ) ) {
2009-04-16 13:21:18 +00:00
if ( data ) * ( ( int * ) data ) = val ;
else RNA_property_enum_set ( ptr , prop , val ) ;
2008-11-30 03:52:07 +00:00
} else {
2008-12-25 10:48:36 +00:00
char * enum_str = pyrna_enum_as_string ( ptr , prop ) ;
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s enum \" %.200s \" not found in (%.200s) " , error_prefix , param , enum_str ) ;
2008-12-25 10:48:36 +00:00
MEM_freeN ( enum_str ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
}
2008-11-29 17:58:17 +00:00
}
2008-11-30 03:52:07 +00:00
break ;
}
case PROP_POINTER :
{
2009-06-07 13:09:18 +00:00
StructRNA * ptype = RNA_property_pointer_type ( ptr , prop ) ;
2009-03-23 13:28:42 +00:00
2009-06-07 13:09:18 +00:00
if ( ! BPy_StructRNA_Check ( value ) & & value ! = Py_None ) {
2009-03-23 13:28:42 +00:00
PointerRNA tmp ;
RNA_pointer_create ( NULL , ptype , NULL , & tmp ) ;
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a %.200s type " , error_prefix , RNA_struct_identifier ( tmp . type ) ) ;
2009-03-23 13:28:42 +00:00
return - 1 ;
} else {
BPy_StructRNA * param = ( BPy_StructRNA * ) value ;
2009-07-26 18:18:14 +00:00
int raise_error = FALSE ;
2009-04-16 13:21:18 +00:00
if ( data ) {
2009-06-16 00:52:21 +00:00
int flag = RNA_property_flag ( prop ) ;
if ( flag & PROP_RNAPTR ) {
2009-06-07 13:09:18 +00:00
if ( value = = Py_None )
memset ( data , 0 , sizeof ( PointerRNA ) ) ;
else
* ( ( PointerRNA * ) data ) = param - > ptr ;
}
else if ( value = = Py_None ) {
* ( ( void * * ) data ) = NULL ;
2009-04-16 13:21:18 +00:00
}
2009-04-19 13:37:59 +00:00
else if ( RNA_struct_is_a ( param - > ptr . type , ptype ) ) {
2009-04-16 13:21:18 +00:00
* ( ( void * * ) data ) = param - > ptr . data ;
2009-06-07 13:09:18 +00:00
}
else {
2009-07-26 18:18:14 +00:00
raise_error = TRUE ;
2009-04-16 13:21:18 +00:00
}
}
else {
/* data==NULL, assign to RNA */
2009-06-07 13:09:18 +00:00
if ( value = = Py_None ) {
PointerRNA valueptr ;
memset ( & valueptr , 0 , sizeof ( valueptr ) ) ;
RNA_property_pointer_set ( ptr , prop , valueptr ) ;
}
else if ( RNA_struct_is_a ( param - > ptr . type , ptype ) ) {
2009-04-16 13:21:18 +00:00
RNA_property_pointer_set ( ptr , prop , param - > ptr ) ;
2009-06-07 13:09:18 +00:00
}
else {
2009-04-16 13:21:18 +00:00
PointerRNA tmp ;
RNA_pointer_create ( NULL , ptype , NULL , & tmp ) ;
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a %.200s type " , error_prefix , RNA_struct_identifier ( tmp . type ) ) ;
2009-04-16 13:21:18 +00:00
return - 1 ;
}
}
if ( raise_error ) {
2009-03-23 13:28:42 +00:00
PointerRNA tmp ;
RNA_pointer_create ( NULL , ptype , NULL , & tmp ) ;
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a %.200s type " , error_prefix , RNA_struct_identifier ( tmp . type ) ) ;
2009-03-23 13:28:42 +00:00
return - 1 ;
}
}
2008-11-30 03:52:07 +00:00
break ;
}
case PROP_COLLECTION :
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
{
int seq_len , i ;
PyObject * item ;
PointerRNA itemptr ;
2009-06-27 01:10:39 +00:00
ListBase * lb ;
CollectionPointerLink * link ;
lb = ( data ) ? ( ListBase * ) data : NULL ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
/* convert a sequence of dict's into a collection */
if ( ! PySequence_Check ( value ) ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a sequence of dicts for an RNA collection " , error_prefix ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
return - 1 ;
}
seq_len = PySequence_Length ( value ) ;
for ( i = 0 ; i < seq_len ; i + + ) {
item = PySequence_GetItem ( value , i ) ;
if ( item = = NULL | | PyDict_Check ( item ) = = 0 ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a sequence of dicts for an RNA collection " , error_prefix ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
Py_XDECREF ( item ) ;
return - 1 ;
}
2009-06-27 01:10:39 +00:00
if ( lb ) {
link = MEM_callocN ( sizeof ( CollectionPointerLink ) , " PyCollectionPointerLink " ) ;
link - > ptr = itemptr ;
BLI_addtail ( lb , link ) ;
}
else
RNA_property_collection_add ( ptr , prop , & itemptr ) ;
2009-07-30 01:52:00 +00:00
if ( pyrna_pydict_to_props ( & itemptr , item , 1 , " Converting a python list to an RNA collection " ) = = - 1 ) {
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
Py_DECREF ( item ) ;
return - 1 ;
}
Py_DECREF ( item ) ;
}
2008-11-30 03:52:07 +00:00
break ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
}
2008-11-30 03:52:07 +00:00
default :
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_AttributeError , " %.200s unknown property type (pyrna_py_to_prop) " , error_prefix ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
break ;
2008-11-29 17:58:17 +00:00
}
}
2008-11-30 03:52:07 +00:00
return 0 ;
2008-11-29 17:58:17 +00:00
}
2008-11-29 13:36:08 +00:00
static PyObject * pyrna_prop_to_py_index ( PointerRNA * ptr , PropertyRNA * prop , int index )
{
PyObject * ret ;
2009-04-19 13:37:59 +00:00
int type = RNA_property_type ( prop ) ;
2008-11-29 13:36:08 +00:00
/* see if we can coorce into a python type - PropertyType */
switch ( type ) {
case PROP_BOOLEAN :
2009-02-02 19:57:57 +00:00
ret = PyBool_FromLong ( RNA_property_boolean_get_index ( ptr , prop , index ) ) ;
2008-11-29 13:36:08 +00:00
break ;
case PROP_INT :
2009-03-29 04:34:20 +00:00
ret = PyLong_FromSsize_t ( ( Py_ssize_t ) RNA_property_int_get_index ( ptr , prop , index ) ) ;
2008-11-29 13:36:08 +00:00
break ;
case PROP_FLOAT :
2009-02-02 19:57:57 +00:00
ret = PyFloat_FromDouble ( RNA_property_float_get_index ( ptr , prop , index ) ) ;
2008-11-29 13:36:08 +00:00
break ;
default :
PyErr_SetString ( PyExc_AttributeError , " not an array type " ) ;
ret = NULL ;
break ;
}
return ret ;
}
2008-11-29 17:58:17 +00:00
static int pyrna_py_to_prop_index ( PointerRNA * ptr , PropertyRNA * prop , int index , PyObject * value )
{
int ret = 0 ;
2009-04-19 13:37:59 +00:00
int type = RNA_property_type ( prop ) ;
2008-11-29 17:58:17 +00:00
/* see if we can coorce into a python type - PropertyType */
switch ( type ) {
case PROP_BOOLEAN :
{
int param = PyObject_IsTrue ( value ) ;
2008-11-30 03:52:07 +00:00
if ( param < 0 ) {
2008-11-29 17:58:17 +00:00
PyErr_SetString ( PyExc_TypeError , " expected True/False or 0/1 " ) ;
ret = - 1 ;
} else {
2009-02-02 19:57:57 +00:00
RNA_property_boolean_set_index ( ptr , prop , index , param ) ;
2008-11-29 17:58:17 +00:00
}
break ;
}
case PROP_INT :
{
int param = PyLong_AsSsize_t ( value ) ;
if ( PyErr_Occurred ( ) ) {
PyErr_SetString ( PyExc_TypeError , " expected an int type " ) ;
ret = - 1 ;
} else {
2009-02-02 19:57:57 +00:00
RNA_property_int_set_index ( ptr , prop , index , param ) ;
2008-11-29 17:58:17 +00:00
}
break ;
}
case PROP_FLOAT :
{
float param = PyFloat_AsDouble ( value ) ;
if ( PyErr_Occurred ( ) ) {
PyErr_SetString ( PyExc_TypeError , " expected a float type " ) ;
ret = - 1 ;
} else {
2009-02-02 19:57:57 +00:00
RNA_property_float_set_index ( ptr , prop , index , param ) ;
2008-11-29 17:58:17 +00:00
}
break ;
}
default :
PyErr_SetString ( PyExc_AttributeError , " not an array type " ) ;
ret = - 1 ;
break ;
}
return ret ;
}
2008-11-29 13:36:08 +00:00
//---------------sequence-------------------------------------------
static Py_ssize_t pyrna_prop_len ( BPy_PropertyRNA * self )
{
Py_ssize_t len ;
2009-04-19 13:37:59 +00:00
if ( RNA_property_type ( self - > prop ) = = PROP_COLLECTION ) {
2008-11-29 13:36:08 +00:00
len = RNA_property_collection_length ( & self - > ptr , self - > prop ) ;
} else {
2009-04-19 13:37:59 +00:00
len = RNA_property_array_length ( self - > prop ) ;
2008-11-29 13:36:08 +00:00
if ( len = = 0 ) { /* not an array*/
PyErr_SetString ( PyExc_AttributeError , " len() only available for collection RNA types " ) ;
return - 1 ;
}
}
return len ;
}
2009-07-01 13:31:36 +00:00
/* internal use only */
static PyObject * prop_subscript_collection_int ( BPy_PropertyRNA * self , int keynum )
2008-11-29 13:36:08 +00:00
{
PointerRNA newptr ;
2009-07-01 13:31:36 +00:00
if ( keynum < 0 ) keynum + = RNA_property_collection_length ( & self - > ptr , self - > prop ) ;
if ( RNA_property_collection_lookup_int ( & self - > ptr , self - > prop , keynum , & newptr ) )
return pyrna_struct_CreatePyObject ( & newptr ) ;
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_IndexError , " index %d out of range " , keynum ) ;
2009-07-01 13:31:36 +00:00
return NULL ;
}
static PyObject * prop_subscript_array_int ( BPy_PropertyRNA * self , int keynum )
{
int len = RNA_property_array_length ( self - > prop ) ;
if ( keynum < 0 ) keynum + = len ;
if ( keynum > = 0 & & keynum < len )
return pyrna_prop_to_py_index ( & self - > ptr , self - > prop , keynum ) ;
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_IndexError , " index %d out of range " , keynum ) ;
2009-07-01 13:31:36 +00:00
return NULL ;
}
static PyObject * prop_subscript_collection_str ( BPy_PropertyRNA * self , char * keyname )
{
PointerRNA newptr ;
if ( RNA_property_collection_lookup_string ( & self - > ptr , self - > prop , keyname , & newptr ) )
return pyrna_struct_CreatePyObject ( & newptr ) ;
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_KeyError , " key \" %.200s \" not found " , keyname ) ;
2009-07-01 13:31:36 +00:00
return NULL ;
}
/* static PyObject *prop_subscript_array_str(BPy_PropertyRNA * self, char *keyname) */
static PyObject * prop_subscript_collection_slice ( BPy_PropertyRNA * self , int start , int stop )
{
PointerRNA newptr ;
PyObject * list = PyList_New ( stop - start ) ;
int count ;
start = MIN2 ( start , stop ) ; /* values are clamped from */
for ( count = start ; count < stop ; count + + ) {
if ( RNA_property_collection_lookup_int ( & self - > ptr , self - > prop , count - start , & newptr ) ) {
PyList_SetItem ( list , count - start , pyrna_struct_CreatePyObject ( & newptr ) ) ;
}
else {
Py_DECREF ( list ) ;
PyErr_SetString ( PyExc_RuntimeError , " error getting an rna struct from a collection " ) ;
return NULL ;
}
}
return list ;
}
static PyObject * prop_subscript_array_slice ( BPy_PropertyRNA * self , int start , int stop )
{
PyObject * list = PyList_New ( stop - start ) ;
int count ;
start = MIN2 ( start , stop ) ; /* values are clamped from PySlice_GetIndicesEx */
for ( count = start ; count < stop ; count + + )
PyList_SetItem ( list , count - start , pyrna_prop_to_py_index ( & self - > ptr , self - > prop , count ) ) ;
return list ;
}
static PyObject * prop_subscript_collection ( BPy_PropertyRNA * self , PyObject * key )
{
2008-11-29 13:36:08 +00:00
if ( PyUnicode_Check ( key ) ) {
2009-07-01 13:31:36 +00:00
return prop_subscript_collection_str ( self , _PyUnicode_AsString ( key ) ) ;
}
2009-07-08 09:23:49 +00:00
else if ( PyIndex_Check ( key ) ) {
Py_ssize_t i = PyNumber_AsSsize_t ( key , PyExc_IndexError ) ;
if ( i = = - 1 & & PyErr_Occurred ( ) )
return NULL ;
return prop_subscript_collection_int ( self , i ) ;
2009-07-01 13:31:36 +00:00
}
else if ( PySlice_Check ( key ) ) {
int len = RNA_property_collection_length ( & self - > ptr , self - > prop ) ;
Py_ssize_t start , stop , step , slicelength ;
if ( PySlice_GetIndicesEx ( ( PySliceObject * ) key , len , & start , & stop , & step , & slicelength ) < 0 )
return NULL ;
if ( slicelength < = 0 ) {
return PyList_New ( 0 ) ;
}
else if ( step = = 1 ) {
return prop_subscript_collection_slice ( self , start , stop ) ;
}
else {
PyErr_SetString ( PyExc_TypeError , " slice steps not supported with rna " ) ;
return NULL ;
}
}
else {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_TypeError , " invalid rna key, key must be a string or an int instead of %.200s instance. " , Py_TYPE ( key ) - > tp_name ) ;
2008-11-29 13:36:08 +00:00
return NULL ;
}
2009-07-01 13:31:36 +00:00
}
static PyObject * prop_subscript_array ( BPy_PropertyRNA * self , PyObject * key )
{
/*if (PyUnicode_Check(key)) {
return prop_subscript_array_str ( self , _PyUnicode_AsString ( key ) ) ;
} else */
2009-07-08 09:23:49 +00:00
if ( PyIndex_Check ( key ) ) {
Py_ssize_t i = PyNumber_AsSsize_t ( key , PyExc_IndexError ) ;
if ( i = = - 1 & & PyErr_Occurred ( ) )
return NULL ;
2009-07-01 13:31:36 +00:00
return prop_subscript_array_int ( self , PyLong_AsSsize_t ( key ) ) ;
}
else if ( PySlice_Check ( key ) ) {
int len = RNA_property_array_length ( self - > prop ) ;
Py_ssize_t start , stop , step , slicelength ;
if ( PySlice_GetIndicesEx ( ( PySliceObject * ) key , len , & start , & stop , & step , & slicelength ) < 0 )
return NULL ;
if ( slicelength < = 0 ) {
return PyList_New ( 0 ) ;
2008-11-29 13:36:08 +00:00
}
2009-07-01 13:31:36 +00:00
else if ( step = = 1 ) {
return prop_subscript_array_slice ( self , start , stop ) ;
2008-11-29 13:36:08 +00:00
}
2009-07-01 13:31:36 +00:00
else {
PyErr_SetString ( PyExc_TypeError , " slice steps not supported with rna " ) ;
return NULL ;
2008-11-29 13:36:08 +00:00
}
}
2009-07-01 13:31:36 +00:00
else {
PyErr_SetString ( PyExc_AttributeError , " invalid key, key must be an int " ) ;
return NULL ;
}
}
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 */
return prop_subscript_array ( self , key ) ;
} else {
PyErr_SetString ( PyExc_TypeError , " rna type is not an array or a collection " ) ;
return NULL ;
}
2008-11-29 13:36:08 +00:00
}
2009-07-01 13:31:36 +00:00
static int prop_subscript_ass_array_slice ( BPy_PropertyRNA * self , int begin , int end , PyObject * value )
{
int count ;
/* values are clamped from */
begin = MIN2 ( begin , end ) ;
2008-11-29 17:58:17 +00:00
2009-07-01 13:31:36 +00:00
for ( count = begin ; count < end ; count + + ) {
if ( pyrna_py_to_prop_index ( & self - > ptr , self - > prop , count - begin , value ) = = - 1 ) {
/* TODO - this is wrong since some values have been assigned... will need to fix that */
return - 1 ; /* pyrna_struct_CreatePyObject should set the error */
}
}
return 0 ;
}
static int prop_subscript_ass_array_int ( BPy_PropertyRNA * self , int keynum , PyObject * value )
2008-11-29 17:58:17 +00:00
{
2009-07-01 13:31:36 +00:00
int len = RNA_property_array_length ( self - > prop ) ;
if ( keynum < 0 ) keynum + = len ;
if ( keynum > = 0 & & keynum < len )
return pyrna_py_to_prop_index ( & self - > ptr , self - > prop , keynum , value ) ;
PyErr_SetString ( PyExc_IndexError , " out of range " ) ;
return - 1 ;
}
static int pyrna_prop_ass_subscript ( BPy_PropertyRNA * self , PyObject * key , PyObject * value )
{
/* char *keyname = NULL; */ /* not supported yet */
2008-11-29 17:58:17 +00:00
2008-11-30 03:52:07 +00:00
if ( ! RNA_property_editable ( & self - > ptr , self - > prop ) ) {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_AttributeError , " PropertyRNA - attribute \" %.200s \" from \" %.200s \" is read-only " , RNA_property_identifier ( self - > prop ) , RNA_struct_identifier ( self - > ptr . type ) ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
}
2009-07-01 13:31:36 +00:00
/* maybe one day we can support this... */
if ( RNA_property_type ( self - > prop ) = = PROP_COLLECTION ) {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_AttributeError , " PropertyRNA - attribute \" %.200s \" from \" %.200s \" is a collection, assignment not supported " , RNA_property_identifier ( self - > prop ) , RNA_struct_identifier ( self - > ptr . type ) ) ;
2008-11-29 17:58:17 +00:00
return - 1 ;
}
2009-07-01 13:31:36 +00:00
2009-07-08 09:23:49 +00:00
if ( PyIndex_Check ( key ) ) {
Py_ssize_t i = PyNumber_AsSsize_t ( key , PyExc_IndexError ) ;
if ( i = = - 1 & & PyErr_Occurred ( ) )
2009-07-09 08:06:26 +00:00
return - 1 ;
2009-07-08 09:23:49 +00:00
return prop_subscript_ass_array_int ( self , i , value ) ;
2009-07-01 13:31:36 +00:00
}
else if ( PySlice_Check ( key ) ) {
int len = RNA_property_array_length ( self - > prop ) ;
Py_ssize_t start , stop , step , slicelength ;
if ( PySlice_GetIndicesEx ( ( PySliceObject * ) key , len , & start , & stop , & step , & slicelength ) < 0 )
return - 1 ;
if ( slicelength < = 0 ) {
return 0 ;
2008-11-29 17:58:17 +00:00
}
2009-07-01 13:31:36 +00:00
else if ( step = = 1 ) {
return prop_subscript_ass_array_slice ( self , start , stop , value ) ;
}
else {
PyErr_SetString ( PyExc_TypeError , " slice steps not supported with rna " ) ;
return - 1 ;
2008-11-29 17:58:17 +00:00
}
}
2009-07-01 13:31:36 +00:00
else {
PyErr_SetString ( PyExc_AttributeError , " invalid key, key must be an int " ) ;
return - 1 ;
}
2008-11-29 17:58:17 +00:00
}
2008-11-29 13:36:08 +00:00
static PyMappingMethods pyrna_prop_as_mapping = {
2009-04-07 15:20:12 +00:00
( lenfunc ) pyrna_prop_len , /* mp_length */
2008-11-29 13:36:08 +00:00
( binaryfunc ) pyrna_prop_subscript , /* mp_subscript */
2009-07-01 13:31:36 +00:00
( objobjargproc ) pyrna_prop_ass_subscript , /* mp_ass_subscript */
2008-11-29 13:36:08 +00:00
} ;
2009-06-13 08:04:43 +00:00
static int pyrna_prop_contains ( BPy_PropertyRNA * self , PyObject * value )
{
PointerRNA newptr ; /* not used, just so RNA_property_collection_lookup_string runs */
char * keyname = _PyUnicode_AsString ( value ) ;
if ( keyname = = NULL ) {
2009-06-20 02:44:57 +00:00
PyErr_SetString ( PyExc_TypeError , " PropertyRNA - key in prop, key must be a string type " ) ;
2009-06-13 08:04:43 +00:00
return - 1 ;
}
if ( RNA_property_type ( self - > prop ) ! = PROP_COLLECTION ) {
2009-06-20 02:44:57 +00:00
PyErr_SetString ( PyExc_TypeError , " PropertyRNA - key in prop, is only valid for collection types " ) ;
2009-06-13 08:04:43 +00:00
return - 1 ;
}
if ( RNA_property_collection_lookup_string ( & self - > ptr , self - > prop , keyname , & newptr ) )
return 1 ;
return 0 ;
}
static PySequenceMethods pyrna_prop_as_sequence = {
NULL , /* Cant set the len otherwise it can evaluate as false */
NULL , /* sq_concat */
NULL , /* sq_repeat */
NULL , /* sq_item */
NULL , /* sq_slice */
NULL , /* sq_ass_item */
NULL , /* sq_ass_slice */
( objobjproc ) pyrna_prop_contains , /* sq_contains */
} ;
2009-07-08 09:23:49 +00:00
static PyObject * pyrna_struct_keyframe_insert ( BPy_StructRNA * self , PyObject * args )
{
char * path ;
int index = 0 ;
float cfra = CTX_data_scene ( BPy_GetContext ( ) ) - > r . cfra ;
if ( ! RNA_struct_is_ID ( self - > ptr . type ) ) {
PyErr_SetString ( PyExc_TypeError , " StructRNA - keyframe_insert only for ID type " ) ;
return NULL ;
}
if ( ! PyArg_ParseTuple ( args , " s|if:keyframe_insert " , & path , & index , & cfra ) )
return NULL ;
return PyBool_FromLong ( insert_keyframe ( ( ID * ) self - > ptr . data , NULL , NULL , path , index , cfra , 0 ) ) ;
}
2009-03-11 17:28:37 +00:00
static PyObject * pyrna_struct_dir ( BPy_StructRNA * self )
2008-11-30 14:00:14 +00:00
{
2009-03-11 17:28:37 +00:00
PyObject * ret , * dict ;
2009-03-21 06:55:30 +00:00
PyObject * pystring ;
2008-11-29 13:36:08 +00:00
2009-04-09 16:52:18 +00:00
/* for looping over attrs and funcs */
PropertyRNA * iterprop ;
2008-12-01 16:59:18 +00:00
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
* */
2009-03-21 06:55:30 +00:00
if ( BPy_StructRNA_CheckExact ( self ) ) {
2009-03-11 17:28:37 +00:00
ret = PyList_New ( 0 ) ;
2009-03-21 06:55:30 +00:00
} else {
pystring = PyUnicode_FromString ( " __dict__ " ) ;
dict = PyObject_GenericGetAttr ( ( PyObject * ) self , pystring ) ;
Py_DECREF ( pystring ) ;
if ( dict = = NULL ) {
PyErr_Clear ( ) ;
ret = PyList_New ( 0 ) ;
}
else {
ret = PyDict_Keys ( dict ) ;
Py_DECREF ( dict ) ;
}
2009-03-05 12:09:30 +00:00
}
2009-03-11 17:28:37 +00:00
/* Collect RNA items*/
{
2009-04-09 16:52:18 +00:00
/*
* Collect RNA attributes
*/
2009-03-05 12:09:30 +00:00
char name [ 256 ] , * nameptr ;
2009-04-19 13:37:59 +00:00
iterprop = RNA_struct_iterator_property ( self - > ptr . type ) ;
2009-03-05 12:09:30 +00:00
2009-06-24 21:27:10 +00:00
RNA_PROP_BEGIN ( & self - > ptr , itemptr , iterprop ) {
nameptr = RNA_struct_name_get_alloc ( & itemptr , name , sizeof ( name ) ) ;
2009-06-24 14:03:55 +00:00
if ( nameptr ) {
2009-03-11 17:28:37 +00:00
pystring = PyUnicode_FromString ( nameptr ) ;
PyList_Append ( ret , pystring ) ;
Py_DECREF ( pystring ) ;
2009-03-05 12:09:30 +00:00
2009-06-24 14:03:55 +00:00
if ( name ! = nameptr )
2009-03-05 12:09:30 +00:00
MEM_freeN ( nameptr ) ;
}
2008-11-29 13:36:08 +00:00
}
2009-06-24 21:27:10 +00:00
RNA_PROP_END ;
2009-04-09 16:52:18 +00:00
}
{
/*
* Collect RNA function items
*/
PointerRNA tptr ;
RNA_pointer_create ( NULL , & RNA_Struct , self - > ptr . type , & tptr ) ;
iterprop = RNA_struct_find_property ( & tptr , " functions " ) ;
2009-06-24 21:27:10 +00:00
RNA_PROP_BEGIN ( & tptr , itemptr , iterprop ) {
pystring = PyUnicode_FromString ( RNA_function_identifier ( itemptr . data ) ) ;
2009-04-09 16:52:18 +00:00
PyList_Append ( ret , pystring ) ;
Py_DECREF ( pystring ) ;
}
2009-06-24 21:27:10 +00:00
RNA_PROP_END ;
2009-03-05 12:09:30 +00:00
}
2009-06-20 14:55:28 +00:00
if ( self - > ptr . type = = & RNA_Context ) {
ListBase lb = CTX_data_dir_get ( self - > ptr . data ) ;
LinkData * link ;
for ( link = lb . first ; link ; link = link - > next ) {
pystring = PyUnicode_FromString ( link - > data ) ;
PyList_Append ( ret , pystring ) ;
Py_DECREF ( pystring ) ;
}
BLI_freelistN ( & lb ) ;
}
2009-03-11 17:28:37 +00:00
return ret ;
}
//---------------getattr--------------------------------------------
static PyObject * pyrna_struct_getattro ( BPy_StructRNA * self , PyObject * pyname )
{
char * name = _PyUnicode_AsString ( pyname ) ;
PyObject * ret ;
PropertyRNA * prop ;
2009-04-07 00:49:39 +00:00
FunctionRNA * func ;
2009-03-11 17:28:37 +00:00
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
2009-03-21 06:55:30 +00:00
*
* Also needed to return methods when its not a subtype
2009-03-11 17:28:37 +00:00
* */
2009-03-21 06:55:30 +00:00
ret = PyObject_GenericGetAttr ( ( PyObject * ) self , pyname ) ;
if ( ret ) return ret ;
else PyErr_Clear ( ) ;
2009-03-11 17:28:37 +00:00
/* done with subtypes */
2009-04-07 00:49:39 +00:00
if ( ( prop = RNA_struct_find_property ( & self - > ptr , name ) ) ) {
ret = pyrna_prop_to_py ( & self - > ptr , prop ) ;
}
else if ( ( func = RNA_struct_find_function ( & self - > ptr , name ) ) ) {
2009-06-25 10:11:37 +00:00
ret = pyrna_func_to_py ( self , func ) ;
2009-03-11 17:28:37 +00:00
}
2009-04-07 00:49:39 +00:00
else if ( self - > ptr . type = = & RNA_Context ) {
2009-03-19 19:03:38 +00:00
PointerRNA newptr ;
ListBase newlb ;
CTX_data_get ( self - > ptr . data , name , & newptr , & newlb ) ;
if ( newptr . data ) {
ret = pyrna_struct_CreatePyObject ( & newptr ) ;
}
else if ( newlb . first ) {
CollectionPointerLink * link ;
PyObject * linkptr ;
ret = PyList_New ( 0 ) ;
for ( link = newlb . first ; link ; link = link - > next ) {
linkptr = pyrna_struct_CreatePyObject ( & link - > ptr ) ;
PyList_Append ( ret , linkptr ) ;
Py_DECREF ( linkptr ) ;
}
}
else {
ret = Py_None ;
Py_INCREF ( ret ) ;
}
BLI_freelistN ( & newlb ) ;
}
2009-03-05 12:09:30 +00:00
else {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_AttributeError , " StructRNA - Attribute \" %.200s \" not found " , name ) ;
2009-03-05 12:09:30 +00:00
ret = NULL ;
2008-11-29 13:36:08 +00:00
}
2008-11-29 17:58:17 +00:00
return ret ;
}
2008-11-29 13:36:08 +00:00
2008-11-29 17:58:17 +00:00
//--------------- setattr-------------------------------------------
2008-12-01 16:59:18 +00:00
static int pyrna_struct_setattro ( BPy_StructRNA * self , PyObject * pyname , PyObject * value )
2008-11-29 17:58:17 +00:00
{
2008-12-01 16:59:18 +00:00
char * name = _PyUnicode_AsString ( pyname ) ;
2008-11-30 03:52:07 +00:00
PropertyRNA * prop = RNA_struct_find_property ( & self - > ptr , name ) ;
2008-11-29 17:58:17 +00:00
if ( prop = = NULL ) {
2009-03-16 15:54:43 +00:00
if ( ! BPy_StructRNA_CheckExact ( self ) & & PyObject_GenericSetAttr ( ( PyObject * ) self , pyname , value ) > = 0 ) {
return 0 ;
}
else {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_AttributeError , " StructRNA - Attribute \" %.200s \" not found " , name ) ;
2009-03-16 15:54:43 +00:00
return - 1 ;
}
2008-11-30 03:52:07 +00:00
}
2008-11-29 13:36:08 +00:00
2008-11-30 03:52:07 +00:00
if ( ! RNA_property_editable ( & self - > ptr , prop ) ) {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_AttributeError , " StructRNA - Attribute \" %.200s \" from \" %.200s \" is read-only " , RNA_property_identifier ( prop ) , RNA_struct_identifier ( self - > ptr . type ) ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
}
/* pyrna_py_to_prop sets its own exceptions */
2009-07-23 13:48:15 +00:00
return pyrna_py_to_prop ( & self - > ptr , prop , NULL , value , " StructRNA - Attribute (setattr) : " ) ;
2008-11-29 13:36:08 +00:00
}
2009-06-30 12:52:16 +00:00
static PyObject * pyrna_prop_keys ( BPy_PropertyRNA * self )
2008-11-29 13:36:08 +00:00
{
PyObject * ret ;
2009-04-19 13:37:59 +00:00
if ( RNA_property_type ( self - > prop ) ! = PROP_COLLECTION ) {
2008-11-29 13:36:08 +00:00
PyErr_SetString ( PyExc_TypeError , " keys() is only valid for collection types " ) ;
ret = NULL ;
} else {
PyObject * item ;
char name [ 256 ] , * nameptr ;
ret = PyList_New ( 0 ) ;
2009-06-24 21:27:10 +00:00
RNA_PROP_BEGIN ( & self - > ptr , itemptr , self - > prop ) {
nameptr = RNA_struct_name_get_alloc ( & itemptr , name , sizeof ( name ) ) ;
2009-06-24 14:03:55 +00:00
if ( nameptr ) {
2008-11-29 13:36:08 +00:00
/* add to python list */
item = PyUnicode_FromString ( nameptr ) ;
PyList_Append ( ret , item ) ;
Py_DECREF ( item ) ;
/* done */
2009-06-24 14:03:55 +00:00
if ( name ! = nameptr )
2008-11-29 13:36:08 +00:00
MEM_freeN ( nameptr ) ;
}
}
2009-06-24 21:27:10 +00:00
RNA_PROP_END ;
2008-11-29 13:36:08 +00:00
}
return ret ;
}
2009-06-30 12:52:16 +00:00
static PyObject * pyrna_prop_items ( BPy_PropertyRNA * self )
2008-11-29 13:36:08 +00:00
{
PyObject * ret ;
2009-04-19 13:37:59 +00:00
if ( RNA_property_type ( self - > prop ) ! = PROP_COLLECTION ) {
2008-12-01 22:20:18 +00:00
PyErr_SetString ( PyExc_TypeError , " items() is only valid for collection types " ) ;
2008-11-29 13:36:08 +00:00
ret = NULL ;
} else {
PyObject * item ;
char name [ 256 ] , * nameptr ;
2009-06-20 13:53:14 +00:00
int i = 0 ;
2008-11-29 13:36:08 +00:00
ret = PyList_New ( 0 ) ;
2009-06-24 21:27:10 +00:00
RNA_PROP_BEGIN ( & self - > ptr , itemptr , self - > prop ) {
if ( itemptr . data ) {
2008-11-29 13:36:08 +00:00
/* add to python list */
2009-06-20 13:53:14 +00:00
item = PyTuple_New ( 2 ) ;
2009-06-24 21:27:10 +00:00
nameptr = RNA_struct_name_get_alloc ( & itemptr , name , sizeof ( name ) ) ;
2009-06-24 14:03:55 +00:00
if ( nameptr ) {
2009-06-20 13:53:14 +00:00
PyTuple_SET_ITEM ( item , 0 , PyUnicode_FromString ( nameptr ) ) ;
2009-06-24 14:03:55 +00:00
if ( name ! = nameptr )
2009-06-20 13:53:14 +00:00
MEM_freeN ( nameptr ) ;
}
else {
PyTuple_SET_ITEM ( item , 0 , PyLong_FromSsize_t ( i ) ) ; /* a bit strange but better then returning an empty list */
}
2009-06-24 21:27:10 +00:00
PyTuple_SET_ITEM ( item , 1 , pyrna_struct_CreatePyObject ( & itemptr ) ) ;
2009-06-20 13:53:14 +00:00
2008-11-29 13:36:08 +00:00
PyList_Append ( ret , item ) ;
Py_DECREF ( item ) ;
2009-06-20 13:53:14 +00:00
i + + ;
2008-11-29 13:36:08 +00:00
}
}
2009-06-24 21:27:10 +00:00
RNA_PROP_END ;
2008-11-29 13:36:08 +00:00
}
return ret ;
}
2009-06-30 12:52:16 +00:00
static PyObject * pyrna_prop_values ( BPy_PropertyRNA * self )
2008-11-29 13:36:08 +00:00
{
PyObject * ret ;
2009-06-20 13:53:14 +00:00
2009-04-19 13:37:59 +00:00
if ( RNA_property_type ( self - > prop ) ! = PROP_COLLECTION ) {
2008-12-02 15:27:10 +00:00
PyErr_SetString ( PyExc_TypeError , " values() is only valid for collection types " ) ;
2008-11-29 13:36:08 +00:00
ret = NULL ;
} else {
PyObject * item ;
ret = PyList_New ( 0 ) ;
2009-06-24 21:27:10 +00:00
RNA_PROP_BEGIN ( & self - > ptr , itemptr , self - > prop ) {
item = pyrna_struct_CreatePyObject ( & itemptr ) ;
2009-06-20 13:53:14 +00:00
PyList_Append ( ret , item ) ;
Py_DECREF ( item ) ;
2008-11-29 13:36:08 +00:00
}
2009-06-24 21:27:10 +00:00
RNA_PROP_END ;
2008-11-29 13:36:08 +00:00
}
return ret ;
}
2009-07-09 08:06:26 +00:00
static PyObject * pyrna_prop_get ( BPy_PropertyRNA * self , PyObject * args )
{
PointerRNA newptr ;
char * key ;
PyObject * def = Py_None ;
if ( ! PyArg_ParseTuple ( args , " s|O:get " , & key , & def ) )
return NULL ;
if ( RNA_property_collection_lookup_string ( & self - > ptr , self - > prop , key , & newptr ) )
return pyrna_struct_CreatePyObject ( & newptr ) ;
Py_INCREF ( def ) ;
return def ;
}
2009-08-10 00:07:34 +00:00
2009-06-30 12:52:16 +00:00
static void foreach_attr_type ( BPy_PropertyRNA * self , char * attr ,
/* values to assign */
RawPropertyType * raw_type , int * attr_tot , int * attr_signed )
{
PropertyRNA * prop ;
* raw_type = - 1 ;
* attr_tot = 0 ;
2009-07-26 18:18:14 +00:00
* attr_signed = FALSE ;
2009-06-30 12:52:16 +00:00
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 ) ;
2009-07-26 18:18:14 +00:00
* attr_signed = ( RNA_property_subtype ( prop ) = = PROP_UNSIGNED ) ? FALSE : TRUE ;
2009-06-30 12:52:16 +00:00
break ;
}
RNA_PROP_END ;
}
/* pyrna_prop_foreach_get/set both use this */
static int foreach_parse_args (
BPy_PropertyRNA * self , PyObject * args ,
/*values to assign */
char * * attr , PyObject * * seq , int * tot , int * size , RawPropertyType * raw_type , int * attr_tot , int * attr_signed )
{
2009-07-01 13:31:36 +00:00
#if 0
2009-06-30 12:52:16 +00:00
int array_tot ;
int target_tot ;
2009-07-01 13:31:36 +00:00
# endif
2009-06-30 12:52:16 +00:00
2009-07-26 18:18:14 +00:00
* size = * raw_type = * attr_tot = * attr_signed = FALSE ;
2009-06-30 12:52:16 +00:00
if ( ! PyArg_ParseTuple ( args , " sO " , attr , seq ) | | ( ! PySequence_Check ( * seq ) & & PyObject_CheckBuffer ( * seq ) ) ) {
PyErr_SetString ( PyExc_TypeError , " foreach_get(attr, sequence) expects a string and a sequence " ) ;
return - 1 ;
}
* tot = PySequence_Length ( * seq ) ; // TODO - buffer may not be a sequence! array.array() is tho.
if ( * tot > 0 ) {
foreach_attr_type ( self , * attr , raw_type , attr_tot , attr_signed ) ;
* size = RNA_raw_type_sizeof ( * raw_type ) ;
#if 0 // works fine but not strictly needed, we could allow RNA_property_collection_raw_* to do the checks
if ( ( * attr_tot ) < 1 )
* attr_tot = 1 ;
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 ) ;
target_tot = array_tot * ( * attr_tot ) ;
/* rna_access.c - rna_raw_access(...) uses this same method */
if ( target_tot ! = ( * tot ) ) {
PyErr_Format ( PyExc_TypeError , " foreach_get(attr, sequence) sequence length mismatch given %d, needed %d " , * tot , target_tot ) ;
return - 1 ;
}
# endif
}
return 0 ;
}
static int foreach_compat_buffer ( RawPropertyType raw_type , int attr_signed , const char * format )
{
char f = format ? * format : ' B ' ; /* B is assumed when not set */
switch ( raw_type ) {
case PROP_RAW_CHAR :
if ( attr_signed ) return ( f = = ' b ' ) ? 1 : 0 ;
else return ( f = = ' B ' ) ? 1 : 0 ;
case PROP_RAW_SHORT :
if ( attr_signed ) return ( f = = ' h ' ) ? 1 : 0 ;
else return ( f = = ' H ' ) ? 1 : 0 ;
case PROP_RAW_INT :
if ( attr_signed ) return ( f = = ' i ' ) ? 1 : 0 ;
else return ( f = = ' I ' ) ? 1 : 0 ;
case PROP_RAW_FLOAT :
return ( f = = ' f ' ) ? 1 : 0 ;
case PROP_RAW_DOUBLE :
return ( f = = ' d ' ) ? 1 : 0 ;
}
return 0 ;
}
static PyObject * foreach_getset ( BPy_PropertyRNA * self , PyObject * args , int set )
{
PyObject * item ;
int i = 0 , ok , buffer_is_compat ;
void * array = NULL ;
/* get/set both take the same args currently */
char * attr ;
PyObject * seq ;
int tot , size , attr_tot , attr_signed ;
RawPropertyType raw_type ;
if ( foreach_parse_args ( self , args , & attr , & seq , & tot , & size , & raw_type , & attr_tot , & attr_signed ) < 0 )
return NULL ;
if ( tot = = 0 )
Py_RETURN_NONE ;
if ( set ) { /* get the array from python */
2009-07-26 18:18:14 +00:00
buffer_is_compat = FALSE ;
2009-06-30 12:52:16 +00:00
if ( PyObject_CheckBuffer ( seq ) ) {
Py_buffer buf ;
PyObject_GetBuffer ( seq , & buf , PyBUF_SIMPLE | PyBUF_FORMAT ) ;
2009-07-01 13:31:36 +00:00
/* check if the buffer matches */
2009-06-30 12:52:16 +00:00
buffer_is_compat = foreach_compat_buffer ( raw_type , attr_signed , buf . format ) ;
if ( buffer_is_compat ) {
ok = RNA_property_collection_raw_set ( NULL , & self - > ptr , self - > prop , attr , buf . buf , raw_type , tot ) ;
}
PyBuffer_Release ( & buf ) ;
}
/* could not use the buffer, fallback to sequence */
if ( ! buffer_is_compat ) {
array = PyMem_Malloc ( size * tot ) ;
for ( ; i < tot ; i + + ) {
item = PySequence_GetItem ( seq , i ) ;
switch ( raw_type ) {
case PROP_RAW_CHAR :
( ( char * ) array ) [ i ] = ( char ) PyLong_AsSsize_t ( item ) ;
break ;
case PROP_RAW_SHORT :
( ( short * ) array ) [ i ] = ( short ) PyLong_AsSsize_t ( item ) ;
break ;
case PROP_RAW_INT :
( ( int * ) array ) [ i ] = ( int ) PyLong_AsSsize_t ( item ) ;
break ;
case PROP_RAW_FLOAT :
( ( float * ) array ) [ i ] = ( float ) PyFloat_AsDouble ( item ) ;
break ;
case PROP_RAW_DOUBLE :
( ( double * ) array ) [ i ] = ( double ) PyFloat_AsDouble ( item ) ;
break ;
}
Py_DECREF ( item ) ;
}
ok = RNA_property_collection_raw_set ( NULL , & self - > ptr , self - > prop , attr , array , raw_type , tot ) ;
}
}
else {
2009-07-26 18:18:14 +00:00
buffer_is_compat = FALSE ;
2009-06-30 12:52:16 +00:00
if ( PyObject_CheckBuffer ( seq ) ) {
Py_buffer buf ;
PyObject_GetBuffer ( seq , & buf , PyBUF_SIMPLE | PyBUF_FORMAT ) ;
/* check if the buffer matches, TODO - signed/unsigned types */
buffer_is_compat = foreach_compat_buffer ( raw_type , attr_signed , buf . format ) ;
if ( buffer_is_compat ) {
ok = RNA_property_collection_raw_get ( NULL , & self - > ptr , self - > prop , attr , buf . buf , raw_type , tot ) ;
}
PyBuffer_Release ( & buf ) ;
}
/* could not use the buffer, fallback to sequence */
if ( ! buffer_is_compat ) {
array = PyMem_Malloc ( size * tot ) ;
ok = RNA_property_collection_raw_get ( NULL , & self - > ptr , self - > prop , attr , array , raw_type , tot ) ;
if ( ! ok ) i = tot ; /* skip the loop */
for ( ; i < tot ; i + + ) {
switch ( raw_type ) {
case PROP_RAW_CHAR :
item = PyLong_FromSsize_t ( ( Py_ssize_t ) ( ( char * ) array ) [ i ] ) ;
break ;
case PROP_RAW_SHORT :
item = PyLong_FromSsize_t ( ( Py_ssize_t ) ( ( short * ) array ) [ i ] ) ;
break ;
case PROP_RAW_INT :
item = PyLong_FromSsize_t ( ( Py_ssize_t ) ( ( int * ) array ) [ i ] ) ;
break ;
case PROP_RAW_FLOAT :
item = PyFloat_FromDouble ( ( double ) ( ( float * ) array ) [ i ] ) ;
break ;
case PROP_RAW_DOUBLE :
item = PyFloat_FromDouble ( ( double ) ( ( double * ) array ) [ i ] ) ;
break ;
}
PySequence_SetItem ( seq , i , item ) ;
Py_DECREF ( item ) ;
}
}
}
if ( PyErr_Occurred ( ) ) {
/* Maybe we could make our own error */
PyErr_Print ( ) ;
PyErr_SetString ( PyExc_SystemError , " could not access the py sequence " ) ;
return NULL ;
}
if ( ! ok ) {
PyErr_SetString ( PyExc_SystemError , " internal error setting the array " ) ;
return NULL ;
}
if ( array )
PyMem_Free ( array ) ;
Py_RETURN_NONE ;
}
static PyObject * pyrna_prop_foreach_get ( BPy_PropertyRNA * self , PyObject * args )
{
return foreach_getset ( self , args , 0 ) ;
}
static PyObject * pyrna_prop_foreach_set ( BPy_PropertyRNA * self , PyObject * args )
{
return foreach_getset ( self , args , 1 ) ;
}
2008-12-02 15:27:10 +00:00
/* 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 */
PyObject * pyrna_prop_iter ( BPy_PropertyRNA * self )
{
/* Try get values from a collection */
PyObject * ret = pyrna_prop_values ( self ) ;
if ( ret = = NULL ) {
/* collection did not work, try array */
2009-04-19 13:37:59 +00:00
int len = RNA_property_array_length ( self - > prop ) ;
2008-12-02 15:27:10 +00:00
if ( len ) {
int i ;
PyErr_Clear ( ) ;
ret = PyList_New ( len ) ;
for ( i = 0 ; i < len ; i + + ) {
PyList_SET_ITEM ( ret , i , pyrna_prop_to_py_index ( & self - > ptr , self - > prop , i ) ) ;
}
}
}
if ( ret ) {
/* we know this is a list so no need to PyIter_Check */
PyObject * iter = PyObject_GetIter ( ret ) ;
Py_DECREF ( ret ) ;
return iter ;
}
PyErr_SetString ( PyExc_TypeError , " this BPy_PropertyRNA object is not iterable " ) ;
return NULL ;
}
2009-03-11 17:28:37 +00:00
static struct PyMethodDef pyrna_struct_methods [ ] = {
2009-07-08 09:23:49 +00:00
/* maybe this become and ID function */
{ " keyframe_insert " , ( PyCFunction ) pyrna_struct_keyframe_insert , METH_VARARGS , NULL } ,
2009-06-30 12:52:16 +00:00
{ " __dir__ " , ( PyCFunction ) pyrna_struct_dir , METH_NOARGS , NULL } ,
2008-12-29 12:04:25 +00:00
{ NULL , NULL , 0 , NULL }
2009-03-11 17:28:37 +00:00
} ;
2008-11-29 13:36:08 +00:00
static struct PyMethodDef pyrna_prop_methods [ ] = {
2009-06-30 12:52:16 +00:00
{ " keys " , ( PyCFunction ) pyrna_prop_keys , METH_NOARGS , NULL } ,
{ " items " , ( PyCFunction ) pyrna_prop_items , METH_NOARGS , NULL } ,
{ " values " , ( PyCFunction ) pyrna_prop_values , METH_NOARGS , NULL } ,
2009-07-09 08:06:26 +00:00
{ " get " , ( PyCFunction ) pyrna_prop_get , METH_VARARGS , NULL } ,
2009-06-30 12:52:16 +00:00
/* array accessor function */
{ " foreach_get " , ( PyCFunction ) pyrna_prop_foreach_get , METH_VARARGS , NULL } ,
{ " foreach_set " , ( PyCFunction ) pyrna_prop_foreach_set , METH_VARARGS , NULL } ,
2009-08-10 00:07:34 +00:00
2008-11-29 13:36:08 +00:00
{ NULL , NULL , 0 , NULL }
} ;
2008-12-01 16:59:18 +00:00
/* only needed for subtyping, so a new class gets a valid BPy_StructRNA
* todo - also accept useful args */
static PyObject * pyrna_struct_new ( PyTypeObject * type , PyObject * args , PyObject * kwds ) {
BPy_StructRNA * base = NULL ;
if ( ! PyArg_ParseTuple ( args , " O!:Base BPy_StructRNA " , & pyrna_struct_Type , & base ) )
return NULL ;
if ( type = = & pyrna_struct_Type ) {
return pyrna_struct_CreatePyObject ( & base - > ptr ) ;
} else {
BPy_StructRNA * ret = ( BPy_StructRNA * ) type - > tp_alloc ( type , 0 ) ;
ret - > ptr = base - > ptr ;
return ( PyObject * ) ret ;
}
}
/* only needed for subtyping, so a new class gets a valid BPy_StructRNA
* todo - also accept useful args */
static PyObject * pyrna_prop_new ( PyTypeObject * type , PyObject * args , PyObject * kwds ) {
BPy_PropertyRNA * base = NULL ;
if ( ! PyArg_ParseTuple ( args , " O!:Base BPy_PropertyRNA " , & pyrna_prop_Type , & base ) )
return NULL ;
if ( type = = & pyrna_prop_Type ) {
return pyrna_prop_CreatePyObject ( & base - > ptr , base - > prop ) ;
} else {
BPy_PropertyRNA * ret = ( BPy_PropertyRNA * ) type - > tp_alloc ( type , 0 ) ;
ret - > ptr = base - > ptr ;
ret - > prop = base - > prop ;
return ( PyObject * ) ret ;
}
}
2009-04-07 00:49:39 +00:00
PyObject * pyrna_param_to_py ( PointerRNA * ptr , PropertyRNA * prop , void * data )
{
PyObject * ret ;
2009-04-19 13:37:59 +00:00
int type = RNA_property_type ( prop ) ;
int len = RNA_property_array_length ( prop ) ;
2009-04-19 20:09:31 +00:00
2009-04-07 00:49:39 +00:00
int a ;
if ( len > 0 ) {
/* resolve the array from a new pytype */
ret = PyTuple_New ( len ) ;
switch ( type ) {
case PROP_BOOLEAN :
for ( a = 0 ; a < len ; a + + )
PyTuple_SET_ITEM ( ret , a , PyBool_FromLong ( ( ( int * ) data ) [ a ] ) ) ;
break ;
case PROP_INT :
for ( a = 0 ; a < len ; a + + )
PyTuple_SET_ITEM ( ret , a , PyLong_FromSsize_t ( ( Py_ssize_t ) ( ( int * ) data ) [ a ] ) ) ;
break ;
case PROP_FLOAT :
for ( a = 0 ; a < len ; a + + )
PyTuple_SET_ITEM ( ret , a , PyFloat_FromDouble ( ( ( float * ) data ) [ a ] ) ) ;
break ;
default :
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " RNA Error: unknown array type \" %d \" (pyrna_param_to_py) " , type ) ;
2009-04-07 00:49:39 +00:00
ret = NULL ;
break ;
}
}
else {
/* see if we can coorce into a python type - PropertyType */
switch ( type ) {
case PROP_BOOLEAN :
ret = PyBool_FromLong ( * ( int * ) data ) ;
break ;
case PROP_INT :
ret = PyLong_FromSsize_t ( ( Py_ssize_t ) * ( int * ) data ) ;
break ;
case PROP_FLOAT :
ret = PyFloat_FromDouble ( * ( float * ) data ) ;
break ;
case PROP_STRING :
{
ret = PyUnicode_FromString ( * ( char * * ) data ) ;
break ;
}
case PROP_ENUM :
{
const char * identifier ;
int val = * ( int * ) data ;
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
if ( RNA_property_enum_identifier ( BPy_GetContext ( ) , ptr , prop , val , & identifier ) ) {
2009-04-07 00:49:39 +00:00
ret = PyUnicode_FromString ( identifier ) ;
} else {
2009-07-13 19:33:59 +00:00
/* prefer not fail silently incase of api errors, maybe disable it later */
char error_str [ 128 ] ;
sprintf ( error_str , " RNA Warning: Current value \" %d \" matches no enum " , val ) ;
PyErr_Warn ( PyExc_RuntimeWarning , error_str ) ;
ret = PyUnicode_FromString ( " " ) ;
2009-07-03 19:56:19 +00:00
/*PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
ret = NULL ; */
2009-04-07 00:49:39 +00:00
}
break ;
}
case PROP_POINTER :
{
PointerRNA newptr ;
2009-06-07 13:09:18 +00:00
StructRNA * type = RNA_property_pointer_type ( ptr , prop ) ;
2009-06-16 00:52:21 +00:00
int flag = RNA_property_flag ( prop ) ;
2009-04-07 00:49:39 +00:00
2009-06-16 00:52:21 +00:00
if ( flag & PROP_RNAPTR ) {
2009-04-07 00:49:39 +00:00
/* in this case we get the full ptr */
newptr = * ( PointerRNA * ) data ;
}
else {
2009-07-28 01:06:56 +00:00
if ( RNA_struct_is_ID ( type ) ) {
RNA_id_pointer_create ( * ( void * * ) data , & newptr ) ;
} else {
/* XXX this is missing the ID part! */
RNA_pointer_create ( NULL , type , * ( void * * ) data , & newptr ) ;
}
2009-04-07 00:49:39 +00:00
}
if ( newptr . data ) {
ret = pyrna_struct_CreatePyObject ( & newptr ) ;
} else {
ret = Py_None ;
Py_INCREF ( ret ) ;
}
break ;
}
case PROP_COLLECTION :
2009-06-27 01:10:39 +00:00
{
ListBase * lb = ( ListBase * ) data ;
CollectionPointerLink * link ;
PyObject * linkptr ;
ret = PyList_New ( 0 ) ;
for ( link = lb - > first ; link ; link = link - > next ) {
linkptr = pyrna_struct_CreatePyObject ( & link - > ptr ) ;
PyList_Append ( ret , linkptr ) ;
Py_DECREF ( linkptr ) ;
}
2009-04-07 00:49:39 +00:00
break ;
2009-06-27 01:10:39 +00:00
}
2009-04-07 00:49:39 +00:00
default :
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " RNA Error: unknown type \" %d \" (pyrna_param_to_py) " , type ) ;
2009-04-07 00:49:39 +00:00
ret = NULL ;
break ;
}
}
return ret ;
}
2009-04-09 13:20:48 +00:00
static PyObject * pyrna_func_call ( PyObject * self , PyObject * args , PyObject * kw )
{
PointerRNA * self_ptr = & ( ( ( BPy_StructRNA * ) PyTuple_GET_ITEM ( self , 0 ) ) - > ptr ) ;
FunctionRNA * self_func = PyCObject_AsVoidPtr ( PyTuple_GET_ITEM ( self , 1 ) ) ;
2009-04-07 00:49:39 +00:00
PointerRNA funcptr ;
2009-07-17 02:31:28 +00:00
ParameterList parms ;
2009-04-07 00:49:39 +00:00
ParameterIterator iter ;
PropertyRNA * pret , * parm ;
PyObject * ret , * item ;
2009-07-23 13:48:15 +00:00
int i , args_len , parms_len , flag , err = 0 , kw_tot = 0 , kw_arg ;
2009-07-17 02:31:28 +00:00
const char * parm_id ;
2009-04-07 00:49:39 +00:00
void * retdata = NULL ;
2009-07-17 12:26:40 +00:00
/* Should never happen but it does in rare cases */
if ( self_ptr = = NULL ) {
PyErr_SetString ( PyExc_RuntimeError , " rna functions internal rna pointer is NULL, this is a bug. aborting " ) ;
return NULL ;
}
if ( self_func = = NULL ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_RuntimeError , " %.200s.<unknown>(): rna function internal function is NULL, this is a bug. aborting " , RNA_struct_identifier ( self_ptr - > type ) ) ;
2009-07-17 12:26:40 +00:00
return NULL ;
}
2009-04-07 00:49:39 +00:00
/* setup */
2009-04-09 13:20:48 +00:00
RNA_pointer_create ( NULL , & RNA_Function , self_func , & funcptr ) ;
2009-04-07 00:49:39 +00:00
2009-04-19 13:37:59 +00:00
pret = RNA_function_return ( self_func ) ;
2009-07-17 02:31:28 +00:00
args_len = PyTuple_GET_SIZE ( args ) ;
2009-04-07 00:49:39 +00:00
2009-07-17 02:31:28 +00:00
RNA_parameter_list_create ( & parms , self_ptr , self_func ) ;
RNA_parameter_list_begin ( & parms , & iter ) ;
parms_len = RNA_parameter_list_size ( & parms ) ;
if ( args_len + ( kw ? PyDict_Size ( kw ) : 0 ) > parms_len ) {
PyErr_Format ( PyExc_TypeError , " %.200s.%.200s(): takes at most %d arguments, got %d " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , parms_len , args_len ) ;
err = - 1 ;
}
2009-04-07 00:49:39 +00:00
/* parse function parameters */
2009-07-17 02:31:28 +00:00
for ( i = 0 ; iter . valid & & err = = 0 ; RNA_parameter_list_next ( & iter ) ) {
2009-04-07 00:49:39 +00:00
parm = iter . parm ;
if ( parm = = pret ) {
retdata = iter . data ;
continue ;
}
2009-07-17 02:31:28 +00:00
parm_id = RNA_property_identifier ( parm ) ;
2009-04-19 13:37:59 +00:00
flag = RNA_property_flag ( parm ) ;
2009-04-07 00:49:39 +00:00
item = NULL ;
2009-07-17 02:31:28 +00:00
if ( ( i < args_len ) & & ( flag & PROP_REQUIRED ) ) {
2009-04-07 00:49:39 +00:00
item = PyTuple_GET_ITEM ( args , i ) ;
2009-04-11 01:45:05 +00:00
i + + ;
2009-07-23 13:48:15 +00:00
2009-07-26 18:18:14 +00:00
kw_arg = FALSE ;
2009-04-11 01:45:05 +00:00
}
2009-07-17 02:31:28 +00:00
else if ( kw ! = NULL ) {
item = PyDict_GetItemString ( kw , parm_id ) ; /* borrow ref */
if ( item )
kw_tot + + ; /* make sure invalid keywords are not given */
2009-07-23 13:48:15 +00:00
2009-07-26 18:18:14 +00:00
kw_arg = TRUE ;
2009-07-17 02:31:28 +00:00
}
2009-04-07 00:49:39 +00:00
if ( item = = NULL ) {
2009-04-11 01:45:05 +00:00
if ( flag & PROP_REQUIRED ) {
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s.%.200s(): required parameter \" %.200s \" not specified " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , parm_id ) ;
2009-04-11 01:45:05 +00:00
err = - 1 ;
break ;
}
2009-07-17 02:31:28 +00:00
else /* PyDict_GetItemString wont raise an error */
2009-04-11 01:45:05 +00:00
continue ;
2009-04-07 00:49:39 +00:00
}
2009-07-23 13:48:15 +00:00
err = pyrna_py_to_prop ( & funcptr , parm , iter . data , item , " " ) ;
if ( err ! = 0 ) {
/* the error generated isnt that useful, so generate it again with a useful prefix
* could also write a function to prepend to error messages */
char error_prefix [ 512 ] ;
PyErr_Clear ( ) ; /* re-raise */
2009-07-26 18:18:14 +00:00
if ( kw_arg = = TRUE )
2009-07-23 13:48:15 +00:00
snprintf ( error_prefix , sizeof ( error_prefix ) , " %s.%s(): error with keyword argument \" %s \" - " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , parm_id ) ;
else
snprintf ( error_prefix , sizeof ( error_prefix ) , " %s.%s(): error with argument %d, \" %s \" - " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , i , parm_id ) ;
pyrna_py_to_prop ( & funcptr , parm , iter . data , item , error_prefix ) ;
2009-04-07 00:49:39 +00:00
break ;
2009-07-23 13:48:15 +00:00
}
2009-04-07 00:49:39 +00:00
}
2009-07-17 02:31:28 +00:00
/* Check if we gave args that dont exist in the function
* printing the error is slow but it should only happen when developing .
* the if below is quick , checking if it passed less keyword args then we gave */
if ( kw & & ( PyDict_Size ( kw ) > kw_tot ) ) {
PyObject * key , * value ;
Py_ssize_t pos = 0 ;
DynStr * bad_args = BLI_dynstr_new ( ) ;
DynStr * good_args = BLI_dynstr_new ( ) ;
char * arg_name , * bad_args_str , * good_args_str ;
2009-07-26 18:18:14 +00:00
int found = FALSE , first = TRUE ;
2009-07-17 02:31:28 +00:00
while ( PyDict_Next ( kw , & pos , & key , & value ) ) {
arg_name = _PyUnicode_AsString ( key ) ;
2009-07-26 18:18:14 +00:00
found = FALSE ;
2009-07-17 02:31:28 +00:00
if ( arg_name = = NULL ) { /* unlikely the argname is not a string but ignore if it is*/
PyErr_Clear ( ) ;
}
else {
/* Search for arg_name */
RNA_parameter_list_begin ( & parms , & iter ) ;
for ( ; iter . valid ; RNA_parameter_list_next ( & iter ) ) {
parm = iter . parm ;
if ( strcmp ( arg_name , RNA_property_identifier ( parm ) ) = = 0 ) {
2009-07-26 18:18:14 +00:00
found = TRUE ;
2009-07-17 02:31:28 +00:00
break ;
}
}
RNA_parameter_list_end ( & iter ) ;
2009-07-26 18:18:14 +00:00
if ( found = = FALSE ) {
2009-07-17 02:31:28 +00:00
BLI_dynstr_appendf ( bad_args , first ? " %s " : " , %s " , arg_name ) ;
2009-07-26 18:18:14 +00:00
first = FALSE ;
2009-07-17 02:31:28 +00:00
}
}
}
/* list good args */
2009-07-26 18:18:14 +00:00
first = TRUE ;
2009-07-17 02:31:28 +00:00
RNA_parameter_list_begin ( & parms , & iter ) ;
for ( ; iter . valid ; RNA_parameter_list_next ( & iter ) ) {
parm = iter . parm ;
BLI_dynstr_appendf ( good_args , first ? " %s " : " , %s " , RNA_property_identifier ( parm ) ) ;
2009-07-26 18:18:14 +00:00
first = FALSE ;
2009-07-17 02:31:28 +00:00
}
RNA_parameter_list_end ( & iter ) ;
bad_args_str = BLI_dynstr_get_cstring ( bad_args ) ;
good_args_str = BLI_dynstr_get_cstring ( good_args ) ;
PyErr_Format ( PyExc_TypeError , " %.200s.%.200s(): was called with invalid keyword arguments(s) (%s), expected (%s) " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , bad_args_str , good_args_str ) ;
BLI_dynstr_free ( bad_args ) ;
BLI_dynstr_free ( good_args ) ;
MEM_freeN ( bad_args_str ) ;
MEM_freeN ( good_args_str ) ;
err = - 1 ;
}
2009-04-07 00:49:39 +00:00
ret = NULL ;
if ( err = = 0 ) {
/* call function */
2009-06-18 19:48:55 +00:00
ReportList reports ;
bContext * C = BPy_GetContext ( ) ;
BKE_reports_init ( & reports , RPT_STORE ) ;
2009-07-17 02:31:28 +00:00
RNA_function_call ( C , & reports , self_ptr , self_func , & parms ) ;
2009-06-18 19:48:55 +00:00
err = ( BPy_reports_to_error ( & reports ) ) ? - 1 : 0 ;
BKE_reports_clear ( & reports ) ;
2009-04-07 00:49:39 +00:00
/* return value */
2009-07-17 02:31:28 +00:00
if ( err = = 0 ) {
if ( pret ) {
2009-06-18 19:48:55 +00:00
ret = pyrna_param_to_py ( & funcptr , pret , retdata ) ;
2009-07-17 02:31:28 +00:00
/* possible there is an error in conversion */
if ( ret = = NULL )
err = - 1 ;
}
}
2009-04-07 00:49:39 +00:00
}
/* cleanup */
RNA_parameter_list_end ( & iter ) ;
2009-07-17 02:31:28 +00:00
RNA_parameter_list_free ( & parms ) ;
2009-04-07 00:49:39 +00:00
if ( ret )
return ret ;
if ( err = = - 1 )
return NULL ;
Py_RETURN_NONE ;
}
2008-11-29 13:36:08 +00:00
/*-----------------------BPy_StructRNA method def------------------------------*/
PyTypeObject pyrna_struct_Type = {
2009-01-29 09:38:52 +00:00
PyVarObject_HEAD_INIT ( NULL , 0 )
2008-11-29 13:36:08 +00:00
" StructRNA " , /* tp_name */
sizeof ( BPy_StructRNA ) , /* tp_basicsize */
0 , /* tp_itemsize */
/* methods */
2008-12-29 03:24:13 +00:00
( destructor ) pyrna_struct_dealloc , /* tp_dealloc */
2008-11-29 13:36:08 +00:00
NULL , /* printfunc tp_print; */
2008-12-01 16:59:18 +00:00
NULL , /* getattrfunc tp_getattr; */
NULL , /* setattrfunc tp_setattr; */
2009-02-26 05:50:19 +00:00
NULL , /* tp_compare */ /* DEPRECATED in python 3.0! */
2008-11-29 13:36:08 +00:00
( reprfunc ) pyrna_struct_repr , /* tp_repr */
/* Method suites for standard classes */
NULL , /* PyNumberMethods *tp_as_number; */
NULL , /* PySequenceMethods *tp_as_sequence; */
NULL , /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
2008-12-02 14:36:35 +00:00
( hashfunc ) pyrna_struct_hash , /* hashfunc tp_hash; */
2008-12-01 16:59:18 +00:00
NULL , /* ternaryfunc tp_call; */
2008-11-29 13:36:08 +00:00
NULL , /* reprfunc tp_str; */
2008-12-01 16:59:18 +00:00
( getattrofunc ) pyrna_struct_getattro , /* getattrofunc tp_getattro; */
( setattrofunc ) pyrna_struct_setattro , /* setattrofunc tp_setattro; */
2008-11-29 13:36:08 +00:00
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
2008-12-01 16:59:18 +00:00
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* long tp_flags; */
2008-11-29 13:36:08 +00:00
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
2009-01-29 09:38:52 +00:00
( richcmpfunc ) pyrna_struct_richcmp , /* richcmpfunc tp_richcompare; */
2008-11-29 13:36:08 +00:00
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
NULL , /* getiterfunc tp_iter; */
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
2009-03-11 17:28:37 +00:00
pyrna_struct_methods , /* struct PyMethodDef *tp_methods; */
2008-11-29 13:36:08 +00:00
NULL , /* struct PyMemberDef *tp_members; */
NULL , /* struct PyGetSetDef *tp_getset; */
NULL , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
2008-12-01 16:59:18 +00:00
pyrna_struct_new , /* newfunc tp_new; */
2008-11-29 13:36:08 +00:00
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;
/*-----------------------BPy_PropertyRNA method def------------------------------*/
PyTypeObject pyrna_prop_Type = {
2009-01-29 09:38:52 +00:00
PyVarObject_HEAD_INIT ( NULL , 0 )
2008-11-29 13:36:08 +00:00
" PropertyRNA " , /* tp_name */
sizeof ( BPy_PropertyRNA ) , /* tp_basicsize */
0 , /* tp_itemsize */
/* methods */
NULL , /* tp_dealloc */
NULL , /* printfunc tp_print; */
2008-11-30 14:00:14 +00:00
NULL , /* getattrfunc tp_getattr; */
2008-11-29 13:36:08 +00:00
NULL , /* setattrfunc tp_setattr; */
2009-02-26 05:50:19 +00:00
NULL , /* tp_compare */ /* DEPRECATED in python 3.0! */
2008-11-29 13:36:08 +00:00
( reprfunc ) pyrna_prop_repr , /* tp_repr */
/* Method suites for standard classes */
NULL , /* PyNumberMethods *tp_as_number; */
2009-06-13 08:04:43 +00:00
& pyrna_prop_as_sequence , /* PySequenceMethods *tp_as_sequence; */
2008-11-29 13:36:08 +00:00
& pyrna_prop_as_mapping , /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL , /* hashfunc tp_hash; */
NULL , /* ternaryfunc tp_call; */
NULL , /* reprfunc tp_str; */
2008-12-02 09:35:29 +00:00
NULL , /*PyObject_GenericGetAttr - MINGW Complains, assign later */ /* getattrofunc tp_getattro; */ /* will only use these if this is a subtype of a py class */
NULL , /*PyObject_GenericSetAttr - MINGW Complains, assign later */ /* setattrofunc tp_setattro; */
2008-11-29 13:36:08 +00:00
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
2008-12-01 16:59:18 +00:00
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* long tp_flags; */
2008-11-29 13:36:08 +00:00
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
2009-01-29 09:38:52 +00:00
( richcmpfunc ) pyrna_prop_richcmp , /* richcmpfunc tp_richcompare; */
2008-11-29 13:36:08 +00:00
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
2008-12-02 15:27:10 +00:00
( getiterfunc ) pyrna_prop_iter , /* getiterfunc tp_iter; */
2008-11-29 13:36:08 +00:00
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
pyrna_prop_methods , /* struct PyMethodDef *tp_methods; */
NULL , /* struct PyMemberDef *tp_members; */
NULL , /* struct PyGetSetDef *tp_getset; */
NULL , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
2008-12-01 16:59:18 +00:00
pyrna_prop_new , /* newfunc tp_new; */
2008-11-29 13:36:08 +00:00
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;
2009-04-19 13:37:59 +00:00
static void pyrna_subtype_set_rna ( PyObject * newclass , StructRNA * srna )
{
PointerRNA ptr ;
PyObject * item ;
2009-05-26 06:29:15 +00:00
Py_INCREF ( newclass ) ;
2009-05-28 02:03:48 +00:00
2009-05-26 06:29:15 +00:00
if ( RNA_struct_py_type_get ( srna ) )
2009-05-28 02:03:48 +00:00
PyObSpit ( " RNA WAS SET - " , RNA_struct_py_type_get ( srna ) ) ;
2009-05-28 10:31:56 +00:00
Py_XDECREF ( ( ( PyObject * ) RNA_struct_py_type_get ( srna ) ) ) ;
2009-05-26 06:29:15 +00:00
2009-04-19 13:37:59 +00:00
RNA_struct_py_type_set ( srna , ( void * ) newclass ) ; /* Store for later use */
/* Not 100% needed but useful,
* having an instance within a type looks wrong however this instance IS an rna type */
RNA_pointer_create ( NULL , & RNA_Struct , srna , & ptr ) ;
item = pyrna_struct_CreatePyObject ( & ptr ) ;
PyDict_SetItemString ( ( ( PyTypeObject * ) newclass ) - > tp_dict , " __rna__ " , item ) ;
Py_DECREF ( item ) ;
/* done with rna instance */
}
2009-04-07 00:49:39 +00:00
2009-07-21 20:05:16 +00:00
static struct PyMethodDef pyrna_struct_subtype_methods [ ] = {
{ " FloatProperty " , ( PyCFunction ) BPy_FloatProperty , METH_VARARGS | METH_KEYWORDS , " " } ,
{ " IntProperty " , ( PyCFunction ) BPy_IntProperty , METH_VARARGS | METH_KEYWORDS , " " } ,
{ " BoolProperty " , ( PyCFunction ) BPy_BoolProperty , METH_VARARGS | METH_KEYWORDS , " " } ,
{ " StringProperty " , ( PyCFunction ) BPy_StringProperty , METH_VARARGS | METH_KEYWORDS , " " } ,
{ NULL , NULL , 0 , NULL }
} ;
2009-07-10 18:09:53 +00:00
PyObject * pyrna_srna_Subtype ( StructRNA * srna )
2009-03-13 07:50:07 +00:00
{
PyObject * newclass = NULL ;
2009-07-10 04:25:49 +00:00
if ( srna = = NULL ) {
2009-03-13 07:50:07 +00:00
newclass = NULL ; /* Nothing to do */
2009-07-10 04:25:49 +00:00
} else if ( ( newclass = RNA_struct_py_type_get ( srna ) ) ) {
2009-03-21 06:55:30 +00:00
Py_INCREF ( newclass ) ;
2009-07-10 04:25:49 +00:00
} else {
2009-03-13 07:50:07 +00:00
/* subclass equivelents
- class myClass ( myBase ) :
some = ' value ' # or . . .
2009-07-10 04:25:49 +00:00
- myClass = type ( name = ' myClass ' , bases = ( myBase , ) , dict = { ' __module__ ' : ' bpy . types ' } )
2009-03-13 07:50:07 +00:00
*/
2009-07-22 19:50:21 +00:00
/* Assume RNA_struct_py_type_get(srna) was alredy checked */
StructRNA * base ;
2009-07-10 04:25:49 +00:00
PyObject * py_base = NULL ;
2009-07-22 19:50:21 +00:00
const char * idname = RNA_struct_identifier ( srna ) ;
const char * descr = RNA_struct_ui_description ( srna ) ;
if ( ! descr ) descr = " (no docs) " ;
2009-03-13 07:50:07 +00:00
2009-07-22 19:50:21 +00:00
/* get the base type */
2009-07-10 04:25:49 +00:00
base = RNA_struct_base ( srna ) ;
if ( base & & base ! = srna ) {
2009-07-10 18:09:53 +00:00
/*/printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); */
py_base = pyrna_srna_Subtype ( base ) ;
2009-08-14 12:29:55 +00:00
Py_DECREF ( py_base ) ; /* srna owns, this is only to pass as an arg */
2009-07-10 04:25:49 +00:00
}
2009-07-10 18:09:53 +00:00
2009-07-10 04:25:49 +00:00
if ( py_base = = NULL ) {
2009-07-10 18:09:53 +00:00
py_base = ( PyObject * ) & pyrna_struct_Type ;
2009-07-10 04:25:49 +00:00
}
2009-08-14 12:29:55 +00:00
/* 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 ) ;
2009-03-21 06:55:30 +00:00
2009-07-10 04:25:49 +00:00
if ( newclass ) {
2009-08-14 12:29:55 +00:00
/* incref's the new class (has 2 now)
* srna owns one , and the other is owned by the caller */
2009-07-10 04:25:49 +00:00
pyrna_subtype_set_rna ( newclass , srna ) ;
2009-08-14 12:29:55 +00:00
2009-07-10 04:25:49 +00:00
// PyObSpit("NewStructRNA Type: ", (PyObject *)newclass);
2009-07-21 20:05:16 +00:00
/* attach functions into the class
* so you can do . . . bpy . types . Scene . SomeFunction ( )
*/
{
PyMethodDef * ml ;
for ( ml = pyrna_struct_subtype_methods ; ml - > ml_name ; ml + + ) {
PyObject_SetAttrString ( newclass , ml - > ml_name , PyCFunction_New ( ml , newclass ) ) ;
}
}
2009-07-10 04:25:49 +00:00
}
else {
/* this should not happen */
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
2009-03-13 07:50:07 +00:00
}
return newclass ;
}
2009-08-14 12:29:55 +00:00
/* 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 */
2009-07-10 18:09:53 +00:00
PyObject * pyrna_struct_Subtype ( PointerRNA * ptr )
{
2009-08-14 12:29:55 +00:00
return pyrna_srna_Subtype ( srna_from_ptr ( ptr ) ) ;
2009-07-10 18:09:53 +00:00
}
2008-11-29 13:36:08 +00:00
/*-----------------------CreatePyObject---------------------------------*/
PyObject * pyrna_struct_CreatePyObject ( PointerRNA * ptr )
{
2009-03-21 06:55:30 +00:00
BPy_StructRNA * pyrna = NULL ;
2009-03-05 16:24:30 +00:00
2009-03-14 13:43:30 +00:00
if ( ptr - > data = = NULL & & ptr - > type = = NULL ) { /* Operator RNA has NULL data */
2009-03-05 16:24:30 +00:00
Py_RETURN_NONE ;
}
2009-07-10 04:25:49 +00:00
else {
2009-03-21 16:03:26 +00:00
PyTypeObject * tp = ( PyTypeObject * ) pyrna_struct_Subtype ( ptr ) ;
2009-03-21 06:55:30 +00:00
if ( tp ) {
pyrna = ( BPy_StructRNA * ) tp - > tp_alloc ( tp , 0 ) ;
2009-08-14 12:29:55 +00:00
Py_DECREF ( tp ) ; /* srna owns, cant hold a ref */
2009-03-21 06:55:30 +00:00
}
else {
fprintf ( stderr , " Could not make type \n " ) ;
pyrna = ( BPy_StructRNA * ) PyObject_NEW ( BPy_StructRNA , & pyrna_struct_Type ) ;
}
2009-03-11 17:28:37 +00:00
}
2009-07-10 04:25:49 +00:00
2008-11-29 13:36:08 +00:00
if ( ! pyrna ) {
PyErr_SetString ( PyExc_MemoryError , " couldn't create BPy_StructRNA object " ) ;
return NULL ;
}
2008-12-29 03:24:13 +00:00
pyrna - > ptr = * ptr ;
2009-07-26 18:18:14 +00:00
pyrna - > freeptr = FALSE ;
2009-07-10 04:25:49 +00:00
// PyObSpit("NewStructRNA: ", (PyObject *)pyrna);
2008-11-29 13:36:08 +00:00
return ( PyObject * ) pyrna ;
}
PyObject * pyrna_prop_CreatePyObject ( PointerRNA * ptr , PropertyRNA * prop )
{
BPy_PropertyRNA * pyrna ;
pyrna = ( BPy_PropertyRNA * ) PyObject_NEW ( BPy_PropertyRNA , & pyrna_prop_Type ) ;
if ( ! pyrna ) {
PyErr_SetString ( PyExc_MemoryError , " couldn't create BPy_rna object " ) ;
return NULL ;
}
pyrna - > ptr = * ptr ;
pyrna - > prop = prop ;
return ( PyObject * ) pyrna ;
}
PyObject * BPY_rna_module ( void )
{
PointerRNA ptr ;
2009-06-22 04:26:48 +00:00
# ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once.
2009-06-25 10:11:37 +00:00
mathutils_rna_array_cb_index = Mathutils_RegisterCallback ( & mathutils_rna_array_cb ) ;
2009-06-23 13:34:45 +00:00
mathutils_rna_matrix_cb_index = Mathutils_RegisterCallback ( & mathutils_rna_matrix_cb ) ;
2009-06-22 04:26:48 +00:00
# endif
2009-03-13 07:50:07 +00:00
/* This can't be set in the pytype struct because some compilers complain */
pyrna_prop_Type . tp_getattro = PyObject_GenericGetAttr ;
pyrna_prop_Type . tp_setattro = PyObject_GenericSetAttr ;
if ( PyType_Ready ( & pyrna_struct_Type ) < 0 )
return NULL ;
if ( PyType_Ready ( & pyrna_prop_Type ) < 0 )
return NULL ;
2008-11-29 13:36:08 +00:00
/* for now, return the base RNA type rather then a real module */
RNA_main_pointer_create ( G . main , & ptr ) ;
return pyrna_struct_CreatePyObject ( & ptr ) ;
}
2008-12-16 16:32:48 +00:00
2009-03-13 07:50:07 +00:00
#if 0
2008-12-16 16:32:48 +00:00
/* This is a way we can access docstrings for RNA types
* without having the datatypes in blender */
PyObject * BPY_rna_doc ( void )
{
PointerRNA ptr ;
/* for now, return the base RNA type rather then a real module */
RNA_blender_rna_pointer_create ( & ptr ) ;
return pyrna_struct_CreatePyObject ( & ptr ) ;
}
2009-03-13 07:50:07 +00:00
# endif
2008-12-16 16:32:48 +00:00
2009-03-11 17:28:37 +00:00
2009-03-21 06:55:30 +00:00
/* pyrna_basetype_* - BPy_BaseTypeRNA is just a BPy_PropertyRNA struct with a differnt type
* the self - > ptr and self - > prop are always set to the " structs " collection */
//---------------getattr--------------------------------------------
static PyObject * pyrna_basetype_getattro ( BPy_BaseTypeRNA * self , PyObject * pyname )
{
PointerRNA newptr ;
PyObject * ret ;
2009-03-11 17:28:37 +00:00
2009-03-21 06:55:30 +00:00
ret = PyObject_GenericGetAttr ( ( PyObject * ) self , pyname ) ;
if ( ret ) return ret ;
else PyErr_Clear ( ) ;
2009-03-11 17:28:37 +00:00
2009-03-21 06:55:30 +00:00
if ( RNA_property_collection_lookup_string ( & self - > ptr , self - > prop , _PyUnicode_AsString ( pyname ) , & newptr ) ) {
2009-04-11 15:05:42 +00:00
ret = pyrna_struct_Subtype ( & newptr ) ;
if ( ret = = NULL ) {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_SystemError , " bpy.types.%.200s subtype could not be generated, this is a bug! " , _PyUnicode_AsString ( pyname ) ) ;
2009-04-11 15:05:42 +00:00
}
return ret ;
2009-03-11 17:28:37 +00:00
}
2009-03-21 06:55:30 +00:00
else { /* Override the error */
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_AttributeError , " bpy.types.%.200s RNA_Struct does not exist " , _PyUnicode_AsString ( pyname ) ) ;
2009-03-21 06:55:30 +00:00
return NULL ;
}
}
static PyObject * pyrna_basetype_dir ( BPy_BaseTypeRNA * self ) ;
static struct PyMethodDef pyrna_basetype_methods [ ] = {
{ " __dir__ " , ( PyCFunction ) pyrna_basetype_dir , METH_NOARGS , " " } ,
2009-04-19 13:37:59 +00:00
{ " register " , ( PyCFunction ) pyrna_basetype_register , METH_VARARGS , " " } ,
{ " unregister " , ( PyCFunction ) pyrna_basetype_unregister , METH_VARARGS , " " } ,
2009-03-21 06:55:30 +00:00
{ NULL , NULL , 0 , NULL }
} ;
static PyObject * pyrna_basetype_dir ( BPy_BaseTypeRNA * self )
{
PyObject * list , * name ;
PyMethodDef * meth ;
list = pyrna_prop_keys ( self ) ; /* like calling structs.keys(), avoids looping here */
for ( meth = pyrna_basetype_methods ; meth - > ml_name ; meth + + ) {
name = PyUnicode_FromString ( meth - > ml_name ) ;
PyList_Append ( list , name ) ;
Py_DECREF ( name ) ;
}
return list ;
}
2009-04-11 16:17:39 +00:00
PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE ;
2009-03-21 06:55:30 +00:00
PyObject * BPY_rna_types ( void )
{
BPy_BaseTypeRNA * self ;
2009-04-07 15:20:12 +00:00
2009-04-11 16:17:39 +00:00
if ( ( pyrna_basetype_Type . tp_flags & Py_TPFLAGS_READY ) = = 0 ) {
pyrna_basetype_Type . tp_name = " RNA_Types " ;
pyrna_basetype_Type . tp_basicsize = sizeof ( BPy_BaseTypeRNA ) ;
pyrna_basetype_Type . tp_getattro = ( getattrofunc ) pyrna_basetype_getattro ;
pyrna_basetype_Type . tp_flags = Py_TPFLAGS_DEFAULT ;
pyrna_basetype_Type . tp_methods = pyrna_basetype_methods ;
if ( PyType_Ready ( & pyrna_basetype_Type ) < 0 )
return NULL ;
}
2009-03-13 07:50:07 +00:00
2009-03-21 06:55:30 +00:00
self = ( BPy_BaseTypeRNA * ) PyObject_NEW ( BPy_BaseTypeRNA , & pyrna_basetype_Type ) ;
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create ( & self - > ptr ) ;
self - > prop = RNA_struct_find_property ( & self - > ptr , " structs " ) ;
return ( PyObject * ) self ;
2009-03-11 17:28:37 +00:00
}
2009-03-16 15:54:43 +00:00
2009-06-18 19:51:22 +00:00
static struct PyMethodDef props_methods [ ] = {
{ " FloatProperty " , ( PyCFunction ) BPy_FloatProperty , METH_VARARGS | METH_KEYWORDS , " " } ,
{ " IntProperty " , ( PyCFunction ) BPy_IntProperty , METH_VARARGS | METH_KEYWORDS , " " } ,
{ " BoolProperty " , ( PyCFunction ) BPy_BoolProperty , METH_VARARGS | METH_KEYWORDS , " " } ,
{ " StringProperty " , ( PyCFunction ) BPy_StringProperty , METH_VARARGS | METH_KEYWORDS , " " } ,
{ NULL , NULL , 0 , NULL }
} ;
2009-03-16 15:54:43 +00:00
2009-06-18 19:51:22 +00:00
static struct PyModuleDef props_module = {
PyModuleDef_HEAD_INIT ,
2009-07-19 13:32:02 +00:00
" bpy.props " ,
2009-06-18 19:51:22 +00:00
" " ,
- 1 , /* multiple "initialization" just copies the module dict. */
props_methods ,
NULL , NULL , NULL , NULL
} ;
PyObject * BPY_rna_props ( void )
{
2009-07-21 20:05:16 +00:00
PyObject * submodule ;
2009-06-18 19:51:22 +00:00
submodule = PyModule_Create ( & props_module ) ;
/* INCREF since its its assumed that all these functions return the
* module with a new ref like PyDict_New , since they are passed to
* PyModule_AddObject which steals a ref */
Py_INCREF ( submodule ) ;
return submodule ;
}
2009-03-21 06:55:30 +00:00
2009-03-16 15:54:43 +00:00
/* Orphan functions, not sure where they should go */
2009-08-09 10:05:33 +00:00
/* get the srna for methods attached to types */
2009-08-11 02:27:25 +00:00
/* */
2009-08-09 10:05:33 +00:00
static StructRNA * srna_from_self ( PyObject * self )
{
BPy_StructRNA * py_srna ;
2009-08-11 02:27:25 +00:00
/* a bit sloppy but would cause a very confusing bug if
* an error happened to be set here */
PyErr_Clear ( ) ;
2009-08-09 10:05:33 +00:00
if ( self = = NULL ) {
return NULL ;
}
2009-08-11 02:27:25 +00:00
else if ( PyCObject_Check ( self ) ) {
2009-08-09 10:05:33 +00:00
return PyCObject_AsVoidPtr ( self ) ;
}
2009-08-11 02:27:25 +00:00
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 */
2009-08-09 10:05:33 +00:00
2009-08-11 02:27:25 +00:00
2009-08-09 10:05:33 +00:00
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_SetString ( PyExc_SystemError , " internal error, self's __rna__ attribute isnt a StructRNA type, should never happen. " ) ;
return NULL ;
}
if ( ( py_srna - > ptr . data & & py_srna - > ptr . type = = & RNA_Struct ) = = 0 ) {
PyErr_SetString ( PyExc_SystemError , " internal error, self's __rna__ attribute wasnt an RNA_Struct, should never happen. " ) ;
return NULL ;
}
if ( ! RNA_struct_is_ID ( py_srna - > ptr . data ) ) {
PyErr_SetString ( PyExc_TypeError , " only ID types support python defined properties " ) ;
return NULL ;
}
return py_srna - > ptr . data ;
}
2009-08-11 02:27:25 +00:00
/* 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 ;
}
2009-03-16 15:54:43 +00:00
/* 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 )
{
2009-03-18 22:22:58 +00:00
static char * kwlist [ ] = { " attr " , " name " , " description " , " min " , " max " , " soft_min " , " soft_max " , " default " , NULL } ;
2009-03-16 15:54:43 +00:00
char * id , * name = " " , * description = " " ;
float min = FLT_MIN , max = FLT_MAX , soft_min = FLT_MIN , soft_max = FLT_MAX , def = 0.0f ;
2009-07-21 20:05:16 +00:00
PropertyRNA * prop ;
2009-08-09 10:05:33 +00:00
StructRNA * srna ;
2009-03-16 15:54:43 +00:00
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 ;
}
2009-08-09 10:05:33 +00:00
srna = srna_from_self ( self ) ;
2009-08-11 02:27:25 +00:00
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 { /* operators defer running this function */
return bpy_prop_deferred_return ( ( void * ) BPy_FloatProperty , kw ) ;
}
2009-03-16 15:54:43 +00:00
}
PyObject * BPy_IntProperty ( PyObject * self , PyObject * args , PyObject * kw )
{
2009-03-18 22:22:58 +00:00
static char * kwlist [ ] = { " attr " , " name " , " description " , " min " , " max " , " soft_min " , " soft_max " , " default " , NULL } ;
2009-03-16 15:54:43 +00:00
char * id , * name = " " , * description = " " ;
int min = INT_MIN , max = INT_MAX , soft_min = INT_MIN , soft_max = INT_MAX , def = 0 ;
2009-07-21 20:05:16 +00:00
PropertyRNA * prop ;
2009-08-09 10:05:33 +00:00
StructRNA * srna ;
2009-03-16 15:54:43 +00:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " s|ssiiiii:IntProperty " , 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 ;
}
2009-08-09 10:05:33 +00:00
srna = srna_from_self ( self ) ;
2009-08-11 02:27:25 +00:00
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 { /* operators defer running this function */
return bpy_prop_deferred_return ( ( void * ) BPy_IntProperty , kw ) ;
}
2009-03-16 15:54:43 +00:00
}
PyObject * BPy_BoolProperty ( PyObject * self , PyObject * args , PyObject * kw )
{
2009-03-18 22:22:58 +00:00
static char * kwlist [ ] = { " attr " , " name " , " description " , " default " , NULL } ;
2009-03-16 15:54:43 +00:00
char * id , * name = " " , * description = " " ;
int def = 0 ;
2009-07-21 20:05:16 +00:00
PropertyRNA * prop ;
2009-08-09 10:05:33 +00:00
StructRNA * srna ;
2009-06-24 21:27:10 +00:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " s|ssi:BoolProperty " , kwlist , & id , & name , & description , & def ) )
2009-03-16 15:54:43 +00:00
return NULL ;
if ( PyTuple_Size ( args ) > 0 ) {
PyErr_SetString ( PyExc_ValueError , " all args must be keywors " ) ; // TODO - py3 can enforce this.
return NULL ;
}
2009-08-11 02:27:25 +00:00
2009-08-09 10:05:33 +00:00
srna = srna_from_self ( self ) ;
2009-08-11 02:27:25 +00:00
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 { /* operators defer running this function */
return bpy_prop_deferred_return ( ( void * ) BPy_BoolProperty , kw ) ;
}
2009-03-16 15:54:43 +00:00
}
2009-04-19 13:37:59 +00:00
2009-06-18 19:51:22 +00:00
PyObject * BPy_StringProperty ( PyObject * self , PyObject * args , PyObject * kw )
{
static char * kwlist [ ] = { " attr " , " name " , " description " , " maxlen " , " default " , NULL } ;
char * id , * name = " " , * description = " " , * def = " " ;
int maxlen = 0 ;
2009-07-21 20:05:16 +00:00
PropertyRNA * prop ;
2009-08-09 10:05:33 +00:00
StructRNA * srna ;
2009-06-18 19:51:22 +00:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " s|ssis:StringProperty " , kwlist , & id , & name , & description , & maxlen , & def ) )
return NULL ;
if ( PyTuple_Size ( args ) > 0 ) {
PyErr_SetString ( PyExc_ValueError , " all args must be keywors " ) ; // TODO - py3 can enforce this.
return NULL ;
}
2009-07-21 20:05:16 +00:00
2009-08-09 10:05:33 +00:00
srna = srna_from_self ( self ) ;
2009-08-11 02:27:25 +00:00
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 { /* operators defer running this function */
return bpy_prop_deferred_return ( ( void * ) BPy_StringProperty , kw ) ;
}
2009-06-18 19:51:22 +00:00
}
2009-04-19 13:37:59 +00:00
/*-------------------- Type Registration ------------------------*/
static int rna_function_arg_count ( FunctionRNA * func )
{
const ListBase * lb = RNA_function_defined_parameters ( func ) ;
PropertyRNA * parm ;
Link * link ;
int count = 1 ;
for ( link = lb - > first ; link ; link = link - > next ) {
parm = ( PropertyRNA * ) link ;
if ( ! ( RNA_property_flag ( parm ) & PROP_RETURN ) )
count + + ;
}
return count ;
}
static int bpy_class_validate ( PointerRNA * dummyptr , void * py_data , int * have_function )
{
const ListBase * lb ;
Link * link ;
FunctionRNA * func ;
PropertyRNA * prop ;
StructRNA * srna = dummyptr - > type ;
const char * class_type = RNA_struct_identifier ( srna ) ;
PyObject * py_class = ( PyObject * ) py_data ;
PyObject * base_class = RNA_struct_py_type_get ( srna ) ;
PyObject * item , * fitem ;
PyObject * py_arg_count ;
int i , flag , arg_count , func_arg_count ;
char identifier [ 128 ] ;
if ( base_class ) {
if ( ! PyObject_IsSubclass ( py_class , base_class ) ) {
PyObject * name = PyObject_GetAttrString ( base_class , " __name__ " ) ;
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " expected %.200s subclass of class \" %.200s \" " , class_type , name ? _PyUnicode_AsString ( name ) : " <UNKNOWN> " ) ;
2009-04-19 13:37:59 +00:00
Py_XDECREF ( name ) ;
return - 1 ;
}
}
/* verify callback functions */
lb = RNA_struct_defined_functions ( srna ) ;
i = 0 ;
for ( link = lb - > first ; link ; link = link - > next ) {
func = ( FunctionRNA * ) link ;
flag = RNA_function_flag ( func ) ;
if ( ! ( flag & FUNC_REGISTER ) )
continue ;
item = PyObject_GetAttrString ( py_class , RNA_function_identifier ( func ) ) ;
have_function [ i ] = ( item ! = NULL ) ;
i + + ;
if ( item = = NULL ) {
if ( ( flag & FUNC_REGISTER_OPTIONAL ) = = 0 ) {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_AttributeError , " expected %.200s class to have an \" %.200s \" attribute " , class_type , RNA_function_identifier ( func ) ) ;
2009-04-19 13:37:59 +00:00
return - 1 ;
}
PyErr_Clear ( ) ;
}
else {
Py_DECREF ( item ) ; /* no need to keep a ref, the class owns it */
if ( PyMethod_Check ( item ) )
fitem = PyMethod_Function ( item ) ; /* py 2.x */
else
fitem = item ; /* py 3.x */
if ( PyFunction_Check ( fitem ) = = 0 ) {
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " expected %.200s class \" %.200s \" attribute to be a function " , class_type , RNA_function_identifier ( func ) ) ;
2009-04-19 13:37:59 +00:00
return - 1 ;
}
func_arg_count = rna_function_arg_count ( func ) ;
if ( func_arg_count > = 0 ) { /* -1 if we dont care*/
py_arg_count = PyObject_GetAttrString ( PyFunction_GET_CODE ( fitem ) , " co_argcount " ) ;
arg_count = PyLong_AsSsize_t ( py_arg_count ) ;
Py_DECREF ( py_arg_count ) ;
if ( arg_count ! = func_arg_count ) {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_AttributeError , " expected %.200s class \" %.200s \" function to have %d args " , class_type , RNA_function_identifier ( func ) , func_arg_count ) ;
2009-04-19 13:37:59 +00:00
return - 1 ;
}
}
}
}
/* verify properties */
lb = RNA_struct_defined_properties ( srna ) ;
for ( link = lb - > first ; link ; link = link - > next ) {
prop = ( PropertyRNA * ) link ;
flag = RNA_property_flag ( prop ) ;
if ( ! ( flag & PROP_REGISTER ) )
continue ;
BLI_snprintf ( identifier , sizeof ( identifier ) , " __%s__ " , RNA_property_identifier ( prop ) ) ;
item = PyObject_GetAttrString ( py_class , identifier ) ;
if ( item = = NULL ) {
if ( strcmp ( identifier , " __idname__ " ) = = 0 ) {
item = PyObject_GetAttrString ( py_class , " __name__ " ) ;
if ( item ) {
Py_DECREF ( item ) ; /* no need to keep a ref, the class owns it */
2009-07-23 13:48:15 +00:00
if ( pyrna_py_to_prop ( dummyptr , prop , NULL , item , " validating class error: " ) ! = 0 )
2009-04-19 13:37:59 +00:00
return - 1 ;
}
}
if ( item = = NULL & & ( flag & PROP_REGISTER_OPTIONAL ) = = 0 ) {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_AttributeError , " expected %.200s class to have an \" %.200s \" attribute " , class_type , identifier ) ;
2009-04-19 13:37:59 +00:00
return - 1 ;
}
PyErr_Clear ( ) ;
}
else {
Py_DECREF ( item ) ; /* no need to keep a ref, the class owns it */
2009-07-23 13:48:15 +00:00
if ( pyrna_py_to_prop ( dummyptr , prop , NULL , item , " validating class error: " ) ! = 0 )
2009-04-19 13:37:59 +00:00
return - 1 ;
}
}
return 0 ;
}
extern void BPY_update_modules ( void ) ; //XXX temp solution
static int bpy_class_call ( PointerRNA * ptr , FunctionRNA * func , ParameterList * parms )
{
PyObject * args ;
PyObject * ret = NULL , * py_class , * py_class_instance , * item , * parmitem ;
PropertyRNA * pret = NULL , * parm ;
ParameterIterator iter ;
PointerRNA funcptr ;
void * retdata = NULL ;
int err = 0 , i , flag ;
2009-08-07 16:20:19 +00:00
PyGILState_STATE gilstate ;
2009-04-19 13:37:59 +00:00
2009-08-07 16:20:19 +00:00
bContext * C = BPy_GetContext ( ) ; // XXX - NEEDS FIXING, QUITE BAD.
bpy_context_set ( C , & gilstate ) ;
2009-04-19 13:37:59 +00:00
py_class = RNA_struct_py_type_get ( ptr - > type ) ;
2009-05-20 05:35:53 +00:00
item = pyrna_struct_CreatePyObject ( ptr ) ;
if ( item = = NULL ) {
py_class_instance = NULL ;
}
else if ( item = = Py_None ) { /* probably wont ever happen but possible */
Py_DECREF ( item ) ;
py_class_instance = NULL ;
}
else {
args = PyTuple_New ( 1 ) ;
PyTuple_SET_ITEM ( args , 0 , item ) ;
py_class_instance = PyObject_Call ( py_class , args , NULL ) ;
Py_DECREF ( args ) ;
}
2009-04-19 13:37:59 +00:00
if ( py_class_instance ) { /* Initializing the class worked, now run its invoke function */
item = PyObject_GetAttrString ( py_class , RNA_function_identifier ( func ) ) ;
flag = RNA_function_flag ( func ) ;
if ( item ) {
pret = RNA_function_return ( func ) ;
RNA_pointer_create ( NULL , & RNA_Function , func , & funcptr ) ;
args = PyTuple_New ( rna_function_arg_count ( func ) ) ;
PyTuple_SET_ITEM ( args , 0 , py_class_instance ) ;
RNA_parameter_list_begin ( parms , & iter ) ;
/* parse function parameters */
for ( i = 1 ; iter . valid ; RNA_parameter_list_next ( & iter ) ) {
parm = iter . parm ;
if ( parm = = pret ) {
retdata = iter . data ;
continue ;
}
parmitem = pyrna_param_to_py ( & funcptr , parm , iter . data ) ;
PyTuple_SET_ITEM ( args , i , parmitem ) ;
i + + ;
}
ret = PyObject_Call ( item , args , NULL ) ;
Py_DECREF ( item ) ;
2009-05-20 05:35:53 +00:00
Py_DECREF ( args ) ;
2009-04-19 13:37:59 +00:00
}
else {
Py_DECREF ( py_class_instance ) ;
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " could not find function %.200s in %.200s to execute callback. " , RNA_function_identifier ( func ) , RNA_struct_identifier ( ptr - > type ) ) ;
2009-04-19 13:37:59 +00:00
err = - 1 ;
}
}
else {
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_RuntimeError , " could not create instance of %.200s to call callback function %.200s. " , RNA_struct_identifier ( ptr - > type ) , RNA_function_identifier ( func ) ) ;
2009-04-19 13:37:59 +00:00
err = - 1 ;
}
if ( ret = = NULL ) { /* covers py_class_instance failing too */
err = - 1 ;
}
else {
if ( retdata )
2009-07-23 13:48:15 +00:00
err = pyrna_py_to_prop ( & funcptr , pret , retdata , ret , " calling class function: " ) ;
2009-04-19 13:37:59 +00:00
Py_DECREF ( ret ) ;
}
2009-07-23 13:48:15 +00:00
if ( err ! = 0 ) {
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
2009-08-07 16:20:19 +00:00
bpy_context_clear ( C , & gilstate ) ;
2009-04-19 13:37:59 +00:00
return err ;
}
static void bpy_class_free ( void * pyob_ptr )
{
2009-08-14 12:29:55 +00:00
PyObject * self = ( PyObject * ) pyob_ptr ;
PyGILState_STATE gilstate ;
gilstate = PyGILState_Ensure ( ) ;
PyDict_Clear ( ( ( PyTypeObject * ) self ) - > tp_dict ) ;
2009-05-28 02:03:48 +00:00
if ( G . f & G_DEBUG ) {
2009-08-14 12:29:55 +00:00
if ( self - > ob_refcnt > 1 ) {
PyObSpit ( " zombie class - ref should be 1 " , self ) ;
}
2009-05-28 02:03:48 +00:00
}
2009-08-14 12:29:55 +00:00
2009-04-19 13:37:59 +00:00
Py_DECREF ( ( PyObject * ) pyob_ptr ) ;
2009-08-14 12:29:55 +00:00
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 ;
2009-04-19 13:37:59 +00:00
}
PyObject * pyrna_basetype_register ( PyObject * self , PyObject * args )
{
bContext * C = NULL ;
PyObject * py_class , * item ;
ReportList reports ;
StructRegisterFunc reg ;
BPy_StructRNA * py_srna ;
StructRNA * srna ;
if ( ! PyArg_ParseTuple ( args , " O:register " , & py_class ) )
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 ) ) {
2009-06-07 14:53:08 +00:00
Py_XDECREF ( item ) ;
2009-04-19 13:37:59 +00:00
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 ) ;
if ( ! reg ) {
PyErr_SetString ( PyExc_AttributeError , " expected a Type subclassed from a registerable rna type (no register supported). " ) ;
return NULL ;
}
/* get the context, so register callback can do necessary refreshes */
2009-05-25 13:48:44 +00:00
C = BPy_GetContext ( ) ;
2009-04-19 13:37:59 +00:00
/* call the register callback */
2009-06-18 19:48:55 +00:00
BKE_reports_init ( & reports , RPT_STORE ) ;
2009-04-19 13:37:59 +00:00
srna = reg ( C , & reports , py_class , bpy_class_validate , bpy_class_call , bpy_class_free ) ;
if ( ! srna ) {
BPy_reports_to_error ( & reports ) ;
BKE_reports_clear ( & reports ) ;
return NULL ;
}
BKE_reports_clear ( & reports ) ;
2009-05-26 06:29:15 +00:00
pyrna_subtype_set_rna ( py_class , srna ) ; /* takes a ref to py_class */
2009-04-19 13:37:59 +00:00
Py_RETURN_NONE ;
}
PyObject * pyrna_basetype_unregister ( PyObject * self , PyObject * args )
{
bContext * C = NULL ;
PyObject * py_class , * item ;
BPy_StructRNA * py_srna ;
StructUnregisterFunc unreg ;
2009-04-23 05:56:09 +00:00
if ( ! PyArg_ParseTuple ( args , " O:unregister " , & py_class ) )
2009-04-19 13:37:59 +00:00
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 */
2009-04-23 09:15:42 +00:00
item = PyDict_GetItemString ( ( ( PyTypeObject * ) py_class ) - > tp_dict , " __rna__ " ) ; /* borrow ref */
2009-04-19 13:37:59 +00:00
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 ) ;
if ( ! unreg ) {
PyErr_SetString ( PyExc_AttributeError , " expected a Type subclassed from a registerable rna type (no unregister supported). " ) ;
return NULL ;
}
/* get the context, so register callback can do necessary refreshes */
2009-05-25 13:48:44 +00:00
C = BPy_GetContext ( ) ;
2009-04-19 13:37:59 +00:00
/* call unregister */
unreg ( C , py_srna - > ptr . data ) ;
/* remove reference to old type */
Py_DECREF ( py_class ) ;
Py_RETURN_NONE ;
}