Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-05-10 05:48:14 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-05-10 05:48:14 +0400
commit136d4c34badc12b72f5c3541fcdaf2b1459af408 (patch)
tree2fc2952fb508234c74f9b1f1151dfea6dc242303 /source
parentf155da0039104af88379bb354674e32ef2595960 (diff)
deprecate controller.getActuator(name) and controller.getSensor(name) for
controller.actuators[name] and controller.sensors[name] Made a read-only sequence type for logic brick sensors and actuators which can access single items or be used like a list or dictionary. We could use a python dictionary or CValueList but that would be slower to create. So you can do... for s in controller.sensors: print s print controller.sensors["Sensor"] print controller.sensors[0] sensors = list(controller.sensors) This sequence type keeps a reference to the proxy it came from and will raise an error on access if the proxy has been removed.
Diffstat (limited to 'source')
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp1
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp30
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp28
-rw-r--r--source/gameengine/Ketsji/KX_PythonSeq.cpp384
-rw-r--r--source/gameengine/Ketsji/KX_PythonSeq.h60
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py6
-rw-r--r--source/gameengine/PyDoc/SCA_IController.py8
7 files changed, 465 insertions, 52 deletions
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index 7d302246c70..7026db5b8a4 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -981,6 +981,5 @@ void PyObjectPlus::SetDeprecationWarningFirst(WarnLink* wlink) {m_base_wlink_f
void PyObjectPlus::SetDeprecationWarningLinkLast(WarnLink* wlink) {m_base_wlink_last= wlink;}
void PyObjectPlus::NullDeprecationWarning() {m_base_wlink_first= m_base_wlink_last= NULL;}
-
#endif //NO_EXP_PYTHON_EMBEDDING
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index 8bf21ed8264..24509f6e6ed 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -31,6 +31,7 @@
#include "SCA_IActuator.h"
#include "SCA_ISensor.h"
#include "PyObjectPlus.h"
+#include "../Ketsji/KX_PythonSeq.h" /* not nice, only need for KX_PythonSeq_CreatePyObject */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -241,10 +242,9 @@ PyParentObject SCA_IController::Parents[] = {
};
PyMethodDef SCA_IController::Methods[] = {
- {"getActuator", (PyCFunction) SCA_IController::sPyGetActuator, METH_O},
- {"getSensor", (PyCFunction) SCA_IController::sPyGetSensor, METH_O},
-
//Deprecated functions ------>
+ {"getSensor", (PyCFunction) SCA_IController::sPyGetSensor, METH_O},
+ {"getActuator", (PyCFunction) SCA_IController::sPyGetActuator, METH_O},
{"getSensors", (PyCFunction) SCA_IController::sPyGetSensors, METH_NOARGS},
{"getActuators", (PyCFunction) SCA_IController::sPyGetActuators, METH_NOARGS},
{"getState", (PyCFunction) SCA_IController::sPyGetState, METH_NOARGS},
@@ -290,7 +290,8 @@ PyObject* SCA_IController::PyGetActuators()
PyObject* SCA_IController::PyGetSensor(PyObject* value)
{
-
+ ShowDeprecationWarning("getSensor(string)", "the sensors[string] property");
+
char *scriptArg = PyString_AsString(value);
if (scriptArg==NULL) {
PyErr_SetString(PyExc_TypeError, "controller.getSensor(string): Python Controller, expected a string (sensor name)");
@@ -313,7 +314,8 @@ PyObject* SCA_IController::PyGetSensor(PyObject* value)
PyObject* SCA_IController::PyGetActuator(PyObject* value)
{
-
+ ShowDeprecationWarning("getActuator(string)", "the actuators[string] property");
+
char *scriptArg = PyString_AsString(value);
if (scriptArg==NULL) {
PyErr_SetString(PyExc_TypeError, "controller.getActuator(string): Python Controller, expected a string (actuator name)");
@@ -360,24 +362,10 @@ PyObject* SCA_IController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_D
PyObject* SCA_IController::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- SCA_IController* self= static_cast<SCA_IController*>(self_v);
- vector<SCA_ISensor*> linkedsensors = self->GetLinkedSensors();
- PyObject* resultlist = PyList_New(linkedsensors.size());
-
- for (unsigned int index=0;index<linkedsensors.size();index++)
- PyList_SET_ITEM(resultlist,index, linkedsensors[index]->GetProxy());
-
- return resultlist;
+ return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_SENSORS);
}
PyObject* SCA_IController::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- SCA_IController* self= static_cast<SCA_IController*>(self_v);
- vector<SCA_IActuator*> linkedactuators = self->GetLinkedActuators();
- PyObject* resultlist = PyList_New(linkedactuators.size());
-
- for (unsigned int index=0;index<linkedactuators.size();index++)
- PyList_SET_ITEM(resultlist,index, linkedactuators[index]->GetProxy());
-
- return resultlist;
+ return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_ACTUATORS);
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index c2216fd3514..2f5b5631761 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -63,6 +63,7 @@ typedef unsigned long uint_ptr;
#include "KX_RayCast.h"
#include "KX_PythonInit.h"
#include "KX_PyMath.h"
+#include "KX_PythonSeq.h"
#include "SCA_IActuator.h"
#include "SCA_ISensor.h"
#include "SCA_IController.h"
@@ -1735,38 +1736,17 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE
/* experemental! */
PyObject* KX_GameObject::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
- SCA_SensorList& sensors= self->GetSensors();
- PyObject* resultlist = PyList_New(sensors.size());
-
- for (unsigned int index=0;index<sensors.size();index++)
- PyList_SET_ITEM(resultlist, index, sensors[index]->GetProxy());
-
- return resultlist;
+ return KX_PythonSeq_CreatePyObject((static_cast<KX_GameObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_SENSORS);
}
PyObject* KX_GameObject::pyattr_get_controllers(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
- SCA_ControllerList& controllers= self->GetControllers();
- PyObject* resultlist = PyList_New(controllers.size());
-
- for (unsigned int index=0;index<controllers.size();index++)
- PyList_SET_ITEM(resultlist, index, controllers[index]->GetProxy());
-
- return resultlist;
+ return KX_PythonSeq_CreatePyObject((static_cast<KX_GameObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_CONTROLLERS);
}
PyObject* KX_GameObject::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
- SCA_ActuatorList& actuators= self->GetActuators();
- PyObject* resultlist = PyList_New(actuators.size());
-
- for (unsigned int index=0;index<actuators.size();index++)
- PyList_SET_ITEM(resultlist, index, actuators[index]->GetProxy());
-
- return resultlist;
+ return KX_PythonSeq_CreatePyObject((static_cast<KX_GameObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_ACTUATORS);
}
PyObject* KX_GameObject::pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp
new file mode 100644
index 00000000000..c3ae35fa47c
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp
@@ -0,0 +1,384 @@
+/**
+ * $Id:
+ *
+ * ***** 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,
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * Readonly sequence wrapper for lookups on logic bricks
+ */
+
+
+#include "KX_PythonSeq.h"
+#include "KX_GameObject.h"
+#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 );
+}
+
+static int KX_PythonSeq_len( KX_PythonSeq * self )
+{
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self->base);
+
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+ return -1;
+ }
+
+ switch(self->type) {
+ case KX_PYGENSEQ_CONT_TYPE_SENSORS:
+ return ((SCA_IController *)self_plus)->GetLinkedSensors().size();
+ case KX_PYGENSEQ_CONT_TYPE_ACTUATORS:
+ return ((SCA_IController *)self_plus)->GetLinkedActuators().size();
+ case KX_PYGENSEQ_OB_TYPE_SENSORS:
+ return ((KX_GameObject *)self_plus)->GetSensors().size();
+ case KX_PYGENSEQ_OB_TYPE_CONTROLLERS:
+ return ((KX_GameObject *)self_plus)->GetControllers().size();
+ case KX_PYGENSEQ_OB_TYPE_ACTUATORS:
+ return ((KX_GameObject *)self_plus)->GetActuators().size();
+ default:
+ /* Should never happen */
+ PyErr_SetString(PyExc_SystemError, "invalid type, internal error");
+ return -1;
+ }
+}
+
+static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index)
+{
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self->base);
+
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+ NULL;
+ }
+
+ switch(self->type) {
+ case KX_PYGENSEQ_CONT_TYPE_SENSORS:
+ {
+ vector<SCA_ISensor*> linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors();
+ SCA_ISensor* sensor;
+ 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:
+ {
+ vector<SCA_IActuator*> linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators();
+ SCA_IActuator* sensor;
+ 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();
+ SCA_ISensor *sensor;
+ 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();
+ SCA_IController *controller;
+ 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();
+ SCA_IActuator *actuator;
+ 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();
+ }
+ }
+}
+
+
+static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key)
+{
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self->base);
+ char *name = NULL;
+
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
+ if (PyInt_Check(key)) {
+ return KX_PythonSeq_getIndex(self, PyInt_AS_LONG( key ));
+ } else if ( PyString_Check(key) ) {
+ name = PyString_AsString( key );
+ } else {
+ PyErr_SetString( PyExc_TypeError, "expected a string or an index" );
+ return NULL;
+ }
+
+ switch(self->type) {
+ case KX_PYGENSEQ_CONT_TYPE_SENSORS:
+ {
+ vector<SCA_ISensor*> linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors();
+ SCA_ISensor* sensor;
+ for (unsigned int index=0;index<linkedsensors.size();index++) {
+ sensor = linkedsensors[index];
+ if (sensor->GetName() == name)
+ return sensor->GetProxy();
+ }
+ break;
+ }
+ case KX_PYGENSEQ_CONT_TYPE_ACTUATORS:
+ {
+ vector<SCA_IActuator*> linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators();
+ SCA_IActuator* sensor;
+ for (unsigned int index=0;index<linkedactuators.size();index++) {
+ sensor = linkedactuators[index];
+ if (sensor->GetName() == name)
+ return sensor->GetProxy();
+ }
+ 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];
+ if (sensor->GetName() == name)
+ return sensor->GetProxy();
+ }
+ 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];
+ if (controller->GetName() == name)
+ return controller->GetProxy();
+ }
+ 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];
+ if (actuator->GetName() == name)
+ return actuator->GetProxy();
+ }
+ break;
+ }
+ }
+
+ PyErr_Format( PyExc_KeyError, "requested item \"%s\" does not exist", name);
+ return NULL;
+}
+
+static PyMappingMethods KX_PythonSeq_as_mapping = {
+ ( inquiry ) KX_PythonSeq_len, /* mp_length */
+ ( binaryfunc ) KX_PythonSeq_subscript, /* mp_subscript */
+ ( objobjargproc ) 0, /* mp_ass_subscript */
+};
+
+
+/*
+ * Initialize the interator index
+ */
+
+static PyObject *KX_PythonSeq_getIter( KX_PythonSeq * self )
+{
+ if(BGE_PROXY_REF(self->base)==NULL) {
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+ NULL;
+ }
+
+ /* create a new iterator if were alredy using this one */
+ 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.
+ */
+
+static PyObject *KX_PythonSeq_nextIter( KX_PythonSeq * self )
+{
+ PyObject *object = KX_PythonSeq_getIndex(self, self->iter);
+
+ 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 */
+}
+
+
+static int KX_PythonSeq_compare( KX_PythonSeq * a, KX_PythonSeq * b ) /* TODO - python3.x wants richcmp */
+{
+ return ( a->type == b->type && a->base == b->base) ? 0 : -1;
+}
+
+/*
+ * 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 = {
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
+ /* 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; */
+ ( cmpfunc ) KX_PythonSeq_compare, /* cmpfunc tp_compare; */
+ ( reprfunc ) KX_PythonSeq_repr, /* reprfunc tp_repr; */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ &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 */
+ 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 */
+ ( getiterfunc) KX_PythonSeq_getIter, /* getiterfunc tp_iter; */
+ ( iternextfunc ) KX_PythonSeq_nextIter, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ NULL, /* struct PyMethodDef *tp_methods; */
+ 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
+};
diff --git a/source/gameengine/Ketsji/KX_PythonSeq.h b/source/gameengine/Ketsji/KX_PythonSeq.h
new file mode 100644
index 00000000000..15a016224a9
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonSeq.h
@@ -0,0 +1,60 @@
+/**
+ * $Id:
+ *
+ * ***** 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,
+ * 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * Readonly sequence wrapper for lookups on logic bricks
+ */
+
+#ifndef _adr_py_seq_h_ // only process once,
+#define _adr_py_seq_h_ // even if multiply included
+
+#include "PyObjectPlus.h"
+
+// -------------------------
+enum KX_PYGENSEQ_TYPE {
+ KX_PYGENSEQ_CONT_TYPE_SENSORS,
+ KX_PYGENSEQ_CONT_TYPE_ACTUATORS,
+ KX_PYGENSEQ_OB_TYPE_SENSORS,
+ KX_PYGENSEQ_OB_TYPE_CONTROLLERS,
+ KX_PYGENSEQ_OB_TYPE_ACTUATORS
+};
+
+/* The Main PyType Object defined in Main.c */
+extern PyTypeObject KX_PythonSeq_Type;
+
+#define BPy_KX_PythonSeq_Check(v) \
+ ((v)->ob_type == &KX_PythonSeq_Type)
+
+typedef struct {
+ PyObject_VAR_HEAD
+ PyObject *base;
+ short type;
+ short iter;
+} KX_PythonSeq;
+
+PyObject *KX_PythonSeq_CreatePyObject(PyObject *base, short type);
+
+#endif // _adr_py_seq_h_
diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index 0f9bfea98f3..257a25e8ad9 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -67,15 +67,15 @@ class KX_GameObject(SCA_IObject):
- note: Most objects use only 1 mesh.
- note: Changes to this list will not update the KX_GameObject.
@type meshes: list of L{KX_MeshProxy}
- @ivar sensors: a list of L{SCA_ISensor} objects.
+ @ivar sensors: a sequence of L{SCA_ISensor} objects with string/index lookups and iterator support.
- note: This attribute is experemental and may be removed (but probably wont be).
- note: Changes to this list will not update the KX_GameObject.
@type sensors: list
- @ivar controllers: a list of L{SCA_IController} objects.
+ @ivar controllers: a sequence of L{SCA_IController} objects with string/index lookups and iterator support.
- note: This attribute is experemental and may be removed (but probably wont be).
- note: Changes to this list will not update the KX_GameObject.
@type controllers: list of L{SCA_ISensor}.
- @ivar actuators: a list of L{SCA_IActuator} objects.
+ @ivar actuators: a list of L{SCA_IActuator} with string/index lookups and iterator support.
- note: This attribute is experemental and may be removed (but probably wont be).
- note: Changes to this list will not update the KX_GameObject.
@type actuators: list
diff --git a/source/gameengine/PyDoc/SCA_IController.py b/source/gameengine/PyDoc/SCA_IController.py
index 3e6ee45e115..cfb4c18a826 100644
--- a/source/gameengine/PyDoc/SCA_IController.py
+++ b/source/gameengine/PyDoc/SCA_IController.py
@@ -12,13 +12,13 @@ class SCA_IController(SCA_ILogicBrick):
@ivar sensors: a list of sensors linked to this controller
- note: the sensors are not necessarily owned by the same object.
- note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup.
- @type sensors: list
+ @type sensors: sequence supporting index/string lookups and iteration.
@ivar actuators: a list of actuators linked to this controller.
- note: the sensors are not necessarily owned by the same object.
- note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup.
- @type actuators: list
+ @type actuators: sequence supporting index/string lookups and iteration.
- @group Deprecated: getState, getSensors, getActuators
+ @group Deprecated: getState, getSensors, getActuators, getSensor, getActuator
"""
def getState():
@@ -39,6 +39,7 @@ class SCA_IController(SCA_ILogicBrick):
"""
def getSensor(name):
"""
+ DEPRECATED: use the sensors[name] property
Gets the named linked sensor.
@type name: string
@@ -53,6 +54,7 @@ class SCA_IController(SCA_ILogicBrick):
"""
def getActuator(name):
"""
+ DEPRECATED: use the actuators[name] property
Gets the named linked actuator.
@type name: string