BGE Py API
authorCampbell Barton <ideasman42@gmail.com>
Tue, 24 Feb 2009 05:50:45 +0000 (05:50 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 24 Feb 2009 05:50:45 +0000 (05:50 +0000)
* 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")

source/gameengine/GameLogic/SCA_PythonController.cpp
source/gameengine/GameLogic/SCA_PythonController.h
source/gameengine/PyDoc/GameLogic.py
source/gameengine/PyDoc/KX_Scene.py
source/gameengine/PyDoc/SCA_PythonController.py

index 5ab8db2986d4f780bdb0d171dad0a24d6406c9c6..92852ee03cb3a6e11dd6ba85d792d13f4a5601b0 100644 (file)
@@ -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<SCA_IActuator*> lacts =  m_sCurrentController->GetLinkedActuators();
+       std::vector<SCA_IActuator*>::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<SCA_IActuator*>(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<SCA_IActuator*> lacts =  m_sCurrentController->GetLinkedActuators();
        
-       std::vector<SCA_IActuator*>::iterator it;
-       bool found = false;
-       CValue* act = (CValue*)ob1;
-
-       for(it = lacts.begin(); it!= lacts.end(); it++) {
-               if( static_cast<SCA_IActuator*>(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;index<m_linkedactuators.size();index++)
        {
                SCA_IActuator* actua = m_linkedactuators[index];
-               STR_String realname = actua->GetName();
-               if (realname == scriptArg)
+               if (actua->GetName() == scriptArg)
                {
                        return actua->AddRef();
                }
index 046ef1f7aed70e10e6774fa0fe5112f1480bcc24..4ec18f32c23a67f942894a2359c53eca7b45102e 100644 (file)
@@ -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);
index 9dab7db608153de52191c4fb2d39617e21d164fb..f743acf06feb2bed7496a2a313967a2d07c3d9d6 100644 (file)
@@ -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.
        """
index 4a0a7a9556d752321327b494a4e911fb32e6d7a0..24b81bbf55e36a289e9cb8a6eb841b46865aa843 100644 (file)
@@ -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.
index 06f2b7e9d1ddb1feb5844de2c5b78653e2bac5c4..9684b41d48128c0bc78e19369d05c2b01f21af36 100644 (file)
@@ -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.