|
Blender
V2.59
|
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 }