diff options
author | Joseph Gilbert <ascotan@gmail.com> | 2004-06-11 17:15:50 +0400 |
---|---|---|
committer | Joseph Gilbert <ascotan@gmail.com> | 2004-06-11 17:15:50 +0400 |
commit | 3a816f1c307c84ff637d12b1d6d8ffef739fbcd6 (patch) | |
tree | 9c172e5995691064d8463a3481f5bac6ffef1522 /source/blender/python/api2_2x/logic.c | |
parent | 648a2d3819d2910f56c06da8844b96d7fa18c84f (diff) |
- new internal Property module
- Object support for add/remove/modify object Properties
Diffstat (limited to 'source/blender/python/api2_2x/logic.c')
-rw-r--r-- | source/blender/python/api2_2x/logic.c | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/source/blender/python/api2_2x/logic.c b/source/blender/python/api2_2x/logic.c new file mode 100644 index 00000000000..5b8f589153b --- /dev/null +++ b/source/blender/python/api2_2x/logic.c @@ -0,0 +1,468 @@ +/* + * + * ***** 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; +} + |