Blender  V2.59
SCA_LogicManager.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: SCA_LogicManager.cpp 35169 2011-02-25 13:32:11Z jesterking $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  * Regulates the top-level logic behaviour for one scene.
00029  */
00030 
00035 #include "Value.h"
00036 #include "SCA_LogicManager.h"
00037 #include "SCA_ISensor.h"
00038 #include "SCA_IController.h"
00039 #include "SCA_IActuator.h"
00040 #include "SCA_EventManager.h"
00041 #include "SCA_PythonController.h"
00042 #include <set>
00043 
00044 
00045 SCA_LogicManager::SCA_LogicManager()
00046 {
00047 }
00048 
00049 
00050 
00051 SCA_LogicManager::~SCA_LogicManager()
00052 {
00053         for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());++it)
00054         {
00055                 delete (*it);
00056         }
00057         m_eventmanagers.clear();
00058         assert(m_activeActuators.Empty());
00059 }
00060 
00061 /*
00062 // this kind of fixes bug 398 but breakes games, so better leave it out for now.
00063 // a removed object's gameobject (and logicbricks and stuff) didn't get released
00064 // because it was still in the m_mapStringToGameObjects map.
00065 void SCA_LogicManager::RemoveGameObject(const STR_String& gameobjname)
00066 {
00067         int numgameobj = m_mapStringToGameObjects.size();
00068         for (int i = 0; i < numgameobj; i++)
00069         {
00070                 CValue** gameobjptr = m_mapStringToGameObjects.at(i);
00071                 assert(gameobjptr);
00072 
00073                 if (gameobjptr)
00074                 {
00075                         if ((*gameobjptr)->GetName() == gameobjname)
00076                                 (*gameobjptr)->Release();
00077                 }
00078         }
00079 
00080         m_mapStringToGameObjects.remove(gameobjname);
00081 }
00082 */
00083 
00084 
00085 void SCA_LogicManager::RegisterEventManager(SCA_EventManager* eventmgr)
00086 {
00087         m_eventmanagers.push_back(eventmgr);
00088 }
00089 
00090 
00091 
00092 void SCA_LogicManager::RegisterGameObjectName(const STR_String& gameobjname,
00093                                                                                           CValue* gameobj)
00094 {
00095         STR_HashedString mn = gameobjname;
00096         m_mapStringToGameObjects.insert(mn,gameobj);
00097 }
00098 
00099 
00100 
00101 void SCA_LogicManager::RegisterGameMeshName(const STR_String& gamemeshname, void* blendobj)
00102 {
00103         STR_HashedString mn = gamemeshname;
00104         m_map_gamemeshname_to_blendobj.insert(mn, blendobj);
00105 }
00106 
00107 
00108 
00109 void SCA_LogicManager::RegisterGameObj(void* blendobj, CValue* gameobj) 
00110 {
00111         m_map_blendobj_to_gameobj.insert(CHashedPtr(blendobj), gameobj);
00112 }
00113 
00114 void SCA_LogicManager::UnregisterGameObj(void* blendobj, CValue* gameobj) 
00115 {
00116         void **obp = m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
00117         if (obp && (CValue*)(*obp) == gameobj)
00118                 m_map_blendobj_to_gameobj.remove(CHashedPtr(blendobj));
00119 }
00120 
00121 CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
00122 {
00123         STR_HashedString mn = gameobjname;
00124         CValue** gameptr = m_mapStringToGameObjects[mn];
00125         
00126         if (gameptr)
00127                 return *gameptr;
00128 
00129         return NULL;
00130 }
00131 
00132 
00133 CValue* SCA_LogicManager::FindGameObjByBlendObj(void* blendobj) 
00134 {
00135         void **obp= m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
00136         return obp?(CValue*)(*obp):NULL;
00137 }
00138 
00139 
00140 
00141 void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshname) 
00142 {
00143         STR_HashedString mn = gamemeshname;
00144         void **obp= m_map_gamemeshname_to_blendobj[mn];
00145         return obp?*obp:NULL;
00146 }
00147 
00148 
00149 
00150 void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
00151 {
00152         sensor->UnlinkAllControllers();
00153         sensor->UnregisterToManager();
00154 }
00155 
00156 void SCA_LogicManager::RemoveController(SCA_IController* controller)
00157 {
00158         controller->UnlinkAllSensors();
00159         controller->UnlinkAllActuators();
00160         controller->Deactivate();
00161 }
00162 
00163 
00164 void SCA_LogicManager::RemoveActuator(SCA_IActuator* actuator)
00165 {
00166         actuator->UnlinkAllControllers();
00167         actuator->Deactivate();
00168         actuator->SetActive(false);
00169 }
00170 
00171 
00172 
00173 void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor)
00174 {
00175         sensor->LinkToController(controller);
00176         controller->LinkToSensor(sensor);
00177 }
00178 
00179 
00180 
00181 void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua)
00182 {
00183         actua->LinkToController(controller);
00184         controller->LinkToActuator(actua);
00185 }
00186 
00187 
00188 
00189 void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
00190 {
00191         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
00192                 (*ie)->NextFrame(curtime, fixedtime);
00193 
00194         for(SG_QList* obj = (SG_QList*)m_triggeredControllerSet.Remove();
00195                 obj != NULL;
00196                 obj = (SG_QList*)m_triggeredControllerSet.Remove())
00197         {
00198                 for(SCA_IController* contr = (SCA_IController*)obj->QRemove();
00199                         contr != NULL;
00200                         contr = (SCA_IController*)obj->QRemove())
00201                 {
00202                         contr->Trigger(this);
00203                         contr->ClrJustActivated();
00204                 }
00205         }
00206 }
00207 
00208 
00209 
00210 void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
00211 {
00212         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
00213                 (*ie)->UpdateFrame();
00214 
00215         SG_DList::iterator<SG_QList> io(m_activeActuators);
00216         for (io.begin(); !io.end(); )
00217         {
00218                 SG_QList* ahead = *io;
00219                 // increment now so that we can remove the current element
00220                 ++io;
00221                 SG_QList::iterator<SCA_IActuator> ia(*ahead);
00222                 for (ia.begin(); !ia.end();  )
00223                 {
00224                         SCA_IActuator* actua = *ia;
00225                         // increment first to allow removal of inactive actuators.
00226                         ++ia;
00227                         if (!actua->Update(curtime, frame))
00228                         {
00229                                 // this actuator is not active anymore, remove
00230                                 actua->QDelink(); 
00231                                 actua->SetActive(false); 
00232                         } else if (actua->IsNoLink())
00233                         {
00234                                 // This actuator has no more links but it still active
00235                                 // make sure it will get a negative event on next frame to stop it
00236                                 // Do this check after Update() rather than before to make sure
00237                                 // that all the actuators that are activated at same time than a state
00238                                 // actuator have a chance to execute. 
00239                                 bool event = false;
00240                                 actua->RemoveAllEvents();
00241                                 actua->AddEvent(event);
00242                         }
00243                 }
00244                 if (ahead->QEmpty())
00245                 {
00246                         // no more active controller, remove from main list
00247                         ahead->Delink();
00248                 }
00249         }
00250 }
00251 
00252 
00253 
00254 void* SCA_LogicManager::GetActionByName (const STR_String& actname)
00255 {
00256         STR_HashedString an = actname;
00257         void** actptr = m_mapStringToActions[an];
00258 
00259         if (actptr)
00260                 return *actptr;
00261 
00262         return NULL;
00263 }
00264 
00265 
00266 
00267 void* SCA_LogicManager::GetMeshByName(const STR_String& meshname)
00268 {
00269         STR_HashedString mn = meshname;
00270         void** meshptr = m_mapStringToMeshes[mn];
00271 
00272         if (meshptr)
00273                 return *meshptr;
00274 
00275         return NULL;
00276 }
00277 
00278 
00279 
00280 void SCA_LogicManager::RegisterMeshName(const STR_String& meshname,void* mesh)
00281 {
00282         STR_HashedString mn = meshname;
00283         m_mapStringToMeshes.insert(mn,mesh);
00284 }
00285 
00286 void SCA_LogicManager::UnregisterMeshName(const STR_String& meshname,void* mesh)
00287 {
00288         STR_HashedString mn = meshname;
00289         m_mapStringToMeshes.remove(mn);
00290 }
00291 
00292 
00293 void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action)
00294 {
00295         STR_HashedString an = actname;
00296         m_mapStringToActions.insert(an, action);
00297 }
00298 
00299 
00300 
00301 void SCA_LogicManager::EndFrame()
00302 {
00303         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
00304         !(ie==m_eventmanagers.end());ie++)
00305         {
00306                 (*ie)->EndFrame();
00307         }
00308 }
00309 
00310 
00311 void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor)
00312 {
00313         controller->Activate(m_triggeredControllerSet);
00314 
00315 #ifdef WITH_PYTHON
00316 
00317         // so that the controller knows which sensor has activited it
00318         // only needed for python controller
00319         // Note that this is safe even if the controller is subclassed.
00320         if (controller->GetType() == &SCA_PythonController::Type)
00321         {
00322                 SCA_PythonController* pythonController = (SCA_PythonController*)controller;
00323                 pythonController->AddTriggeredSensor(sensor);
00324         }
00325 #endif
00326 }
00327 
00328 SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
00329 {
00330         // find an eventmanager of a certain type
00331         SCA_EventManager* eventmgr = NULL;
00332 
00333         for (vector<SCA_EventManager*>::const_iterator i=
00334         m_eventmanagers.begin();!(i==m_eventmanagers.end());i++)
00335         {
00336                 SCA_EventManager* emgr = *i;
00337                 if (emgr->GetType() == eventmgrtype)
00338                 {
00339                         eventmgr = emgr;
00340                         break;
00341                 }
00342         }
00343         return eventmgr;
00344 }