Blender V2.61 - r43446

SCA_LogicManager.cpp

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