| 
									
										
										
										
											2006-11-29 23:31:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * $Id: IDProp.c | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-04-16 22:40:48 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							| 
									
										
										
										
											2006-11-29 23:31:46 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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 | 
					
						
							| 
									
										
										
										
											2008-04-16 22:40:48 +00:00
										 |  |  |  * of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2006-11-29 23:31:46 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Joseph Eagar | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-04-16 22:40:48 +00:00
										 |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							| 
									
										
										
										
											2006-11-29 23:31:46 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | #include "DNA_ID.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_idprop.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "IDProp.h"
 | 
					
						
							|  |  |  | #include "gen_utils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define BSTR_EQ(a, b)	(*(a) == *(b) && !strcmp(a, b))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*** Function to wrap ID properties ***/ | 
					
						
							| 
									
										
										
										
											2006-11-19 16:00:04 +00:00
										 |  |  | PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern PyTypeObject IDArray_Type; | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | extern PyTypeObject IDGroup_Iter_Type; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*********************** ID Property Main Wrapper Stuff ***************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | PyObject *IDGroup_repr( BPy_IDProperty *self ) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	return PyString_FromString( "(ID Property)" ); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern PyTypeObject IDGroup_Type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop ) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	switch ( prop->type ) { | 
					
						
							|  |  |  | 		case IDP_STRING: | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyString_FromString( prop->data.pointer ); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		case IDP_INT: | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyInt_FromLong( (long)prop->data.val ); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		case IDP_FLOAT: | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyFloat_FromDouble( (double)(*(float*)(&prop->data.val)) ); | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 		case IDP_DOUBLE: | 
					
						
							|  |  |  | 			return PyFloat_FromDouble( (*(double*)(&prop->data.val)) ); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		case IDP_GROUP: | 
					
						
							|  |  |  | 			/*blegh*/ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 				BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &IDGroup_Type); | 
					
						
							|  |  |  | 				if (!group) | 
					
						
							|  |  |  | 					return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 					   "PyObject_New() failed" ); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 				group->id = id; | 
					
						
							|  |  |  | 				group->prop = prop; | 
					
						
							|  |  |  | 				return (PyObject*) group; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		case IDP_ARRAY: | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 				BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &IDArray_Type); | 
					
						
							|  |  |  | 				if (!array) | 
					
						
							|  |  |  | 					return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 					   "PyObject_New() failed" ); | 
					
						
							|  |  |  | 					    | 
					
						
							|  |  |  | 				array->id = id; | 
					
						
							|  |  |  | 				array->prop = prop; | 
					
						
							|  |  |  | 				return (PyObject*) array; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (prop->type) { | 
					
						
							|  |  |  | 		case IDP_STRING: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			char *st; | 
					
						
							|  |  |  | 			if (!PyString_Check(value)) | 
					
						
							|  |  |  | 				return EXPP_ReturnIntError(PyExc_TypeError, "expected a string!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			st = PyString_AsString(value); | 
					
						
							|  |  |  | 			IDP_ResizeArray(prop, strlen(st)+1); | 
					
						
							|  |  |  | 			strcpy(prop->data.pointer, st); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case IDP_INT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			int ivalue; | 
					
						
							|  |  |  | 			if (!PyNumber_Check(value)) | 
					
						
							|  |  |  | 				return EXPP_ReturnIntError(PyExc_TypeError, "expected an int!"); | 
					
						
							|  |  |  | 			value = PyNumber_Int(value); | 
					
						
							|  |  |  | 			if (!value) | 
					
						
							|  |  |  | 				return EXPP_ReturnIntError(PyExc_TypeError, "expected an int!"); | 
					
						
							|  |  |  | 			ivalue = (int) PyInt_AsLong(value); | 
					
						
							|  |  |  | 			prop->data.val = ivalue; | 
					
						
							|  |  |  | 			Py_XDECREF(value); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case IDP_FLOAT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			float fvalue; | 
					
						
							|  |  |  | 			if (!PyNumber_Check(value)) | 
					
						
							|  |  |  | 				return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!"); | 
					
						
							|  |  |  | 			value = PyNumber_Float(value); | 
					
						
							|  |  |  | 			if (!value) | 
					
						
							|  |  |  | 				return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!"); | 
					
						
							|  |  |  | 			fvalue = (float) PyFloat_AsDouble(value); | 
					
						
							|  |  |  | 			*(float*)&self->prop->data.val = fvalue; | 
					
						
							|  |  |  | 			Py_XDECREF(value); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 		case IDP_DOUBLE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			double dvalue; | 
					
						
							|  |  |  | 			if (!PyNumber_Check(value)) | 
					
						
							|  |  |  | 				return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!"); | 
					
						
							|  |  |  | 			value = PyNumber_Float(value); | 
					
						
							|  |  |  | 			if (!value) | 
					
						
							|  |  |  | 				return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!"); | 
					
						
							|  |  |  | 			dvalue = (float) PyFloat_AsDouble(value); | 
					
						
							|  |  |  | 			*(double*)&self->prop->data.val = dvalue; | 
					
						
							|  |  |  | 			Py_XDECREF(value); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			return EXPP_ReturnIntError(PyExc_AttributeError, "attempt to set read-only attribute!"); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-22 04:41:21 +00:00
										 |  |  | PyObject *BPy_IDGroup_GetName(BPy_IDProperty *self, void *bleh) | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	return PyString_FromString(self->prop->name); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-22 04:41:21 +00:00
										 |  |  | int BPy_IDGroup_SetName(BPy_IDProperty *self, PyObject *value, void *bleh) | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *st; | 
					
						
							|  |  |  | 	if (!PyString_Check(value)) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_TypeError, "expected a string!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	st = PyString_AsString(value); | 
					
						
							|  |  |  | 	if (strlen(st) >= MAX_IDPROP_NAME) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_TypeError, "string length cannot exceed 31 characters!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	strcpy(self->prop->name, st); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDGroup_GetType(BPy_IDProperty *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	return PyInt_FromLong((long)self->prop->type); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyGetSetDef BPy_IDGroup_getseters[] = { | 
					
						
							|  |  |  | 	{"name", | 
					
						
							|  |  |  | 	 (getter)BPy_IDGroup_GetName, (setter)BPy_IDGroup_SetName, | 
					
						
							|  |  |  | 	 "The name of this Group.", | 
					
						
							|  |  |  | 	 NULL}, | 
					
						
							|  |  |  | 	 {NULL, NULL, NULL, NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 	  | 
					
						
							|  |  |  | int BPy_IDGroup_Map_Len(BPy_IDProperty *self) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (self->prop->type != IDP_GROUP) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 			"len() of unsized object"); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	return self->prop->len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	IDProperty *loop; | 
					
						
							|  |  |  | 	char *st; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (self->prop->type  != IDP_GROUP) | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_TypeError, | 
					
						
							|  |  |  | 			"unsubscriptable object"); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	if (!PyString_Check(item))  | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_TypeError, | 
					
						
							|  |  |  | 			"only strings are allowed as keys of ID properties"); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	st = PyString_AsString(item); | 
					
						
							|  |  |  | 	for (loop=self->prop->data.group.first; loop; loop=loop->next) { | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		if (BSTR_EQ(loop->name, st)) return BPy_IDGroup_WrapData(self->id, loop); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return EXPP_ReturnPyObjError( PyExc_KeyError, | 
					
						
							|  |  |  | 		"key not in subgroup dict"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*returns NULL on success, error string on failure*/ | 
					
						
							|  |  |  | char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObject *ob) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-22 04:41:21 +00:00
										 |  |  | 	IDProperty *prop = NULL; | 
					
						
							| 
									
										
										
										
											2007-03-01 21:30:48 +00:00
										 |  |  | 	IDPropertyTemplate val = {0}; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (PyFloat_Check(ob)) { | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 		val.d = PyFloat_AsDouble(ob); | 
					
						
							|  |  |  | 		prop = IDP_New(IDP_DOUBLE, val, name); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	} else if (PyInt_Check(ob)) { | 
					
						
							|  |  |  | 		val.i = (int) PyInt_AsLong(ob); | 
					
						
							|  |  |  | 		prop = IDP_New(IDP_INT, val, name); | 
					
						
							|  |  |  | 	} else if (PyString_Check(ob)) { | 
					
						
							|  |  |  | 		val.str = PyString_AsString(ob); | 
					
						
							|  |  |  | 		prop = IDP_New(IDP_STRING, val, name); | 
					
						
							|  |  |  | 	} else if (PySequence_Check(ob)) { | 
					
						
							|  |  |  | 		PyObject *item; | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*validate sequence and derive type.
 | 
					
						
							|  |  |  | 		we assume IDP_INT unless we hit a float | 
					
						
							|  |  |  | 		number; then we assume it's */ | 
					
						
							|  |  |  | 		val.array.type = IDP_INT; | 
					
						
							|  |  |  | 		val.array.len = PySequence_Length(ob); | 
					
						
							|  |  |  | 		for (i=0; i<val.array.len; i++) { | 
					
						
							|  |  |  | 			item = PySequence_GetItem(ob, i); | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 			if (PyFloat_Check(item)) val.array.type = IDP_DOUBLE; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 			else if (!PyInt_Check(item)) return "only floats and ints are allowed in ID property arrays"; | 
					
						
							|  |  |  | 			Py_XDECREF(item); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		prop = IDP_New(IDP_ARRAY, val, name); | 
					
						
							|  |  |  | 		for (i=0; i<val.array.len; i++) { | 
					
						
							|  |  |  | 			item = PySequence_GetItem(ob, i); | 
					
						
							|  |  |  | 			if (val.array.type == IDP_INT) { | 
					
						
							|  |  |  | 				item = PyNumber_Int(item); | 
					
						
							|  |  |  | 				((int*)prop->data.pointer)[i] = (int)PyInt_AsLong(item); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				item = PyNumber_Float(item); | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 				((double*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			Py_XDECREF(item); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if (PyMapping_Check(ob)) { | 
					
						
							|  |  |  | 		PyObject *keys, *vals, *key, *pval; | 
					
						
							|  |  |  | 		int i, len; | 
					
						
							|  |  |  | 		/*yay! we get into recursive stuff now!*/ | 
					
						
							|  |  |  | 		keys = PyMapping_Keys(ob); | 
					
						
							|  |  |  | 		vals = PyMapping_Values(ob); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*we allocate the group first; if we hit any invalid data,
 | 
					
						
							|  |  |  | 		  we can delete it easily enough.*/ | 
					
						
							|  |  |  | 		prop = IDP_New(IDP_GROUP, val, name); | 
					
						
							|  |  |  | 		len = PyMapping_Length(ob); | 
					
						
							|  |  |  | 		for (i=0; i<len; i++) { | 
					
						
							|  |  |  | 			key = PySequence_GetItem(keys, i); | 
					
						
							|  |  |  | 			pval = PySequence_GetItem(vals, i); | 
					
						
							|  |  |  | 			if (!PyString_Check(key)) { | 
					
						
							|  |  |  | 				IDP_FreeProperty(prop); | 
					
						
							|  |  |  | 				MEM_freeN(prop); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 				Py_XDECREF(keys); | 
					
						
							|  |  |  | 				Py_XDECREF(vals); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 				Py_XDECREF(key); | 
					
						
							|  |  |  | 				Py_XDECREF(pval); | 
					
						
							|  |  |  | 				return "invalid element in subgroup dict template!"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (BPy_IDProperty_Map_ValidateAndCreate(PyString_AsString(key), prop, pval)) { | 
					
						
							|  |  |  | 				IDP_FreeProperty(prop); | 
					
						
							|  |  |  | 				MEM_freeN(prop); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 				Py_XDECREF(keys); | 
					
						
							|  |  |  | 				Py_XDECREF(vals); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 				Py_XDECREF(key); | 
					
						
							|  |  |  | 				Py_XDECREF(pval); | 
					
						
							|  |  |  | 				return "invalid element in subgroup dict template!"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			Py_XDECREF(key); | 
					
						
							|  |  |  | 			Py_XDECREF(pval); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_XDECREF(keys); | 
					
						
							|  |  |  | 		Py_XDECREF(vals); | 
					
						
							| 
									
										
										
										
											2006-12-01 03:04:36 +00:00
										 |  |  | 	} else return "invalid property value"; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2007-05-22 04:41:21 +00:00
										 |  |  | 	IDP_ReplaceInGroup(group, prop); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | int BPy_IDGroup_Map_SetItem(BPy_IDProperty *self, PyObject *key, PyObject *val) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *err; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (self->prop->type  != IDP_GROUP) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 			"unsubscriptable object"); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	if (!PyString_Check(key)) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 		   "only strings are allowed as subgroup keys" ); | 
					
						
							| 
									
										
										
										
											2006-12-01 03:04:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (val == NULL) { | 
					
						
							|  |  |  | 		IDProperty *pkey = IDP_GetPropertyFromGroup(self->prop, PyString_AsString(key)); | 
					
						
							|  |  |  | 		if (pkey) { | 
					
						
							|  |  |  | 			IDP_RemFromGroup(self->prop, pkey); | 
					
						
							|  |  |  | 			IDP_FreeProperty(pkey); | 
					
						
							|  |  |  | 			MEM_freeN(pkey); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} else return EXPP_ReturnIntError( PyExc_RuntimeError, "property not found in group" ); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	err = BPy_IDProperty_Map_ValidateAndCreate(PyString_AsString(key), self->prop, val); | 
					
						
							|  |  |  | 	if (err) return EXPP_ReturnIntError( PyExc_RuntimeError, err ); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | PyObject *BPy_IDGroup_SpawnIterator(BPy_IDProperty *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &IDGroup_Iter_Type); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (!iter) | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 		   "PyObject_New() failed" ); | 
					
						
							|  |  |  | 	iter->group = self; | 
					
						
							|  |  |  | 	iter->mode = IDPROP_ITER_KEYS; | 
					
						
							|  |  |  | 	iter->cur = self->prop->data.group.first; | 
					
						
							|  |  |  | 	Py_XINCREF(iter); | 
					
						
							|  |  |  | 	return (PyObject*) iter; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (prop->type) { | 
					
						
							|  |  |  | 		case IDP_STRING: | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyString_FromString(prop->data.pointer); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case IDP_FLOAT: | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyFloat_FromDouble(*((float*)&prop->data.val)); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 		case IDP_DOUBLE: | 
					
						
							|  |  |  | 			return PyFloat_FromDouble(*((double*)&prop->data.val)); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		case IDP_INT: | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyInt_FromLong( (long)prop->data.val ); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case IDP_ARRAY: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			PyObject *seq = PyList_New(prop->len); | 
					
						
							|  |  |  | 			int i; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if (!seq)  | 
					
						
							|  |  |  | 				return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 					   "PyList_New() failed" ); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			for (i=0; i<prop->len; i++) { | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 				if (prop->subtype == IDP_FLOAT) { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 						PyList_SetItem(seq, i, | 
					
						
							|  |  |  | 						PyFloat_FromDouble(((float*)prop->data.pointer)[i])); | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 				} else if (prop->subtype == IDP_DOUBLE) { | 
					
						
							|  |  |  | 						PyList_SetItem(seq, i, | 
					
						
							|  |  |  | 						PyFloat_FromDouble(((double*)prop->data.pointer)[i]));				 | 
					
						
							|  |  |  | 				} else 	{ PyList_SetItem(seq, i, | 
					
						
							|  |  |  | 						  PyInt_FromLong(((int*)prop->data.pointer)[i])); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return seq; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case IDP_GROUP: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			PyObject *dict = PyDict_New(), *wrap; | 
					
						
							|  |  |  | 			IDProperty *loop; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if (!dict) | 
					
						
							|  |  |  | 				return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 					   "PyDict_New() failed" ); | 
					
						
							|  |  |  | 					    | 
					
						
							|  |  |  | 			for (loop=prop->data.group.first; loop; loop=loop->next) { | 
					
						
							|  |  |  | 				wrap = BPy_IDGroup_MapDataToPy(loop); | 
					
						
							|  |  |  | 				if (!wrap)  | 
					
						
							|  |  |  | 					return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 					   "BPy_IDGroup_MapDataToPy() failed" ); | 
					
						
							|  |  |  | 					    | 
					
						
							|  |  |  | 				PyDict_SetItemString(dict, loop->name, wrap); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return dict; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 					   "eek!! a property exists with a bad type code!!!" ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-16 12:24:41 +00:00
										 |  |  | PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value) | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	IDProperty *loop; | 
					
						
							|  |  |  | 	PyObject *pyform; | 
					
						
							| 
									
										
										
										
											2007-06-16 12:24:41 +00:00
										 |  |  | 	char *name = PyString_AsString(value); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2007-06-16 12:24:41 +00:00
										 |  |  | 	if (!name) { | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		return EXPP_ReturnPyObjError( PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2008-01-23 15:51:25 +00:00
										 |  |  | 		   "pop expected at least 1 argument, got 0" ); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (loop=self->prop->data.group.first; loop; loop=loop->next) { | 
					
						
							|  |  |  | 		if (BSTR_EQ(loop->name, name)) { | 
					
						
							|  |  |  | 			pyform = BPy_IDGroup_MapDataToPy(loop); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if (!pyform) | 
					
						
							|  |  |  | 				/*ok something bad happened with the pyobject,
 | 
					
						
							|  |  |  | 				  so don't remove the prop from the group.  if pyform is | 
					
						
							|  |  |  | 				  NULL, then it already should have raised an exception.*/ | 
					
						
							|  |  |  | 				  return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			IDP_RemFromGroup(self->prop, loop); | 
					
						
							|  |  |  | 			return pyform; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return EXPP_ReturnPyObjError( PyExc_KeyError, | 
					
						
							|  |  |  | 		   "item not in group" ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDGroup_IterItems(BPy_IDProperty *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &IDGroup_Iter_Type); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (!iter) | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 		   "PyObject_New() failed" ); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	iter->group = self; | 
					
						
							|  |  |  | 	iter->mode = IDPROP_ITER_ITEMS; | 
					
						
							|  |  |  | 	iter->cur = self->prop->data.group.first; | 
					
						
							|  |  |  | 	Py_XINCREF(iter); | 
					
						
							|  |  |  | 	return (PyObject*) iter; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	PyObject *seq = PyList_New(self->prop->len); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	IDProperty *loop; | 
					
						
							| 
									
										
										
										
											2008-02-23 02:12:50 +00:00
										 |  |  | 	int i, j; | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!seq)  | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 		   "PyList_New() failed" ); | 
					
						
							|  |  |  | 		    | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++) | 
					
						
							|  |  |  | 		PyList_SetItem(seq, i, PyString_FromString(loop->name)); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-02-23 02:12:50 +00:00
										 |  |  | 	if (i != self->prop->len) { | 
					
						
							|  |  |  | 		printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys!\n"); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*fill rest of list with valid references to None*/ | 
					
						
							|  |  |  | 		for (j=i; j<self->prop->len; j++) { | 
					
						
							|  |  |  | 			Py_INCREF(Py_None); | 
					
						
							|  |  |  | 			PyList_SetItem(seq, j, Py_None); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*set correct group length*/ | 
					
						
							|  |  |  | 		self->prop->len = i; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 		/*free the list*/ | 
					
						
							| 
									
										
										
										
											2008-02-23 02:12:50 +00:00
										 |  |  | 		Py_DECREF(seq); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*call self again*/ | 
					
						
							|  |  |  | 		return BPy_IDGroup_GetKeys(self);		 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	return seq; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *seq = PyList_New(self->prop->len); | 
					
						
							|  |  |  | 	IDProperty *loop; | 
					
						
							| 
									
										
										
										
											2008-02-23 02:12:50 +00:00
										 |  |  | 	int i, j; | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!seq)  | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 		   "PyList_New() failed" ); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++) { | 
					
						
							|  |  |  | 		PyList_SetItem(seq, i, BPy_IDGroup_WrapData(self->id, loop)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-02-23 02:12:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (i != self->prop->len) { | 
					
						
							|  |  |  | 		printf("ID Property Error found and corrected in BPy_IDGroup_GetValues!\n"); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*fill rest of list with valid references to None*/ | 
					
						
							|  |  |  | 		for (j=i; j<self->prop->len; j++) { | 
					
						
							|  |  |  | 			Py_INCREF(Py_None); | 
					
						
							|  |  |  | 			PyList_SetItem(seq, j, Py_None); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*set correct group length*/ | 
					
						
							|  |  |  | 		self->prop->len = i; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*free the old list*/ | 
					
						
							|  |  |  | 		Py_DECREF(seq); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/*call self again*/ | 
					
						
							|  |  |  | 		return BPy_IDGroup_GetValues(self);		 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	return seq; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-16 12:24:41 +00:00
										 |  |  | PyObject *BPy_IDGroup_HasKey(BPy_IDProperty *self, PyObject *value) | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	IDProperty *loop; | 
					
						
							| 
									
										
										
										
											2007-06-16 12:24:41 +00:00
										 |  |  | 	char *name = PyString_AsString(value); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2007-06-16 12:24:41 +00:00
										 |  |  | 	if (!name) | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		return EXPP_ReturnPyObjError( PyExc_TypeError, | 
					
						
							|  |  |  | 		   "expected a string"); | 
					
						
							|  |  |  | 		    | 
					
						
							|  |  |  | 	for (loop=self->prop->data.group.first; loop; loop=loop->next) { | 
					
						
							|  |  |  | 		if (BSTR_EQ(loop->name, name)) Py_RETURN_TRUE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Py_RETURN_FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDGroup_Update(BPy_IDProperty *self, PyObject *vars) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *pyob, *pkey, *pval; | 
					
						
							| 
									
										
										
										
											2008-04-17 21:14:55 +00:00
										 |  |  | 	Py_ssize_t i=0; | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (PySequence_Size(vars) != 1) | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_TypeError, | 
					
						
							|  |  |  | 		   "expected an object derived from dict."); | 
					
						
							|  |  |  | 	   | 
					
						
							|  |  |  | 	pyob = PyTuple_GET_ITEM(vars, 0); | 
					
						
							|  |  |  | 	if (!PyDict_Check(pyob)) | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_TypeError, | 
					
						
							|  |  |  | 		   "expected an object derived from dict."); | 
					
						
							|  |  |  | 		    | 
					
						
							|  |  |  | 	while (PyDict_Next(pyob, &i, &pkey, &pval)) { | 
					
						
							|  |  |  | 		BPy_IDGroup_Map_SetItem(self, pkey, pval); | 
					
						
							|  |  |  | 		if (PyErr_Occurred()) return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDGroup_ConvertToPy(BPy_IDProperty *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return BPy_IDGroup_MapDataToPy(self->prop); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef BPy_IDGroup_methods[] = { | 
					
						
							| 
									
										
										
										
											2007-06-16 12:24:41 +00:00
										 |  |  | 	{"pop", (PyCFunction)BPy_IDGroup_Pop, METH_O, | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		"pop an item from the group; raises KeyError if the item doesn't exist."}, | 
					
						
							|  |  |  | 	{"iteritems", (PyCFunction)BPy_IDGroup_IterItems, METH_NOARGS, | 
					
						
							|  |  |  | 		"iterate through the items in the dict; behaves like dictionary method iteritems."}, | 
					
						
							|  |  |  | 	{"keys", (PyCFunction)BPy_IDGroup_GetKeys, METH_NOARGS, | 
					
						
							|  |  |  | 		"get the keys associated with this group as a list of strings."}, | 
					
						
							|  |  |  | 	{"values", (PyCFunction)BPy_IDGroup_GetValues, METH_NOARGS, | 
					
						
							|  |  |  | 		"get the values associated with this group."}, | 
					
						
							| 
									
										
										
										
											2007-06-16 12:24:41 +00:00
										 |  |  | 	{"has_key", (PyCFunction)BPy_IDGroup_HasKey, METH_O, | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		"returns true if the group contains a key, false if not."}, | 
					
						
							|  |  |  | 	{"update", (PyCFunction)BPy_IDGroup_Update, METH_VARARGS, | 
					
						
							|  |  |  | 		"updates the values in the group with the values of another or a dict."}, | 
					
						
							|  |  |  | 	{"convert_to_pyobject", (PyCFunction)BPy_IDGroup_ConvertToPy, METH_NOARGS, | 
					
						
							|  |  |  | 		"return a purely python version of the group."}, | 
					
						
							|  |  |  | 	{0, NULL, 0, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | PyMappingMethods BPy_IDGroup_Mapping = { | 
					
						
							|  |  |  | 	(inquiry)BPy_IDGroup_Map_Len, 			/*inquiry mp_length */ | 
					
						
							|  |  |  | 	(binaryfunc)BPy_IDGroup_Map_GetItem,		/*binaryfunc mp_subscript */ | 
					
						
							|  |  |  | 	(objobjargproc)BPy_IDGroup_Map_SetItem,	/*objobjargproc mp_ass_subscript */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | PyTypeObject IDGroup_Type = { | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	PyObject_HEAD_INIT( NULL )  /* required py macro */ | 
					
						
							|  |  |  | 	0,                          /* ob_size */ | 
					
						
							|  |  |  | 	/*  For printing, in format "<module>.<name>" */ | 
					
						
							|  |  |  | 	"Blender IDProperty",           /* char *tp_name; */ | 
					
						
							|  |  |  | 	sizeof( BPy_IDProperty ),       /* int tp_basicsize; */ | 
					
						
							|  |  |  | 	0,                          /* tp_itemsize;  For allocation */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Methods to implement standard operations */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-15 01:47:53 +00:00
										 |  |  | 	NULL,						/* destructor tp_dealloc; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	NULL,                       /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	NULL,     /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  | 	NULL,     /* setattrfunc tp_setattr; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	NULL,                       /* cmpfunc tp_compare; */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	( reprfunc ) IDGroup_repr,     /* reprfunc tp_repr; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Method suites for standard classes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NULL,                       /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  | 	NULL,	        			/* PySequenceMethods *tp_as_sequence; */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	&BPy_IDGroup_Mapping,     /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* More standard operations (here for binary compatibility) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NULL,                       /* hashfunc tp_hash; */ | 
					
						
							|  |  |  | 	NULL,                       /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  | 	NULL,                       /* reprfunc tp_str; */ | 
					
						
							|  |  |  | 	NULL,                       /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  | 	NULL,                       /* setattrofunc tp_setattro; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  | 	NULL,                       /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT,         /* long tp_flags; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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 ***/ | 
					
						
							|  |  |  | 	NULL,                       /* richcmpfunc tp_richcompare; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /***  weak reference enabler ***/ | 
					
						
							|  |  |  | 	0,                          /* long tp_weaklistoffset; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  | 	/*   Iterators */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	(getiterfunc)BPy_IDGroup_SpawnIterator, /* getiterfunc tp_iter; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	NULL,                       /* iternextfunc tp_iternext; */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  |   /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							|  |  |  | 	BPy_IDGroup_methods,        /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  | 	NULL,                       /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  | 	BPy_IDGroup_getseters,       /* struct PyGetSetDef *tp_getset; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | /*********** Main external wrapping function *******/ | 
					
						
							| 
									
										
										
										
											2006-11-19 16:00:04 +00:00
										 |  |  | PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	BPy_IDProperty *wrap = PyObject_New(BPy_IDProperty, &IDGroup_Type); | 
					
						
							| 
									
										
										
										
											2006-12-04 04:51:32 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (!wrap) | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 		   "PyObject_New() failed" ); | 
					
						
							|  |  |  | 						    | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	wrap->prop = prop; | 
					
						
							| 
									
										
										
										
											2006-11-19 16:00:04 +00:00
										 |  |  | 	wrap->parent = parent; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	wrap->id = id; | 
					
						
							|  |  |  | 	//wrap->destroy = 0;
 | 
					
						
							|  |  |  | 	return (PyObject*) wrap; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********Array Wrapper********/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *IDArray_repr(BPy_IDArray *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	return PyString_FromString("(ID Array)"); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDArray_GetType(BPy_IDArray *self) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	return PyInt_FromLong( (long)self->prop->subtype ); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | PyObject *BPy_IDArray_GetLen(BPy_IDArray *self) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	return PyInt_FromLong( (long)self->prop->len ); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | static PyGetSetDef BPy_IDArray_getseters[] = { | 
					
						
							|  |  |  | 	{"len", | 
					
						
							|  |  |  | 	 (getter)BPy_IDArray_GetLen, (setter)NULL, | 
					
						
							|  |  |  | 	 "The length of the array, can also be gotten with len(array).", | 
					
						
							|  |  |  | 	 NULL}, | 
					
						
							|  |  |  | 	{"type", | 
					
						
							|  |  |  | 	 (getter)BPy_IDArray_GetType, (setter)NULL, | 
					
						
							|  |  |  | 	 "The type of the data in the array, is an ant.", | 
					
						
							|  |  |  | 	 NULL},	 | 
					
						
							|  |  |  | 	{NULL, NULL, NULL, NULL, NULL}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | int BPy_IDArray_Len(BPy_IDArray *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return self->prop->len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (index < 0 || index >= self->prop->len) | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_IndexError, | 
					
						
							|  |  |  | 				"index out of range!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (self->prop->subtype) { | 
					
						
							|  |  |  | 		case IDP_FLOAT: | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyFloat_FromDouble( (double)(((float*)self->prop->data.pointer)[index])); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 		case IDP_DOUBLE: | 
					
						
							|  |  |  | 			return PyFloat_FromDouble( (((double*)self->prop->data.pointer)[index])); | 
					
						
							|  |  |  | 			break;		 | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 		case IDP_INT: | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyInt_FromLong( (long)((int*)self->prop->data.pointer)[index] ); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 				"invalid/corrupt array type!"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	float f; | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 	double d; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	if (index < 0 || index >= self->prop->len) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_RuntimeError, | 
					
						
							|  |  |  | 				"index out of range!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (self->prop->subtype) { | 
					
						
							|  |  |  | 		case IDP_FLOAT: | 
					
						
							|  |  |  | 			if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 				"expected a float"); | 
					
						
							|  |  |  | 			val = PyNumber_Float(val); | 
					
						
							|  |  |  | 			if (!val) return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 				"expected a float"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			f = (float) PyFloat_AsDouble(val); | 
					
						
							|  |  |  | 			((float*)self->prop->data.pointer)[index] = f; | 
					
						
							|  |  |  | 			Py_XDECREF(val); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2008-07-24 19:22:17 +00:00
										 |  |  | 		case IDP_DOUBLE: | 
					
						
							|  |  |  | 			if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 				"expected a float"); | 
					
						
							|  |  |  | 			val = PyNumber_Float(val); | 
					
						
							|  |  |  | 			if (!val) return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 				"expected a float"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			d = (double) PyFloat_AsDouble(val); | 
					
						
							|  |  |  | 			((double*)self->prop->data.pointer)[index] = d; | 
					
						
							|  |  |  | 			Py_XDECREF(val); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 		case IDP_INT: | 
					
						
							|  |  |  | 			if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 				"expected an int"); | 
					
						
							|  |  |  | 			val = PyNumber_Int(val); | 
					
						
							|  |  |  | 			if (!val) return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 				"expected an int"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			i = (int) PyInt_AsLong(val); | 
					
						
							|  |  |  | 			((int*)self->prop->data.pointer)[index] = i; | 
					
						
							|  |  |  | 			Py_XDECREF(val); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PySequenceMethods BPy_IDArray_Seq = { | 
					
						
							|  |  |  | 	(inquiry) BPy_IDArray_Len,			/* inquiry sq_length */ | 
					
						
							|  |  |  | 	0,									/* binaryfunc sq_concat */ | 
					
						
							|  |  |  | 	0,									/* intargfunc sq_repeat */ | 
					
						
							|  |  |  | 	(intargfunc)BPy_IDArray_GetItem,	/* intargfunc sq_item */ | 
					
						
							|  |  |  | 	0,									/* intintargfunc sq_slice */ | 
					
						
							|  |  |  | 	(intobjargproc)BPy_IDArray_SetItem,	/* intobjargproc sq_ass_item */ | 
					
						
							|  |  |  | 	0,									/* intintobjargproc sq_ass_slice */ | 
					
						
							|  |  |  | 	0,									/* objobjproc sq_contains */ | 
					
						
							|  |  |  | 				/* Added in release 2.0 */ | 
					
						
							|  |  |  | 	0,									/* binaryfunc sq_inplace_concat */ | 
					
						
							|  |  |  | 	0,									/* intargfunc sq_inplace_repeat */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyTypeObject IDArray_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT( NULL )  /* required py macro */ | 
					
						
							|  |  |  | 	0,                          /* ob_size */ | 
					
						
							|  |  |  | 	/*  For printing, in format "<module>.<name>" */ | 
					
						
							|  |  |  | 	"Blender IDArray",           /* char *tp_name; */ | 
					
						
							|  |  |  | 	sizeof( BPy_IDArray ),       /* int tp_basicsize; */ | 
					
						
							|  |  |  | 	0,                          /* tp_itemsize;  For allocation */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Methods to implement standard operations */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-15 01:47:53 +00:00
										 |  |  | 	NULL,						/* destructor tp_dealloc; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	NULL,                       /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	NULL,     /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  | 	NULL,     /* setattrfunc tp_setattr; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	NULL,                       /* cmpfunc tp_compare; */ | 
					
						
							|  |  |  | 	( reprfunc ) IDArray_repr,     /* reprfunc tp_repr; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Method suites for standard classes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NULL,                       /* PyNumberMethods *tp_as_number; */ | 
					
						
							|  |  |  | 	&BPy_IDArray_Seq,   			/* PySequenceMethods *tp_as_sequence; */ | 
					
						
							|  |  |  | 	NULL,                       /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* More standard operations (here for binary compatibility) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NULL,                       /* hashfunc tp_hash; */ | 
					
						
							|  |  |  | 	NULL,                       /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  | 	NULL,                       /* reprfunc tp_str; */ | 
					
						
							|  |  |  | 	NULL,                       /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  | 	NULL,                       /* setattrofunc tp_setattro; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  | 	NULL,                       /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT,         /* long tp_flags; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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 ***/ | 
					
						
							|  |  |  | 	NULL,                       /* richcmpfunc tp_richcompare; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /***  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 ***/ | 
					
						
							|  |  |  | 	NULL,                       /* struct PyMethodDef *tp_methods; */ | 
					
						
							|  |  |  | 	NULL,                       /* struct PyMemberDef *tp_members; */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	BPy_IDArray_getseters,       /* struct PyGetSetDef *tp_getset; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	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; */ | 
					
						
							|  |  |  | 	NULL,                       /* newfunc tp_new; */ | 
					
						
							|  |  |  | 	/*  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 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********** ID Property Group iterator ********/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | PyObject *IDGroup_Iter_iterself(PyObject *self) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	Py_XINCREF(self); | 
					
						
							|  |  |  | 	return self; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | PyObject *IDGroup_Iter_repr(BPy_IDGroup_Iter *self) | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	return PyString_FromString("(ID Property Group)"); | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	IDProperty *cur=NULL; | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 	PyObject *tmpval; | 
					
						
							|  |  |  | 	PyObject *ret; | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (self->cur) { | 
					
						
							|  |  |  | 		cur = self->cur; | 
					
						
							|  |  |  | 		self->cur = self->cur->next; | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		if (self->mode == IDPROP_ITER_ITEMS) { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			tmpval = BPy_IDGroup_WrapData(self->group->id, cur); | 
					
						
							|  |  |  | 			ret = Py_BuildValue("[s, O]", cur->name, tmpval); | 
					
						
							|  |  |  | 			Py_DECREF(tmpval); | 
					
						
							|  |  |  | 			return ret; | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2007-05-26 04:39:31 +00:00
										 |  |  | 			return PyString_FromString(cur->name); | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError( PyExc_StopIteration, | 
					
						
							|  |  |  | 				"iterator at end" ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyTypeObject IDGroup_Iter_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT( NULL )  /* required py macro */ | 
					
						
							|  |  |  | 	0,                          /* ob_size */ | 
					
						
							|  |  |  | 	/*  For printing, in format "<module>.<name>" */ | 
					
						
							|  |  |  | 	"Blender IDGroup_Iter",           /* char *tp_name; */ | 
					
						
							|  |  |  | 	sizeof( BPy_IDGroup_Iter ),       /* int tp_basicsize; */ | 
					
						
							|  |  |  | 	0,                          /* tp_itemsize;  For allocation */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Methods to implement standard operations */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-15 01:47:53 +00:00
										 |  |  | 	NULL,						/* destructor tp_dealloc; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	NULL,                       /* printfunc tp_print; */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	NULL,     /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  | 	NULL,     /* setattrfunc tp_setattr; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	NULL,                       /* cmpfunc tp_compare; */ | 
					
						
							|  |  |  | 	( reprfunc ) IDGroup_Iter_repr,     /* reprfunc 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) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NULL,                       /* hashfunc tp_hash; */ | 
					
						
							|  |  |  | 	NULL,                       /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  | 	NULL,                       /* reprfunc tp_str; */ | 
					
						
							|  |  |  | 	NULL,                       /* getattrofunc tp_getattro; */ | 
					
						
							|  |  |  | 	NULL,                       /* setattrofunc tp_setattro; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Functions to access object as input/output buffer */ | 
					
						
							|  |  |  | 	NULL,                       /* PyBufferProcs *tp_as_buffer; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*** Flags to define presence of optional/expanded features ***/ | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT,         /* long tp_flags; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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 ***/ | 
					
						
							|  |  |  | 	NULL,                       /* richcmpfunc tp_richcompare; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /***  weak reference enabler ***/ | 
					
						
							|  |  |  | 	0,                          /* long tp_weaklistoffset; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  | 	/*   Iterators */ | 
					
						
							| 
									
										
										
										
											2006-12-16 23:54:45 +00:00
										 |  |  | 	IDGroup_Iter_iterself,              /* getiterfunc tp_iter; */ | 
					
						
							| 
									
										
										
										
											2006-11-17 04:46:48 +00:00
										 |  |  | 	(iternextfunc) BPy_Group_Iter_Next, /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-29 23:31:46 +00:00
										 |  |  | void IDProp_Init_Types(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyType_Ready( &IDGroup_Type ); | 
					
						
							|  |  |  | 	PyType_Ready( &IDGroup_Iter_Type ); | 
					
						
							|  |  |  | 	PyType_Ready( &IDArray_Type ); | 
					
						
							|  |  |  | } |