From 6c7c38a4e4892677f8e7db2b41115209901a2d35 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 24 Feb 2009 05:50:45 +0000 Subject: [PATCH] BGE Py API * Made GameLogic.addActiveActuator(actu, bool) to raise an error if the actuator is not in the list. Before it would allow any value as the actuator and fail silently (makes debugging scripts more difficult). * Allow the actuator to be a string which is convenient if you dont want to change the settings of the actuator. * Added activate/deactivate functions to the controller, this is more logical since the GameLogic.addActiveActuator() function is running through the controller anyway. GameLogic.addActiveActuator(controller.getActuator("SomeAct"), True) ...can be replaced with... controller.activate("SomeAct") --- .../GameLogic/SCA_PythonController.cpp | 91 ++++++++++++++----- .../GameLogic/SCA_PythonController.h | 4 + source/gameengine/PyDoc/GameLogic.py | 2 +- source/gameengine/PyDoc/KX_Scene.py | 2 + .../gameengine/PyDoc/SCA_PythonController.py | 12 ++- 5 files changed, 86 insertions(+), 25 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 5ab8db2986d..92852ee03cb 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -157,8 +157,40 @@ static const char* sPyGetCurrentController__doc__; PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self) { - m_sCurrentController->AddRef(); - return m_sCurrentController; + return m_sCurrentController->AddRef(); +} + +SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) +{ + // for safety, todo: only allow for registered actuators (pointertable) + // we don't want to crash gameengine/blender by python scripts + std::vector lacts = m_sCurrentController->GetLinkedActuators(); + std::vector::iterator it; + + if (PyString_Check(value)) { + /* get the actuator from the name */ + char *name= PyString_AsString(value); + for(it = lacts.begin(); it!= lacts.end(); it++) { + if( name == (*it)->GetName() ) { + return *it; + } + } + } + else { + /* Expecting an actuator type */ + for(it = lacts.begin(); it!= lacts.end(); it++) { + if( static_cast(value) == (*it) ) { + return *it; + } + } + } + + /* set the exception */ + PyObject *value_str = PyObject_Repr(value); /* new ref */ + PyErr_Format(PyExc_ValueError, "'%s' not in this controllers actuator list", PyString_AsString(value_str)); + Py_DECREF(value_str); + + return false; } #if 0 @@ -175,26 +207,14 @@ PyObject* SCA_PythonController::sPyAddActiveActuator( int activate; if (!PyArg_ParseTuple(args, "Oi", &ob1,&activate)) return NULL; - - // for safety, todo: only allow for registered actuators (pointertable) - // we don't want to crash gameengine/blender by python scripts - std::vector lacts = m_sCurrentController->GetLinkedActuators(); - std::vector::iterator it; - bool found = false; - CValue* act = (CValue*)ob1; - - for(it = lacts.begin(); it!= lacts.end(); it++) { - if( static_cast(act) == (*it) ) { - found=true; - break; - } - } - if(found){ - CValue* boolval = new CBoolValue(activate!=0); - m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)act,boolval); - boolval->Release(); - } + SCA_IActuator* actu = LinkedActuatorFromPy(ob1); + if(actu==NULL) + return NULL; + + CValue* boolval = new CBoolValue(activate!=0); + m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu,boolval); + boolval->Release(); Py_RETURN_NONE; } @@ -229,6 +249,9 @@ PyParentObject SCA_PythonController::Parents[] = { NULL }; PyMethodDef SCA_PythonController::Methods[] = { + {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O}, + {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O}, + {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetActuators_doc}, {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator, METH_O, (PY_METHODCHAR)SCA_PythonController::GetActuator_doc}, {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetSensors_doc}, @@ -380,6 +403,29 @@ int SCA_PythonController::_setattr(const char *attr, PyObject *value) return SCA_IController::_setattr(attr, value); } +PyObject* SCA_PythonController::PyActivate(PyObject* self, PyObject *value) +{ + SCA_IActuator* actu = LinkedActuatorFromPy(value); + if(actu==NULL) + return NULL; + + CValue* boolval = new CBoolValue(true); + m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval); + boolval->Release(); + Py_RETURN_NONE; +} + +PyObject* SCA_PythonController::PyDeActivate(PyObject* self, PyObject *value) +{ + SCA_IActuator* actu = LinkedActuatorFromPy(value); + if(actu==NULL) + return NULL; + + CValue* boolval = new CBoolValue(false); + m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval); + boolval->Release(); + Py_RETURN_NONE; +} PyObject* SCA_PythonController::PyGetActuators(PyObject* self) { @@ -437,8 +483,7 @@ SCA_PythonController::PyGetActuator(PyObject* self, PyObject* value) for (unsigned int index=0;indexGetName(); - if (realname == scriptArg) + if (actua->GetName() == scriptArg) { return actua->AddRef(); } diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 046ef1f7aed..4ec18f32c23 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -77,9 +77,13 @@ class SCA_PythonController : public SCA_IController static const char* sPyAddActiveActuator__doc__; static PyObject* sPyAddActiveActuator(PyObject* self, PyObject* args); + static SCA_IActuator* LinkedActuatorFromPy(PyObject *value); virtual PyObject* _getattr(const char *attr); virtual int _setattr(const char *attr, PyObject *value); + + KX_PYMETHOD_O(SCA_PythonController,Activate); + KX_PYMETHOD_O(SCA_PythonController,DeActivate); KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetSensors); KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetActuators); KX_PYMETHOD_DOC_O(SCA_PythonController,GetSensor); diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 9dab7db6081..f743acf06fe 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -159,7 +159,7 @@ def addActiveActuator(actuator, activate): """ Activates the given actuator. - @type actuator: L{SCA_IActuator} + @type actuator: L{SCA_IActuator} or the actuator name as a string. @type activate: boolean @param activate: whether to activate or deactivate the given actuator. """ diff --git a/source/gameengine/PyDoc/KX_Scene.py b/source/gameengine/PyDoc/KX_Scene.py index 4a0a7a9556d..24b81bbf55e 100644 --- a/source/gameengine/PyDoc/KX_Scene.py +++ b/source/gameengine/PyDoc/KX_Scene.py @@ -39,6 +39,8 @@ class KX_Scene: @ivar name: The scene's name @type name: string + @type objects: A list of objects in the scene. + @type objects: list [L{KX_GameObject}] @ivar active_camera: The current active camera @type active_camera: L{KX_Camera} @ivar suspended: True if the scene is suspended. diff --git a/source/gameengine/PyDoc/SCA_PythonController.py b/source/gameengine/PyDoc/SCA_PythonController.py index 06f2b7e9d1d..9684b41d481 100644 --- a/source/gameengine/PyDoc/SCA_PythonController.py +++ b/source/gameengine/PyDoc/SCA_PythonController.py @@ -15,7 +15,17 @@ class SCA_PythonController(SCA_IController): This can be used with the GameObject's state to test if the controller is active. @type state: integer """ - + def activate(actuator): + """ + Activates an actuator attached to this controller. + @type actuator: actuator or the actuator name as a string + """ + def deactivate(actuator): + """ + Deactivates an actuator attached to this controller. + @type actuator: actuator or the actuator name as a string + """ + def getSensors(): """ Gets a list of all sensors attached to this controller.