This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/python/api2_2x/logic.c
Willian Padovani Germano 34977b8937 BPython:
- applied Campbell Barton's patch for access to Oops location and selection of materials, mesh data and objects, slightly modified. Thanks, Campbell;
- got rid of warnings in many files, hopefully not introducing any other during the process.  Mostly this was done: 1) new EXPP_incr_ret_True/False functions were added and used instead of "Py_INCREF(Py_True/False); return Py_True/False;".  Currently at least the functions use the fact that PyTrue/False == 1/0 and use 1 and 0 to avoid the warnings. 2) Filling of certain types structs got 0's added for all not defined data and methods.  This is surely Python version specific, since these structs can change size and content at each major version number Python update.
2005-02-09 15:53:35 +00:00

558 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 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
//--------------- 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_True();
} else {
self->data = EXPP_incr_ret_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( self->property->data )
attr = EXPP_incr_ret_True();
else
attr = EXPP_incr_ret_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;
}