Blender  V2.59
SCA_IController.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: SCA_IController.cpp 35169 2011-02-25 13:32:11Z jesterking $
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include <stddef.h>
00035 
00036 #include "SCA_IController.h"
00037 #include "SCA_LogicManager.h"
00038 #include "SCA_IActuator.h"
00039 #include "SCA_ISensor.h"
00040 #include "PyObjectPlus.h"
00041 #include "../Ketsji/KX_PythonSeq.h" /* not nice, only need for KX_PythonSeq_CreatePyObject */
00042 
00043 #include <stdio.h>
00044 
00045 SCA_IController::SCA_IController(SCA_IObject* gameobj)
00046         :
00047         SCA_ILogicBrick(gameobj),
00048         m_statemask(0),
00049         m_justActivated(false)
00050 {
00051 }
00052         
00053 
00054         
00055 SCA_IController::~SCA_IController()
00056 {
00057         //UnlinkAllActuators();
00058 }
00059 
00060 
00061 
00062 std::vector<class SCA_ISensor*>& SCA_IController::GetLinkedSensors()
00063 {
00064         return m_linkedsensors;
00065 }
00066 
00067 
00068 
00069 std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
00070 {
00071         return m_linkedactuators;
00072 }
00073 
00074 
00075 
00076 void SCA_IController::UnlinkAllSensors()
00077 {
00078         std::vector<class SCA_ISensor*>::iterator sensit;
00079         for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
00080         {
00081                 if (IsActive()) 
00082                 {
00083                         (*sensit)->DecLink();
00084                 }
00085                 (*sensit)->UnlinkController(this);
00086         }
00087         m_linkedsensors.clear();
00088 }
00089 
00090 
00091 
00092 void SCA_IController::UnlinkAllActuators()
00093 {
00094         std::vector<class SCA_IActuator*>::iterator actit;
00095         for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
00096         {
00097                 if (IsActive()) 
00098                 {
00099                         (*actit)->DecLink();
00100                 }
00101                 (*actit)->UnlinkController(this);
00102         }
00103         m_linkedactuators.clear();
00104 }
00105 
00106 void SCA_IController::LinkToActuator(SCA_IActuator* actua)
00107 {
00108         m_linkedactuators.push_back(actua);
00109         if (IsActive())
00110         {
00111                 actua->IncLink();
00112         }
00113 }
00114 
00115 void    SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
00116 {
00117         std::vector<class SCA_IActuator*>::iterator actit;
00118         for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
00119         {
00120                 if ((*actit) == actua)
00121                 {
00122                         if (IsActive())
00123                         {
00124                                 (*actit)->DecLink();
00125                         }
00126                         *actit = m_linkedactuators.back();
00127                         m_linkedactuators.pop_back();
00128                         return;
00129                 }
00130         }
00131         printf("Missing link from controller %s:%s to actuator %s:%s\n", 
00132                 m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), 
00133                 actua->GetParent()->GetName().ReadPtr(), actua->GetName().ReadPtr());
00134 }
00135 
00136 void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
00137 {
00138         m_linkedsensors.push_back(sensor);
00139         if (IsActive())
00140         {
00141                 sensor->IncLink();
00142         }
00143 }
00144 
00145 void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor)
00146 {
00147         std::vector<class SCA_ISensor*>::iterator sensit;
00148         for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
00149         {
00150                 if ((*sensit) == sensor)
00151                 {
00152                         if (IsActive())
00153                         {
00154                                 sensor->DecLink();
00155                         }
00156                         *sensit = m_linkedsensors.back();
00157                         m_linkedsensors.pop_back();
00158                         return;
00159                 }
00160         }
00161         printf("Missing link from controller %s:%s to sensor %s:%s\n", 
00162                 m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), 
00163                 sensor->GetParent()->GetName().ReadPtr(), sensor->GetName().ReadPtr());
00164 }
00165 
00166 
00167 void SCA_IController::ApplyState(unsigned int state)
00168 {
00169         std::vector<class SCA_IActuator*>::iterator actit;
00170         std::vector<class SCA_ISensor*>::iterator sensit;
00171 
00172         if (m_statemask & state) 
00173         {
00174                 if (!IsActive()) 
00175                 {
00176                         // reactive the controller, all the links to actuator are valid again
00177                         for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
00178                         {
00179                                 (*actit)->IncLink();
00180                         }
00181 
00182                         for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
00183                         {
00184                                 (*sensit)->IncLink();
00185                         }
00186                         SetActive(true);
00187                         m_justActivated = true;
00188                 }
00189         } else if (IsActive())
00190         {
00191                 for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
00192                 {
00193                         (*actit)->DecLink();
00194                 }
00195                 for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
00196                 {
00197                         (*sensit)->DecLink();
00198                 }
00199                 SetActive(false);
00200                 m_justActivated = false;
00201         }
00202 }
00203 
00204 #ifdef WITH_PYTHON
00205 
00206 /* Python api */
00207 
00208 PyTypeObject SCA_IController::Type = {
00209         PyVarObject_HEAD_INIT(NULL, 0)
00210         "SCA_IController",
00211         sizeof(PyObjectPlus_Proxy),
00212         0,
00213         py_base_dealloc,
00214         0,
00215         0,
00216         0,
00217         0,
00218         py_base_repr,
00219         0,0,0,0,0,0,0,0,0,
00220         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00221         0,0,0,0,0,0,0,
00222         Methods,
00223         0,
00224         0,
00225         &SCA_ILogicBrick::Type,
00226         0,0,0,0,0,0,
00227         py_base_new
00228 };
00229 
00230 PyMethodDef SCA_IController::Methods[] = {
00231         {NULL,NULL} //Sentinel
00232 };
00233 
00234 PyAttributeDef SCA_IController::Attributes[] = {
00235         KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_IController, pyattr_get_state),
00236         KX_PYATTRIBUTE_RO_FUNCTION("sensors", SCA_IController, pyattr_get_sensors),
00237         KX_PYATTRIBUTE_RO_FUNCTION("actuators", SCA_IController, pyattr_get_actuators),
00238         KX_PYATTRIBUTE_BOOL_RW("useHighPriority",SCA_IController,m_bookmark),
00239         { NULL }        //Sentinel
00240 };
00241 
00242 PyObject* SCA_IController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00243 {
00244         SCA_IController* self= static_cast<SCA_IController*>(self_v);
00245         return PyLong_FromSsize_t(self->m_statemask);
00246 }
00247 
00248 PyObject* SCA_IController::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00249 {
00250         return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_SENSORS);    
00251 }
00252 
00253 PyObject* SCA_IController::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00254 {
00255         return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_ACTUATORS);  
00256 }
00257 #endif // WITH_PYTHON