Spelling Cleanup
[blender.git] / source / gameengine / GameLogic / SCA_LogicManager.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * Regulates the top-level logic behavior for one scene.
27  */
28
29 /** \file gameengine/GameLogic/SCA_LogicManager.cpp
30  *  \ingroup gamelogic
31  */
32
33 #include "Value.h"
34 #include "SCA_LogicManager.h"
35 #include "SCA_ISensor.h"
36 #include "SCA_IController.h"
37 #include "SCA_IActuator.h"
38 #include "SCA_EventManager.h"
39 #include "SCA_PythonController.h"
40 #include <set>
41
42
43 SCA_LogicManager::SCA_LogicManager()
44 {
45 }
46
47
48
49 SCA_LogicManager::~SCA_LogicManager()
50 {
51         for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());++it)
52         {
53                 delete (*it);
54         }
55         m_eventmanagers.clear();
56         assert(m_activeActuators.Empty());
57 }
58
59 /*
60 // this kind of fixes bug 398 but breakes games, so better leave it out for now.
61 // a removed object's gameobject (and logicbricks and stuff) didn't get released
62 // because it was still in the m_mapStringToGameObjects map.
63 void SCA_LogicManager::RemoveGameObject(const STR_String& gameobjname)
64 {
65         int numgameobj = m_mapStringToGameObjects.size();
66         for (int i = 0; i < numgameobj; i++)
67         {
68                 CValue** gameobjptr = m_mapStringToGameObjects.at(i);
69                 assert(gameobjptr);
70
71                 if (gameobjptr)
72                 {
73                         if ((*gameobjptr)->GetName() == gameobjname)
74                                 (*gameobjptr)->Release();
75                 }
76         }
77
78         m_mapStringToGameObjects.remove(gameobjname);
79 }
80 */
81
82
83 void SCA_LogicManager::RegisterEventManager(SCA_EventManager* eventmgr)
84 {
85         m_eventmanagers.push_back(eventmgr);
86 }
87
88
89
90 void SCA_LogicManager::RegisterGameObjectName(const STR_String& gameobjname,
91                                                                                           CValue* gameobj)
92 {
93         STR_HashedString mn = gameobjname;
94         m_mapStringToGameObjects.insert(mn,gameobj);
95 }
96
97
98
99 void SCA_LogicManager::RegisterGameMeshName(const STR_String& gamemeshname, void* blendobj)
100 {
101         STR_HashedString mn = gamemeshname;
102         m_map_gamemeshname_to_blendobj.insert(mn, blendobj);
103 }
104
105
106
107 void SCA_LogicManager::RegisterGameObj(void* blendobj, CValue* gameobj) 
108 {
109         m_map_blendobj_to_gameobj.insert(CHashedPtr(blendobj), gameobj);
110 }
111
112 void SCA_LogicManager::UnregisterGameObj(void* blendobj, CValue* gameobj) 
113 {
114         void **obp = m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
115         if (obp && (CValue*)(*obp) == gameobj)
116                 m_map_blendobj_to_gameobj.remove(CHashedPtr(blendobj));
117 }
118
119 CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
120 {
121         STR_HashedString mn = gameobjname;
122         CValue** gameptr = m_mapStringToGameObjects[mn];
123         
124         if (gameptr)
125                 return *gameptr;
126
127         return NULL;
128 }
129
130
131 CValue* SCA_LogicManager::FindGameObjByBlendObj(void* blendobj) 
132 {
133         void **obp= m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
134         return obp?(CValue*)(*obp):NULL;
135 }
136
137
138
139 void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshname) 
140 {
141         STR_HashedString mn = gamemeshname;
142         void **obp= m_map_gamemeshname_to_blendobj[mn];
143         return obp?*obp:NULL;
144 }
145
146
147
148 void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
149 {
150         sensor->UnlinkAllControllers();
151         sensor->UnregisterToManager();
152 }
153
154 void SCA_LogicManager::RemoveController(SCA_IController* controller)
155 {
156         controller->UnlinkAllSensors();
157         controller->UnlinkAllActuators();
158         controller->Deactivate();
159 }
160
161
162 void SCA_LogicManager::RemoveActuator(SCA_IActuator* actuator)
163 {
164         actuator->UnlinkAllControllers();
165         actuator->Deactivate();
166         actuator->SetActive(false);
167 }
168
169
170
171 void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor)
172 {
173         sensor->LinkToController(controller);
174         controller->LinkToSensor(sensor);
175 }
176
177
178
179 void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua)
180 {
181         actua->LinkToController(controller);
182         controller->LinkToActuator(actua);
183 }
184
185
186
187 void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
188 {
189         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
190                 (*ie)->NextFrame(curtime, fixedtime);
191
192         for(SG_QList* obj = (SG_QList*)m_triggeredControllerSet.Remove();
193                 obj != NULL;
194                 obj = (SG_QList*)m_triggeredControllerSet.Remove())
195         {
196                 for(SCA_IController* contr = (SCA_IController*)obj->QRemove();
197                         contr != NULL;
198                         contr = (SCA_IController*)obj->QRemove())
199                 {
200                         contr->Trigger(this);
201                         contr->ClrJustActivated();
202                 }
203         }
204 }
205
206
207
208 void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
209 {
210         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
211                 (*ie)->UpdateFrame();
212
213         SG_DList::iterator<SG_QList> io(m_activeActuators);
214         for (io.begin(); !io.end(); )
215         {
216                 SG_QList* ahead = *io;
217                 // increment now so that we can remove the current element
218                 ++io;
219                 SG_QList::iterator<SCA_IActuator> ia(*ahead);
220                 for (ia.begin(); !ia.end();  )
221                 {
222                         SCA_IActuator* actua = *ia;
223                         // increment first to allow removal of inactive actuators.
224                         ++ia;
225                         if (!actua->Update(curtime, frame))
226                         {
227                                 // this actuator is not active anymore, remove
228                                 actua->QDelink(); 
229                                 actua->SetActive(false); 
230                         } else if (actua->IsNoLink())
231                         {
232                                 // This actuator has no more links but it still active
233                                 // make sure it will get a negative event on next frame to stop it
234                                 // Do this check after Update() rather than before to make sure
235                                 // that all the actuators that are activated at same time than a state
236                                 // actuator have a chance to execute. 
237                                 bool event = false;
238                                 actua->RemoveAllEvents();
239                                 actua->AddEvent(event);
240                         }
241                 }
242                 if (ahead->QEmpty())
243                 {
244                         // no more active controller, remove from main list
245                         ahead->Delink();
246                 }
247         }
248 }
249
250
251
252 void* SCA_LogicManager::GetActionByName (const STR_String& actname)
253 {
254         STR_HashedString an = actname;
255         void** actptr = m_mapStringToActions[an];
256
257         if (actptr)
258                 return *actptr;
259
260         return NULL;
261 }
262
263
264
265 void* SCA_LogicManager::GetMeshByName(const STR_String& meshname)
266 {
267         STR_HashedString mn = meshname;
268         void** meshptr = m_mapStringToMeshes[mn];
269
270         if (meshptr)
271                 return *meshptr;
272
273         return NULL;
274 }
275
276
277
278 void SCA_LogicManager::RegisterMeshName(const STR_String& meshname,void* mesh)
279 {
280         STR_HashedString mn = meshname;
281         m_mapStringToMeshes.insert(mn,mesh);
282 }
283
284 void SCA_LogicManager::UnregisterMeshName(const STR_String& meshname,void* mesh)
285 {
286         STR_HashedString mn = meshname;
287         m_mapStringToMeshes.remove(mn);
288 }
289
290
291 void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action)
292 {
293         STR_HashedString an = actname;
294         m_mapStringToActions.insert(an, action);
295 }
296
297
298
299 void SCA_LogicManager::EndFrame()
300 {
301         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
302         !(ie==m_eventmanagers.end());ie++)
303         {
304                 (*ie)->EndFrame();
305         }
306 }
307
308
309 void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor)
310 {
311         controller->Activate(m_triggeredControllerSet);
312
313 #ifdef WITH_PYTHON
314
315         // so that the controller knows which sensor has activited it
316         // only needed for python controller
317         // Note that this is safe even if the controller is subclassed.
318         if (controller->GetType() == &SCA_PythonController::Type)
319         {
320                 SCA_PythonController* pythonController = (SCA_PythonController*)controller;
321                 pythonController->AddTriggeredSensor(sensor);
322         }
323 #endif
324 }
325
326 SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
327 {
328         // find an eventmanager of a certain type
329         SCA_EventManager* eventmgr = NULL;
330
331         for (vector<SCA_EventManager*>::const_iterator i=
332         m_eventmanagers.begin();!(i==m_eventmanagers.end());i++)
333         {
334                 SCA_EventManager* emgr = *i;
335                 if (emgr->GetType() == eventmgrtype)
336                 {
337                         eventmgr = emgr;
338                         break;
339                 }
340         }
341         return eventmgr;
342 }