From 136d4c34badc12b72f5c3541fcdaf2b1459af408 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 May 2009 01:48:14 +0000 Subject: [PATCH] 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. --- .../gameengine/Expressions/PyObjectPlus.cpp | 1 - .../gameengine/GameLogic/SCA_IController.cpp | 30 +- source/gameengine/Ketsji/KX_GameObject.cpp | 28 +- source/gameengine/Ketsji/KX_PythonSeq.cpp | 384 ++++++++++++++++++ source/gameengine/Ketsji/KX_PythonSeq.h | 60 +++ source/gameengine/PyDoc/KX_GameObject.py | 6 +- source/gameengine/PyDoc/SCA_IController.py | 8 +- 7 files changed, 465 insertions(+), 52 deletions(-) create mode 100644 source/gameengine/Ketsji/KX_PythonSeq.cpp create mode 100644 source/gameengine/Ketsji/KX_PythonSeq.h 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 @@ -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(self_v); - vector linkedsensors = self->GetLinkedSensors(); - PyObject* resultlist = PyList_New(linkedsensors.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(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(self_v); - vector linkedactuators = self->GetLinkedActuators(); - PyObject* resultlist = PyList_New(linkedactuators.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(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(self_v); - SCA_SensorList& sensors= self->GetSensors(); - PyObject* resultlist = PyList_New(sensors.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(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(self_v); - SCA_ControllerList& controllers= self->GetControllers(); - PyObject* resultlist = PyList_New(controllers.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(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(self_v); - SCA_ActuatorList& actuators= self->GetActuators(); - PyObject* resultlist = PyList_New(actuators.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(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 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 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 linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); + SCA_ISensor* sensor; + for (unsigned int index=0;indexGetName() == name) + return sensor->GetProxy(); + } + break; + } + case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: + { + vector linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); + SCA_IActuator* sensor; + for (unsigned int index=0;indexGetName() == 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;indexGetName() == 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;indexGetName() == 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;indexGetName() == 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 "." */ + "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