| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2010-03-21 01:14:04 +00:00
										 |  |  |  * $Id$ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  |  * The Original Code is: none of this file. | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Campbell Barton | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * Readonly sequence wrapper for lookups on logic bricks | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 13:35:59 +00:00
										 |  |  | /** \file gameengine/Ketsji/KX_PythonSeq.cpp
 | 
					
						
							|  |  |  |  *  \ingroup ketsji | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-31 04:11:39 +00:00
										 |  |  | #ifdef WITH_PYTHON
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "KX_PythonSeq.h"
 | 
					
						
							|  |  |  | #include "KX_GameObject.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-24 21:22:24 +00:00
										 |  |  | #include "BL_ArmatureObject.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | #include "SCA_ISensor.h"
 | 
					
						
							|  |  |  | #include "SCA_IController.h"
 | 
					
						
							|  |  |  | #include "SCA_IActuator.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *KX_PythonSeq_CreatePyObject( PyObject *base, short type ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	KX_PythonSeq *seq = PyObject_NEW( KX_PythonSeq, &KX_PythonSeq_Type); | 
					
						
							|  |  |  | 	seq->base = base; | 
					
						
							|  |  |  | 	Py_INCREF(base); /* so we can always access to check if its valid */ | 
					
						
							|  |  |  | 	seq->type = type; | 
					
						
							|  |  |  | 	seq->iter = -1; /* init */ | 
					
						
							|  |  |  | 	return (PyObject *)seq; | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |  static void KX_PythonSeq_dealloc( KX_PythonSeq * self ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Py_DECREF(self->base); | 
					
						
							|  |  |  | 	PyObject_DEL( self ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | static Py_ssize_t KX_PythonSeq_len( PyObject * self ) | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 	PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	  | 
					
						
							|  |  |  | 	if(self_plus==NULL) { | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 		PyErr_SetString(PyExc_SystemError, "len(seq): "BGE_PROXY_ERROR_MSG); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 	switch(((KX_PythonSeq *)self)->type) { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	case KX_PYGENSEQ_CONT_TYPE_SENSORS: | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 		return ((SCA_IController *)self_plus)->GetLinkedSensors().size(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 		return ((SCA_IController *)self_plus)->GetLinkedActuators().size(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	case KX_PYGENSEQ_OB_TYPE_SENSORS: | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 		return ((KX_GameObject *)self_plus)->GetSensors().size(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 		return ((KX_GameObject *)self_plus)->GetControllers().size(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	case KX_PYGENSEQ_OB_TYPE_ACTUATORS: | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 		return ((KX_GameObject *)self_plus)->GetActuators().size(); | 
					
						
							| 
									
										
										
										
											2009-09-24 21:22:24 +00:00
										 |  |  | 	case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS: | 
					
						
							|  |  |  | 		return ((BL_ArmatureObject *)self_plus)->GetConstraintNumber(); | 
					
						
							|  |  |  | 	case KX_PYGENSEQ_OB_TYPE_CHANNELS: | 
					
						
							|  |  |  | 		return ((BL_ArmatureObject *)self_plus)->GetChannelNumber(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		/* Should never happen */ | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_SystemError, "invalid type, internal error"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index) | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 	PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	  | 
					
						
							|  |  |  | 	if(self_plus==NULL) { | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 		PyErr_SetString(PyExc_SystemError, "val = seq[i]: "BGE_PROXY_ERROR_MSG); | 
					
						
							| 
									
										
										
										
											2009-05-10 15:23:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 	switch(((KX_PythonSeq *)self)->type) { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 		case KX_PYGENSEQ_CONT_TYPE_SENSORS: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-10 20:53:58 +00:00
										 |  |  | 			vector<SCA_ISensor*>& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			if(index<0) index += linkedsensors.size(); | 
					
						
							|  |  |  | 			if(index<0 || index>= linkedsensors.size()) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return linkedsensors[index]->GetProxy(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-10 20:53:58 +00:00
										 |  |  | 			vector<SCA_IActuator*>& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			if(index<0) index += linkedactuators.size(); | 
					
						
							|  |  |  | 			if(index<0 || index>= linkedactuators.size()) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return linkedactuators[index]->GetProxy(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_OB_TYPE_SENSORS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors(); | 
					
						
							|  |  |  | 			if(index<0) index += linkedsensors.size(); | 
					
						
							|  |  |  | 			if(index<0 || index>= linkedsensors.size()) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return linkedsensors[index]->GetProxy(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers(); | 
					
						
							|  |  |  | 			if(index<0) index += linkedcontrollers.size(); | 
					
						
							|  |  |  | 			if(index<0 || index>= linkedcontrollers.size()) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return linkedcontrollers[index]->GetProxy(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_OB_TYPE_ACTUATORS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators(); | 
					
						
							|  |  |  | 			if(index<0) index += linkedactuators.size(); | 
					
						
							|  |  |  | 			if(index<0 || index>= linkedactuators.size()) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return linkedactuators[index]->GetProxy(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-09-24 21:22:24 +00:00
										 |  |  | 		case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			int nb_constraint = ((BL_ArmatureObject *)self_plus)->GetConstraintNumber(); | 
					
						
							|  |  |  | 			if(index<0)  | 
					
						
							|  |  |  | 				index += nb_constraint; | 
					
						
							|  |  |  | 			if(index<0 || index>= nb_constraint) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return ((BL_ArmatureObject *)self_plus)->GetConstraint(index)->GetProxy(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_OB_TYPE_CHANNELS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			int nb_channel = ((BL_ArmatureObject *)self_plus)->GetChannelNumber(); | 
					
						
							|  |  |  | 			if(index<0)  | 
					
						
							|  |  |  | 				index += nb_channel; | 
					
						
							|  |  |  | 			if(index<0 || index>= nb_channel) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return ((BL_ArmatureObject *)self_plus)->GetChannel(index)->GetProxy(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-10 15:23:18 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	PyErr_SetString(PyExc_SystemError, "invalid sequence type, this is a bug"); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | static PyObjectPlus * KX_PythonSeq_subscript__internal(PyObject *self, char *key) | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 	PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 	switch(((KX_PythonSeq *)self)->type) { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 		case KX_PYGENSEQ_CONT_TYPE_SENSORS: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-10 20:53:58 +00:00
										 |  |  | 			vector<SCA_ISensor*>& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			SCA_ISensor* sensor; | 
					
						
							|  |  |  | 			for (unsigned int index=0;index<linkedsensors.size();index++) { | 
					
						
							|  |  |  | 				sensor = linkedsensors[index]; | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 				if (sensor->GetName() == key) | 
					
						
							|  |  |  | 					return static_cast<PyObjectPlus *>(sensor); | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-10 20:53:58 +00:00
										 |  |  | 			vector<SCA_IActuator*>& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); | 
					
						
							| 
									
										
										
										
											2009-05-10 15:23:18 +00:00
										 |  |  | 			SCA_IActuator* actuator; | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			for (unsigned int index=0;index<linkedactuators.size();index++) { | 
					
						
							| 
									
										
										
										
											2009-05-10 15:23:18 +00:00
										 |  |  | 				actuator = linkedactuators[index]; | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 				if (actuator->GetName() == key) | 
					
						
							|  |  |  | 					return static_cast<PyObjectPlus *>(actuator); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_OB_TYPE_SENSORS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors(); | 
					
						
							|  |  |  | 			SCA_ISensor *sensor; | 
					
						
							|  |  |  | 			for (unsigned int index=0;index<linkedsensors.size();index++) { | 
					
						
							|  |  |  | 				sensor= linkedsensors[index]; | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 				if (sensor->GetName() == key) | 
					
						
							|  |  |  | 					return static_cast<PyObjectPlus *>(sensor); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers(); | 
					
						
							|  |  |  | 			SCA_IController *controller; | 
					
						
							|  |  |  | 			for (unsigned int index=0;index<linkedcontrollers.size();index++) { | 
					
						
							|  |  |  | 				controller= linkedcontrollers[index]; | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 				if (controller->GetName() == key) | 
					
						
							|  |  |  | 					return static_cast<PyObjectPlus *>(controller); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_OB_TYPE_ACTUATORS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators(); | 
					
						
							|  |  |  | 			SCA_IActuator *actuator; | 
					
						
							|  |  |  | 			for (unsigned int index=0;index<linkedactuators.size();index++) { | 
					
						
							|  |  |  | 				actuator= linkedactuators[index]; | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 				if (actuator->GetName() == key) | 
					
						
							|  |  |  | 					return static_cast<PyObjectPlus *>(actuator); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-09-24 21:22:24 +00:00
										 |  |  | 		case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			return ((BL_ArmatureObject*)self_plus)->GetConstraint(key); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case KX_PYGENSEQ_OB_TYPE_CHANNELS: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			return ((BL_ArmatureObject*)self_plus)->GetChannel(key); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if(self_plus==NULL) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_SystemError, "val = seq[key], KX_PythonSeq: "BGE_PROXY_ERROR_MSG); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-06-29 02:25:54 +00:00
										 |  |  | 	if (PyLong_Check(key)) { | 
					
						
							|  |  |  | 		return KX_PythonSeq_getIndex(self, PyLong_AsSsize_t( key )); | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-29 02:25:54 +00:00
										 |  |  | 	else if ( PyUnicode_Check(key) ) { | 
					
						
							|  |  |  | 		char *name = _PyUnicode_AsString(key); | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 		PyObjectPlus *ret = KX_PythonSeq_subscript__internal(self, name); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if(ret) { | 
					
						
							|  |  |  | 			return ret->GetProxy(); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			PyErr_Format( PyExc_KeyError, "requested item \"%s\" does not exist", name); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		PyErr_SetString( PyExc_TypeError, "expected a string or an index" ); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int KX_PythonSeq_contains(PyObject *self, PyObject *key) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if(self_plus==NULL) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: "BGE_PROXY_ERROR_MSG); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-29 02:25:54 +00:00
										 |  |  | 	if(!PyUnicode_Check(key)) { | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 		PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: key must be a string"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-06-29 02:25:54 +00:00
										 |  |  | 	if(KX_PythonSeq_subscript__internal(self, _PyUnicode_AsString(key))) | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Matches python dict.get(key, [default]) */ | 
					
						
							|  |  |  | PyObject* KX_PythonSeq_get(PyObject * self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *key; | 
					
						
							|  |  |  | 	PyObject* def = Py_None; | 
					
						
							|  |  |  | 	PyObjectPlus* ret_plus; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if((ret_plus = KX_PythonSeq_subscript__internal(self, key))) | 
					
						
							|  |  |  | 		return ret_plus->GetProxy(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Py_INCREF(def); | 
					
						
							|  |  |  | 	return def; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PySequenceMethods KX_PythonSeq_as_sequence = { | 
					
						
							|  |  |  | 	NULL,		/* Cant set the len otherwise it can evaluate as false */ | 
					
						
							|  |  |  | 	NULL,		/* sq_concat */ | 
					
						
							|  |  |  | 	NULL,		/* sq_repeat */ | 
					
						
							|  |  |  | 	NULL,		/* sq_item */ | 
					
						
							|  |  |  | 	NULL,		/* sq_slice */ | 
					
						
							|  |  |  | 	NULL,		/* sq_ass_item */ | 
					
						
							|  |  |  | 	NULL,		/* sq_ass_slice */ | 
					
						
							|  |  |  | 	(objobjproc)KX_PythonSeq_contains,	/* sq_contains */ | 
					
						
							| 
									
										
										
										
											2010-05-16 10:09:07 +00:00
										 |  |  | 	(binaryfunc) NULL, /* sq_inplace_concat */ | 
					
						
							|  |  |  | 	(ssizeargfunc) NULL, /* sq_inplace_repeat */ | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | static PyMappingMethods KX_PythonSeq_as_mapping = { | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 	KX_PythonSeq_len,	/* mp_length */ | 
					
						
							|  |  |  | 	KX_PythonSeq_subscript,	/* mp_subscript */ | 
					
						
							| 
									
										
										
										
											2009-05-10 15:23:18 +00:00
										 |  |  | 	0,	/* mp_ass_subscript */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | PyMethodDef KX_PythonSeq_methods[] = { | 
					
						
							|  |  |  | 	// dict style access for props
 | 
					
						
							|  |  |  | 	{"get",(PyCFunction) KX_PythonSeq_get, METH_VARARGS}, | 
					
						
							|  |  |  | 	{NULL,NULL} //Sentinel
 | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Initialize the interator index | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | static PyObject *KX_PythonSeq_getIter(KX_PythonSeq *self) | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if(BGE_PROXY_REF(self->base)==NULL) { | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 		PyErr_SetString(PyExc_SystemError, "for i in seq: "BGE_PROXY_ERROR_MSG); | 
					
						
							| 
									
										
										
										
											2009-05-10 15:23:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-07-17 18:08:14 +00:00
										 |  |  | 	/* create a new iterator if were already using this one */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	if (self->iter == -1) { | 
					
						
							|  |  |  | 		self->iter = 0; | 
					
						
							|  |  |  | 		Py_INCREF(self); | 
					
						
							|  |  |  | 		return (PyObject *)self; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return KX_PythonSeq_CreatePyObject(self->base, self->type); | 
					
						
							|  |  |  |  	} | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Return next KX_PythonSeq iter. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | static PyObject *KX_PythonSeq_nextIter(KX_PythonSeq *self) | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 22:33:21 +00:00
										 |  |  | 	PyObject *object = KX_PythonSeq_getIndex((PyObject *)self, self->iter); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	self->iter++; | 
					
						
							|  |  |  | 	if( object==NULL ) { | 
					
						
							|  |  |  | 		self->iter= -1; /* for reuse */ | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_StopIteration,	"iterator at end"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return object; /* can be NULL for end of iterator */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | static int KX_PythonSeq_compare( KX_PythonSeq * a, KX_PythonSeq * b ) | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return ( a->type == b->type && a->base == b->base) ? 0 : -1;	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-02 20:46:28 +00:00
										 |  |  | static PyObject *KX_PythonSeq_richcmp(PyObject *a, PyObject *b, int op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 	PyObject *res; | 
					
						
							|  |  |  | 	int ok= -1; /* zero is true */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(BPy_KX_PythonSeq_Check(a) && BPy_KX_PythonSeq_Check(b)) | 
					
						
							|  |  |  | 		ok= KX_PythonSeq_compare((KX_PythonSeq *)a, (KX_PythonSeq *)b); | 
					
						
							| 
									
										
										
										
											2009-09-02 20:46:28 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 	switch (op) { | 
					
						
							|  |  |  | 	case Py_NE: | 
					
						
							|  |  |  | 		ok = !ok; /* pass through */ | 
					
						
							|  |  |  | 	case Py_EQ: | 
					
						
							|  |  |  | 		res = ok ? Py_False : Py_True; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case Py_LT: | 
					
						
							|  |  |  | 	case Py_LE: | 
					
						
							|  |  |  | 	case Py_GT: | 
					
						
							|  |  |  | 	case Py_GE: | 
					
						
							|  |  |  | 		res = Py_NotImplemented; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		PyErr_BadArgument(); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2009-09-02 20:46:28 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 	Py_INCREF(res); | 
					
						
							|  |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											2009-09-02 20:46:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-03 01:52:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * repr function | 
					
						
							|  |  |  |  * convert to a list and get its string value | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static PyObject *KX_PythonSeq_repr( KX_PythonSeq * self ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *list = PySequence_List((PyObject *)self); | 
					
						
							|  |  |  | 	PyObject *repr = PyObject_Repr(list); | 
					
						
							|  |  |  | 	Py_DECREF(list); | 
					
						
							|  |  |  | 	return repr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Python KX_PythonSeq_Type structure definition:                               */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | PyTypeObject KX_PythonSeq_Type = { | 
					
						
							|  |  |  | 	PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  | 	/*  For printing, in format "<module>.<name>" */ | 
					
						
							|  |  |  | 	"KX_PythonSeq",           /* char *tp_name; */ | 
					
						
							|  |  |  | 	sizeof( KX_PythonSeq ),       /* int tp_basicsize; */ | 
					
						
							|  |  |  | 	0,                          /* tp_itemsize;  For allocation */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Methods to implement standard operations */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	( destructor ) KX_PythonSeq_dealloc, /* destructor tp_dealloc; */ | 
					
						
							|  |  |  | 	NULL,                       /* printfunc tp_print; */ | 
					
						
							|  |  |  | 	NULL,                       /* getattrfunc tp_getattr; */ | 
					
						
							|  |  |  | 	NULL,                       /* setattrfunc tp_setattr; */ | 
					
						
							| 
									
										
										
										
											2009-09-02 20:46:28 +00:00
										 |  |  | 	NULL,						/* cmpfunc tp_compare; */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	( reprfunc ) KX_PythonSeq_repr,   /* reprfunc tp_repr; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Method suites for standard classes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NULL,                       /* PyNumberMethods *tp_as_number; */ | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 	&KX_PythonSeq_as_sequence,	    /* PySequenceMethods *tp_as_sequence; */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	&KX_PythonSeq_as_mapping,                       /* PyMappingMethods *tp_as_mapping; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* More standard operations (here for binary compatibility) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NULL,                       /* hashfunc tp_hash; */ | 
					
						
							|  |  |  | 	NULL,                       /* ternaryfunc tp_call; */ | 
					
						
							|  |  |  | 	NULL,                       /* reprfunc tp_str; */ | 
					
						
							|  |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2009-09-02 20:46:28 +00:00
										 |  |  | 	NULL,						/* traverseproc tp_traverse; */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* delete references to contained objects */ | 
					
						
							|  |  |  | 	NULL,                       /* inquiry tp_clear; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /***  Assigned meaning in release 2.1 ***/ | 
					
						
							|  |  |  |   /*** rich comparisons ***/ | 
					
						
							| 
									
										
										
										
											2009-09-02 20:46:28 +00:00
										 |  |  | 	(richcmpfunc)KX_PythonSeq_richcmp,	/* richcmpfunc tp_richcompare; */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /***  weak reference enabler ***/ | 
					
						
							|  |  |  | 	0,                          /* long tp_weaklistoffset; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*** Added in release 2.2 ***/ | 
					
						
							|  |  |  | 	/*   Iterators */ | 
					
						
							|  |  |  | 	( getiterfunc) KX_PythonSeq_getIter, /* getiterfunc tp_iter; */ | 
					
						
							|  |  |  | 	( iternextfunc ) KX_PythonSeq_nextIter, /* iternextfunc tp_iternext; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*** Attribute descriptor and subclassing stuff ***/ | 
					
						
							| 
									
										
										
										
											2009-06-16 08:52:04 +00:00
										 |  |  | 	KX_PythonSeq_methods,       /* struct PyMethodDef *tp_methods; */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:48:14 +00:00
										 |  |  | 	NULL,                       /* struct PyMemberDef *tp_members; */ | 
					
						
							|  |  |  | 	NULL,       /* struct PyGetSetDef *tp_getset; */ | 
					
						
							|  |  |  | 	NULL,                       /* struct _typeobject *tp_base; */ | 
					
						
							|  |  |  | 	NULL,                       /* PyObject *tp_dict; */ | 
					
						
							|  |  |  | 	NULL,                       /* descrgetfunc tp_descr_get; */ | 
					
						
							|  |  |  | 	NULL,                       /* descrsetfunc tp_descr_set; */ | 
					
						
							|  |  |  | 	0,                          /* long tp_dictoffset; */ | 
					
						
							|  |  |  | 	NULL,                       /* initproc tp_init; */ | 
					
						
							|  |  |  | 	NULL,                       /* allocfunc tp_alloc; */ | 
					
						
							|  |  |  | 	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 | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-09-29 21:42:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-31 04:11:39 +00:00
										 |  |  | #endif // WITH_PYTHON
 |