Blender  V2.59
KX_ConvertControllers.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: KX_ConvertControllers.cpp 35167 2011-02-25 13:30:41Z 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 "MEM_guardedalloc.h"
00035 
00036 #include "KX_BlenderSceneConverter.h"
00037 #include "KX_ConvertControllers.h"
00038 #include "KX_Python.h"
00039 
00040 // Controller
00041 #include "SCA_ANDController.h"
00042 #include "SCA_ORController.h"
00043 #include "SCA_NANDController.h"
00044 #include "SCA_NORController.h"
00045 #include "SCA_XORController.h"
00046 #include "SCA_XNORController.h"
00047 #include "SCA_PythonController.h"
00048 #include "SCA_ExpressionController.h"
00049 
00050 #include "SCA_LogicManager.h"
00051 #include "KX_GameObject.h"
00052 #include "IntValue.h"
00053 
00054 /* This little block needed for linking to Blender... */
00055 #ifdef WIN32
00056 #include "BLI_winstuff.h"
00057 #endif
00058 
00059 #include "DNA_object_types.h"
00060 #include "DNA_controller_types.h"
00061 #include "DNA_text_types.h"
00062 
00063 #include "BKE_text.h"
00064 
00065 #include "BLI_blenlib.h"
00066 
00067 /* end of blender include block */
00068 
00069 
00070         static void
00071 LinkControllerToActuators(
00072         SCA_IController *game_controller,
00073         bController* bcontr,    
00074         SCA_LogicManager* logicmgr,
00075         KX_BlenderSceneConverter* converter
00076 ) {
00077         // Iterate through the actuators of the game blender
00078         // controller and find the corresponding ketsji actuator.
00079 
00080         game_controller->ReserveActuator(bcontr->totlinks);
00081         for (int i=0;i<bcontr->totlinks;i++)
00082         {
00083                 bActuator* bact = (bActuator*) bcontr->links[i];
00084                 SCA_IActuator *game_actuator = converter->FindGameActuator(bact);
00085                 if (game_actuator) {
00086                         logicmgr->RegisterToActuator(game_controller, game_actuator);
00087                 }
00088         }
00089 }
00090 
00091 
00092 void BL_ConvertControllers(
00093         struct Object* blenderobject,
00094         class KX_GameObject* gameobj,
00095         SCA_LogicManager* logicmgr,
00096         int activeLayerBitInfo,
00097         bool isInActiveLayer,
00098         KX_BlenderSceneConverter* converter
00099 ) {
00100         int uniqueint=0;
00101         int count = 0;
00102         int executePriority=0;
00103         bController* bcontr = (bController*)blenderobject->controllers.first;
00104         while (bcontr)
00105         {
00106                 bcontr = bcontr->next;
00107                 count++;
00108         }
00109         gameobj->ReserveController(count);
00110         bcontr = (bController*)blenderobject->controllers.first;
00111         while (bcontr)
00112         {
00113                 SCA_IController* gamecontroller = NULL;
00114                 switch(bcontr->type)
00115                 {
00116                         case CONT_LOGIC_AND:
00117                         {
00118                                 gamecontroller = new SCA_ANDController(gameobj);
00119                                 break;
00120                         }
00121                         case CONT_LOGIC_OR:
00122                         {
00123                                 gamecontroller = new SCA_ORController(gameobj);
00124                                 break;
00125                         }
00126                         case CONT_LOGIC_NAND:
00127                         {
00128                                 gamecontroller = new SCA_NANDController(gameobj);
00129                                 break;
00130                         }
00131                         case CONT_LOGIC_NOR:
00132                         {
00133                                 gamecontroller = new SCA_NORController(gameobj);
00134                                 break;
00135                         }
00136                         case CONT_LOGIC_XOR:
00137                         {
00138                                 gamecontroller = new SCA_XORController(gameobj);
00139                                 break;
00140                         }
00141                         case CONT_LOGIC_XNOR:
00142                         {
00143                                 gamecontroller = new SCA_XNORController(gameobj);
00144                                 break;
00145                         }
00146                         case CONT_EXPRESSION:
00147                         {
00148                                 bExpressionCont* bexpcont = (bExpressionCont*) bcontr->data;
00149                                 STR_String expressiontext = STR_String(bexpcont->str);
00150                                 if (expressiontext.Length() > 0)
00151                                 {
00152                                         gamecontroller = new SCA_ExpressionController(gameobj,expressiontext);
00153                                 }
00154                                 break;
00155                         }
00156                         case CONT_PYTHON:
00157                         {
00158                                 bPythonCont* pycont = (bPythonCont*) bcontr->data;
00159                                 SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
00160                                 gamecontroller = pyctrl;
00161 #ifdef WITH_PYTHON
00162 
00163                                 pyctrl->SetNamespace(converter->GetPyNamespace());
00164                                 
00165                                 if(pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
00166                                         if (pycont->text)
00167                                         {
00168                                                 char *buf;
00169                                                 // this is some blender specific code
00170                                                 buf= txt_to_buf(pycont->text);
00171                                                 if (buf)
00172                                                 {
00173                                                         pyctrl->SetScriptText(STR_String(buf));
00174                                                         pyctrl->SetScriptName(pycont->text->id.name+2);
00175                                                         MEM_freeN(buf);
00176                                                 }
00177                                                 
00178                                         }
00179                                 }
00180                                 else {
00181                                         /* let the controller print any warnings here when importing */
00182                                         pyctrl->SetScriptText(STR_String(pycont->module)); 
00183                                         pyctrl->SetScriptName(pycont->module); /* will be something like module.func so using it as the name is OK */
00184 
00185                                         if(pycont->flag & CONT_PY_DEBUG) {
00186                                                 printf("\nDebuging \"%s\", module for object %s\n\texpect worse performance.\n", pycont->module, blenderobject->id.name+2);
00187                                                 pyctrl->SetDebug(true);
00188                                         }
00189                                 }
00190                                 
00191 #endif // WITH_PYTHON
00192 
00193                                 break;
00194                         }
00195                         default:
00196                         {
00197                                 
00198                         }
00199                 }
00200 
00201                 if (gamecontroller)
00202                 {
00203                         LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
00204                         gamecontroller->SetExecutePriority(executePriority++);
00205                         gamecontroller->SetBookmark((bcontr->flag & CONT_PRIO) != 0);
00206                         gamecontroller->SetState(bcontr->state_mask);
00207                         STR_String uniquename = bcontr->name;
00208                         uniquename += "#CONTR#";
00209                         uniqueint++;
00210                         CIntValue* uniqueval = new CIntValue(uniqueint);
00211                         uniquename += uniqueval->GetText();
00212                         uniqueval->Release();
00213                         gamecontroller->SetName(uniquename);
00214                         gameobj->AddController(gamecontroller);
00215                         
00216                         converter->RegisterGameController(gamecontroller, bcontr);
00217 
00218 #ifdef WITH_PYTHON
00219                         if (bcontr->type==CONT_PYTHON) {
00220                                 SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
00221                                 /* not strictly needed but gives syntax errors early on and
00222                                  * gives more predictable performance for larger scripts */
00223                                 if(pyctrl->m_mode==SCA_PythonController::SCA_PYEXEC_SCRIPT)
00224                                         pyctrl->Compile();
00225                                 else {
00226                                         /* We cant do this because importing runs the script which could end up accessing
00227                                          * internal BGE functions, this is unstable while we're converting the scene.
00228                                          * This is a pitty because its useful to see errors at startup but cant help it */
00229                                         
00230                                         // pyctrl->Import();
00231                                 }
00232                         }
00233 #endif // WITH_PYTHON
00234 
00235                         //done with gamecontroller
00236                         gamecontroller->Release();
00237                 }
00238                 
00239                 bcontr = bcontr->next;
00240         }
00241 
00242 }