Run everything thru indent to cleanup spaces vs tabs. Clean up some of the comments by hand. BGL.c was not touched due to all that macro wackyness. There are no functional changes to the code. Pre-indent versions of source are tagged with tag bpy-cleanup-20040925 , just in case.
557 lines
16 KiB
C
557 lines
16 KiB
C
/*
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* 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.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* This is a new part of Blender.
|
|
*
|
|
* Contributor(s): Joseph Gilbert
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
*/
|
|
|
|
#include "logic.h"
|
|
#include "gen_utils.h"
|
|
#include <MEM_guardedalloc.h>
|
|
#include <BLI_blenlib.h>
|
|
|
|
//--------------- Python BPy_Property methods declarations:---------------
|
|
static PyObject *Property_getName( BPy_Property * self );
|
|
static PyObject *Property_setName( BPy_Property * self, PyObject * args );
|
|
static PyObject *Property_getData( BPy_Property * self );
|
|
static PyObject *Property_setData( BPy_Property * self, PyObject * args );
|
|
static PyObject *Property_getType( BPy_Property * self );
|
|
//--------------- Python BPy_Property methods table:----------------------
|
|
static PyMethodDef BPy_Property_methods[] = {
|
|
{"getName", ( PyCFunction ) Property_getName, METH_NOARGS,
|
|
"() - return Property name"},
|
|
{"setName", ( PyCFunction ) Property_setName, METH_VARARGS,
|
|
"() - set the name of this Property"},
|
|
{"getData", ( PyCFunction ) Property_getData, METH_NOARGS,
|
|
"() - return Property data"},
|
|
{"setData", ( PyCFunction ) Property_setData, METH_VARARGS,
|
|
"() - set the data of this Property"},
|
|
{"getType", ( PyCFunction ) Property_getType, METH_NOARGS,
|
|
"() - return Property type"},
|
|
{NULL, NULL, 0, NULL}
|
|
};
|
|
//--------------- Python TypeProperty callback function prototypes--------
|
|
static void Property_dealloc( BPy_Property * Property );
|
|
static PyObject *Property_getAttr( BPy_Property * Property, char *name );
|
|
static int Property_setAttr( BPy_Property * Property, char *name,
|
|
PyObject * v );
|
|
static PyObject *Property_repr( BPy_Property * Property );
|
|
static int Property_compare( BPy_Property * a1, BPy_Property * a2 );
|
|
//--------------- Python TypeProperty structure definition----------------
|
|
PyTypeObject property_Type = {
|
|
PyObject_HEAD_INIT( NULL )
|
|
0, /* ob_size */
|
|
"Blender Property", /* tp_name */
|
|
sizeof( BPy_Property ), /* tp_basicsize */
|
|
0, /* tp_itemsize */
|
|
/* methods */
|
|
( destructor ) Property_dealloc, /* tp_dealloc */
|
|
0, /* tp_print */
|
|
( getattrfunc ) Property_getAttr, /* tp_getattr */
|
|
( setattrfunc ) Property_setAttr, /* tp_setattr */
|
|
( cmpfunc ) Property_compare, /* tp_compare */
|
|
( reprfunc ) Property_repr, /* tp_repr */
|
|
0, /* tp_as_number */
|
|
0, /* tp_as_sequence */
|
|
0, /* tp_as_mapping */
|
|
0, /* tp_as_hash */
|
|
0, 0, 0, 0, 0, 0,
|
|
0, /* tp_doc */
|
|
0, 0, 0, 0, 0, 0,
|
|
BPy_Property_methods, /* tp_methods */
|
|
0, /* tp_members */
|
|
};
|
|
//--------------- Property module internal callbacks-------------------
|
|
|
|
//--------------- updatePyProperty-------------------------------------
|
|
int updatePyProperty( BPy_Property * self )
|
|
{
|
|
if( !self->property ) {
|
|
return 0; //nothing to update - not linked
|
|
} else {
|
|
BLI_strncpy( self->name, self->property->name, 32 );
|
|
self->type = self->property->type;
|
|
if( self->property->type == PROP_BOOL ) {
|
|
if( *( ( int * ) &self->property->poin ) ) {
|
|
self->data = EXPP_incr_ret( Py_True );
|
|
} else {
|
|
self->data = EXPP_incr_ret( Py_False );
|
|
}
|
|
} else if( self->property->type == PROP_INT ) {
|
|
self->data = PyInt_FromLong( self->property->data );
|
|
} else if( self->property->type == PROP_FLOAT ) {
|
|
self->data =
|
|
PyFloat_FromDouble( *
|
|
( ( float * ) &self->
|
|
property->data ) );
|
|
} else if( self->property->type == PROP_TIME ) {
|
|
self->data =
|
|
PyFloat_FromDouble( *
|
|
( ( float * ) &self->
|
|
property->data ) );
|
|
} else if( self->property->type == PROP_STRING ) {
|
|
self->data =
|
|
PyString_FromString( self->property->poin );
|
|
}
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//--------------- updatePropertyData------------------------------------
|
|
int updateProperyData( BPy_Property * self )
|
|
{
|
|
if( !self->property ) {
|
|
//nothing to update - not linked
|
|
return 0;
|
|
} else {
|
|
BLI_strncpy( self->property->name, self->name, 32 );
|
|
self->property->type = self->type;
|
|
if( PyInt_Check( self->data ) ) {
|
|
*( ( int * ) &self->property->data ) =
|
|
( int ) PyInt_AsLong( self->data );
|
|
} else if( PyFloat_Check( self->data ) ) {
|
|
*( ( float * ) &self->property->data ) =
|
|
( float ) PyFloat_AsDouble( self->data );
|
|
} else if( PyString_Check( self->data ) ) {
|
|
BLI_strncpy( self->property->poin,
|
|
PyString_AsString( self->data ),
|
|
MAX_PROPSTRING );
|
|
}
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//--------------- checkValidData_ptr--------------------------------
|
|
int checkValidData_ptr( BPy_Property * self )
|
|
{
|
|
int length;
|
|
//test pointer to see if data was removed (oops)
|
|
length = MEM_allocN_len( self->property );
|
|
if( length != sizeof( bProperty ) ) { //data was freed
|
|
self->property = NULL;
|
|
return 0;
|
|
} else { //it's ok as far as we can tell
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//---------------BPy_Property internal callbacks/methods------------
|
|
|
|
//--------------- dealloc-------------------------------------------
|
|
static void Property_dealloc( BPy_Property * self )
|
|
{
|
|
PyMem_Free( self->name );
|
|
PyObject_DEL( self );
|
|
}
|
|
|
|
//---------------getattr--------------------------------------------
|
|
static PyObject *Property_getAttr( BPy_Property * self, char *name )
|
|
{
|
|
PyObject *attr = Py_None;
|
|
|
|
checkValidData_ptr( self );
|
|
if( strcmp( name, "name" ) == 0 )
|
|
attr = Property_getName( self );
|
|
else if( strcmp( name, "data" ) == 0 )
|
|
attr = Property_getData( self );
|
|
else if( strcmp( name, "type" ) == 0 )
|
|
attr = Property_getType( self );
|
|
else if( strcmp( name, "__members__" ) == 0 ) {
|
|
attr = Py_BuildValue( "[s,s,s]", "name", "data", "type" );
|
|
}
|
|
|
|
if( !attr )
|
|
return ( EXPP_ReturnPyObjError
|
|
( PyExc_MemoryError, "couldn't create PyObject" ) );
|
|
|
|
if( attr != Py_None )
|
|
return attr;
|
|
|
|
return Py_FindMethod( BPy_Property_methods, ( PyObject * ) self,
|
|
name );
|
|
}
|
|
|
|
//--------------- setattr-------------------------------------------
|
|
static int
|
|
Property_setAttr( BPy_Property * self, char *name, PyObject * value )
|
|
{
|
|
PyObject *valtuple;
|
|
PyObject *error = NULL;
|
|
|
|
checkValidData_ptr( self );
|
|
valtuple = Py_BuildValue( "(O)", value );
|
|
if( !valtuple )
|
|
return EXPP_ReturnIntError( PyExc_MemoryError,
|
|
"PropertySetAttr: couldn't create tuple" );
|
|
|
|
if( strcmp( name, "name" ) == 0 )
|
|
error = Property_setName( self, valtuple );
|
|
else if( strcmp( name, "data" ) == 0 )
|
|
error = Property_setData( self, valtuple );
|
|
else {
|
|
Py_DECREF( valtuple );
|
|
return ( EXPP_ReturnIntError
|
|
( PyExc_KeyError, "attribute not found" ) );
|
|
}
|
|
Py_DECREF( valtuple );
|
|
|
|
if( error != Py_None )
|
|
return -1;
|
|
|
|
Py_DECREF( Py_None );
|
|
return 0;
|
|
}
|
|
|
|
//--------------- repr----------------------------------------------
|
|
static PyObject *Property_repr( BPy_Property * self )
|
|
{
|
|
checkValidData_ptr( self );
|
|
if( self->property ) {
|
|
return PyString_FromFormat( "[Property \"%s\"]",
|
|
self->property->name );
|
|
} else {
|
|
return PyString_FromFormat( "[Property \"%s\"]", self->name );
|
|
}
|
|
}
|
|
|
|
//--------------- compare-------------------------------------------
|
|
//compares property.name and property.data
|
|
static int Property_compare( BPy_Property * a, BPy_Property * b )
|
|
{
|
|
BPy_Property *py_propA, *py_propB;
|
|
int retval = -1;
|
|
|
|
checkValidData_ptr( a );
|
|
checkValidData_ptr( b );
|
|
//2 python objects
|
|
if( !a->property && !b->property ) {
|
|
if( a->type != b->type )
|
|
retval = -1;
|
|
if( BLI_streq( a->name, b->name ) ) {
|
|
retval = PyObject_Compare( a->data, b->data );
|
|
} else
|
|
retval = -1;
|
|
} else if( a->property && b->property ) { //2 real properties
|
|
if( a->property->type != b->property->type )
|
|
retval = -1;
|
|
if( BLI_streq( a->property->name, b->property->name ) ) {
|
|
if( a->property->type == PROP_BOOL
|
|
|| a->property->type == PROP_INT ) {
|
|
if( a->property->data == b->property->data )
|
|
retval = 0;
|
|
else
|
|
retval = -1;
|
|
} else if( a->property->type == PROP_FLOAT
|
|
|| a->property->type == PROP_TIME ) {
|
|
if( *( ( float * ) &a->property->data ) ==
|
|
*( ( float * ) &b->property->data ) )
|
|
retval = 0;
|
|
else
|
|
retval = -1;
|
|
} else if( a->property->type == PROP_STRING ) {
|
|
if( BLI_streq
|
|
( a->property->poin, b->property->poin ) )
|
|
retval = 0;
|
|
else
|
|
retval = -1;
|
|
}
|
|
} else
|
|
retval = -1;
|
|
} else { //1 real 1 python
|
|
if( !a->property ) {
|
|
py_propA = a;
|
|
py_propB = b;
|
|
} else {
|
|
py_propA = b;
|
|
py_propB = a;
|
|
}
|
|
if( py_propB->property->type != py_propA->type )
|
|
retval = -1;
|
|
if( BLI_streq( py_propB->property->name, py_propA->name ) ) {
|
|
if( py_propB->property->type == PROP_BOOL ||
|
|
py_propB->property->type == PROP_INT ) {
|
|
retval = PyObject_Compare( py_propA->data,
|
|
PyInt_FromLong
|
|
( py_propB->
|
|
property->
|
|
data ) );
|
|
} else if( py_propB->property->type == PROP_FLOAT
|
|
|| py_propB->property->type == PROP_TIME ) {
|
|
retval = PyObject_Compare( py_propA->data,
|
|
PyFloat_FromDouble
|
|
( *
|
|
( ( float * )
|
|
&py_propB->
|
|
property->
|
|
data ) ) );
|
|
} else if( py_propB->property->type == PROP_STRING ) {
|
|
retval = PyObject_Compare( py_propA->data,
|
|
PyString_FromString
|
|
( py_propB->
|
|
property->
|
|
poin ) );
|
|
}
|
|
} else
|
|
retval = -1;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
//--------------- Property visible functions------------------------
|
|
//--------------- Property_CreatePyObject---------------------------
|
|
PyObject *Property_CreatePyObject( struct bProperty * Property )
|
|
{
|
|
BPy_Property *py_property;
|
|
|
|
py_property =
|
|
( BPy_Property * ) PyObject_NEW( BPy_Property,
|
|
&property_Type );
|
|
|
|
//set the struct flag
|
|
py_property->property = Property;
|
|
|
|
//allocate space for python vars
|
|
py_property->name = PyMem_Malloc( 32 );
|
|
|
|
if( !updatePyProperty( py_property ) )
|
|
return ( EXPP_ReturnPyObjError
|
|
( PyExc_AttributeError, "Property struct empty" ) );
|
|
|
|
return ( ( PyObject * ) py_property );
|
|
}
|
|
|
|
//--------------- Property_CheckPyObject----------------------------
|
|
int Property_CheckPyObject( PyObject * py_obj )
|
|
{
|
|
return ( py_obj->ob_type == &property_Type );
|
|
}
|
|
|
|
//--------------- Property_FromPyObject-----------------------------
|
|
struct bProperty *Property_FromPyObject( PyObject * py_obj )
|
|
{
|
|
BPy_Property *py_property;
|
|
|
|
py_property = ( BPy_Property * ) py_obj;
|
|
if( !py_property->property )
|
|
return NULL;
|
|
else
|
|
return ( py_property->property );
|
|
}
|
|
|
|
//--------------- newPropertyObject()-------------------------------
|
|
PyObject *newPropertyObject( char *name, PyObject * data, int type )
|
|
{
|
|
BPy_Property *py_property;
|
|
|
|
py_property =
|
|
( BPy_Property * ) PyObject_NEW( BPy_Property,
|
|
&property_Type );
|
|
py_property->name = PyMem_Malloc( 32 );
|
|
py_property->property = NULL;
|
|
|
|
BLI_strncpy( py_property->name, name, 32 );
|
|
py_property->data = data;
|
|
py_property->type = type;
|
|
|
|
return ( PyObject * ) py_property;
|
|
}
|
|
|
|
//--------------- Python BPy_Property methods-----------------------
|
|
//--------------- BPy_Property.getName()----------------------------
|
|
static PyObject *Property_getName( BPy_Property * self )
|
|
{
|
|
PyObject *attr = NULL;
|
|
|
|
if( !self->property )
|
|
attr = PyString_FromString( self->name );
|
|
else
|
|
attr = PyString_FromString( self->property->name );
|
|
|
|
if( attr )
|
|
return attr;
|
|
|
|
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
|
"couldn't get Property.name attribute" ) );
|
|
}
|
|
|
|
//--------------- BPy_Property.setName()----------------------------
|
|
static PyObject *Property_setName( BPy_Property * self, PyObject * args )
|
|
{
|
|
char *name;
|
|
|
|
if( !PyArg_ParseTuple( args, "s", &name ) )
|
|
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
|
|
"expected string argument" ) );
|
|
|
|
if( !self->property ) {
|
|
BLI_strncpy( self->name, name, 32 );
|
|
} else {
|
|
BLI_strncpy( self->property->name, name, 32 );
|
|
updatePyProperty( self );
|
|
}
|
|
|
|
return EXPP_incr_ret( Py_None );
|
|
}
|
|
|
|
//--------------- BPy_Property.getData()----------------------------
|
|
static PyObject *Property_getData( BPy_Property * self )
|
|
{
|
|
PyObject *attr = NULL;
|
|
|
|
if( !self->property ) {
|
|
attr = EXPP_incr_ret( self->data );
|
|
} else {
|
|
if( self->property->type == PROP_BOOL ) {
|
|
if( *( ( int * ) &self->property->poin ) )
|
|
attr = EXPP_incr_ret( Py_True );
|
|
else
|
|
attr = EXPP_incr_ret( Py_False );
|
|
} else if( self->property->type == PROP_INT ) {
|
|
attr = PyInt_FromLong( self->property->data );
|
|
} else if( self->property->type == PROP_FLOAT ||
|
|
self->property->type == PROP_TIME ) {
|
|
attr = PyFloat_FromDouble( *
|
|
( ( float * ) &self->
|
|
property->data ) );
|
|
} else if( self->property->type == PROP_STRING ) {
|
|
attr = PyString_FromString( self->property->poin );
|
|
}
|
|
}
|
|
if( attr )
|
|
return attr;
|
|
|
|
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
|
"couldn't get Property.name attribute" ) );
|
|
}
|
|
|
|
//--------------- BPy_Property.setData()----------------------------
|
|
static PyObject *Property_setData( BPy_Property * self, PyObject * args )
|
|
{
|
|
PyObject *data;
|
|
char *type_str = NULL;
|
|
int type = -1;
|
|
short *p_type = NULL;
|
|
|
|
if( !PyArg_ParseTuple( args, "O|s", &data, &type_str ) )
|
|
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
|
|
"expected object and optional string argument" ) );
|
|
|
|
if( !PyInt_Check( data ) && !PyFloat_Check( data )
|
|
&& !PyString_Check( data ) )
|
|
return ( EXPP_ReturnPyObjError
|
|
( PyExc_RuntimeError,
|
|
"float, int, or string expected as data" ) );
|
|
|
|
//parse property name
|
|
if( type_str ) {
|
|
if( BLI_streq( type_str, "BOOL" ) )
|
|
type = PROP_BOOL;
|
|
else if( BLI_streq( type_str, "INT" ) )
|
|
type = PROP_INT;
|
|
else if( BLI_streq( type_str, "FLOAT" ) )
|
|
type = PROP_FLOAT;
|
|
else if( BLI_streq( type_str, "TIME" ) )
|
|
type = PROP_TIME;
|
|
else if( BLI_streq( type_str, "STRING" ) )
|
|
type = PROP_STRING;
|
|
else
|
|
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
|
"BOOL, INT, FLOAT, TIME or STRING expected" ) );
|
|
}
|
|
//get pointer to type
|
|
if( self->property )
|
|
p_type = &self->property->type;
|
|
else
|
|
p_type = &self->type;
|
|
|
|
//set the type
|
|
if( PyInt_Check( data ) ) {
|
|
if( type == -1 || type == PROP_INT )
|
|
*p_type = PROP_INT;
|
|
else
|
|
*p_type = PROP_BOOL;
|
|
} else if( PyFloat_Check( data ) ) {
|
|
if( type == -1 || type == PROP_FLOAT )
|
|
*p_type = PROP_FLOAT;
|
|
else
|
|
*p_type = PROP_TIME;
|
|
} else if( PyString_Check( data ) ) {
|
|
if( type == -1 || type == PROP_STRING )
|
|
*p_type = PROP_STRING;
|
|
} else {
|
|
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
|
"cant set unknown data type" ) );
|
|
}
|
|
|
|
//set the data
|
|
if( self->property ) {
|
|
if( PyInt_Check( data ) ) {
|
|
*( ( int * ) &self->property->data ) =
|
|
( int ) PyInt_AsLong( data );
|
|
} else if( PyFloat_Check( data ) ) {
|
|
*( ( float * ) &self->property->data ) =
|
|
( float ) PyFloat_AsDouble( data );
|
|
} else if( PyString_Check( data ) ) {
|
|
BLI_strncpy( self->property->poin,
|
|
PyString_AsString( data ),
|
|
MAX_PROPSTRING );
|
|
}
|
|
updatePyProperty( self );
|
|
} else {
|
|
self->data = data;
|
|
}
|
|
return EXPP_incr_ret( Py_None );
|
|
}
|
|
|
|
//--------------- BPy_Property.getType()----------------------------
|
|
static PyObject *Property_getType( BPy_Property * self )
|
|
{
|
|
PyObject *attr = Py_None;
|
|
int type;
|
|
|
|
if( self->property )
|
|
type = self->property->type;
|
|
else
|
|
type = self->type;
|
|
|
|
if( type == PROP_BOOL )
|
|
attr = Py_BuildValue( "s", "BOOL" );
|
|
else if( type == PROP_INT )
|
|
attr = Py_BuildValue( "s", "INT" );
|
|
else if( type == PROP_FLOAT )
|
|
attr = Py_BuildValue( "s", "FLOAT" );
|
|
else if( type == PROP_STRING )
|
|
attr = Py_BuildValue( "s", "STRING" );
|
|
else if( type == PROP_TIME )
|
|
attr = Py_BuildValue( "s", "TIME" );
|
|
|
|
return attr;
|
|
}
|