49f01d643e5a907de75b85da78b22c49493f9e39
[blender.git] / source / gameengine / GameLogic / SCA_LogicManager.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Regulates the top-level logic behaviour for one scene.
29  */
30 #include "Value.h"
31 #include "SCA_LogicManager.h"
32 #include "SCA_ISensor.h"
33 #include "SCA_IController.h"
34 #include "SCA_IActuator.h"
35 #include "SCA_EventManager.h"
36 #include <set>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42
43 SCA_LogicManager::SCA_LogicManager()
44 {
45 }
46
47
48
49 SCA_LogicManager::~SCA_LogicManager()
50 {
51         /* AddRef() is not used when the objects are added to m_mapStringToGameObjects
52            so Release() should not be used either. The memory leak big is fixed
53            in BL_ConvertBlenderObjects()
54
55         int numgameobj = m_mapStringToGameObjects.size();
56         for (int i = 0; i < numgameobj; i++)
57         {
58                 CValue** gameobjptr = m_mapStringToGameObjects.at(i);
59                 assert(gameobjptr);
60                 if (gameobjptr)
61                         (*gameobjptr)->Release();
62     
63         }
64         */
65         /*for (int i=0;i<m_sensorcontrollermap.size();i++)
66         {
67                 vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
68                 delete controllerarray;
69         }
70         */
71         for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());it++)
72         {
73                 delete (*it);
74         }
75         m_eventmanagers.clear();
76         m_sensorcontrollermapje.clear();
77         m_removedActuators.clear();
78         m_activeActuators.clear();
79 }
80
81
82 /*
83 // this kind of fixes bug 398 but breakes games, so better leave it out for now.
84 // a removed object's gameobject (and logicbricks and stuff) didn't get released
85 // because it was still in the m_mapStringToGameObjects map.
86 void SCA_LogicManager::RemoveGameObject(const STR_String& gameobjname)
87 {
88         int numgameobj = m_mapStringToGameObjects.size();
89         for (int i = 0; i < numgameobj; i++)
90         {
91                 CValue** gameobjptr = m_mapStringToGameObjects.at(i);
92                 assert(gameobjptr);
93
94                 if (gameobjptr)
95                 {
96                         if ((*gameobjptr)->GetName() == gameobjname)
97                                 (*gameobjptr)->Release();
98                 }
99         }
100
101         m_mapStringToGameObjects.remove(gameobjname);
102 }
103 */
104
105
106 void SCA_LogicManager::RegisterEventManager(SCA_EventManager* eventmgr)
107 {
108         m_eventmanagers.push_back(eventmgr);
109 }
110
111
112
113 void SCA_LogicManager::RegisterGameObjectName(const STR_String& gameobjname,
114                                                                                           CValue* gameobj)
115 {
116         STR_HashedString mn = gameobjname;
117         m_mapStringToGameObjects.insert(mn,gameobj);
118 }
119
120
121
122 void SCA_LogicManager::RegisterGameMeshName(const STR_String& gamemeshname, void* blendobj)
123 {
124         STR_HashedString mn = gamemeshname;
125         m_map_gamemeshname_to_blendobj.insert(mn, blendobj);
126 }
127
128
129
130 void SCA_LogicManager::RegisterGameObj(CValue* gameobj, void* blendobj) 
131 {
132         m_map_gameobj_to_blendobj.insert(CHashedPtr(gameobj), blendobj);
133 }
134
135
136
137 CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
138 {
139         STR_HashedString mn = "OB"+gameobjname;
140         CValue** gameptr = m_mapStringToGameObjects[mn];
141         
142         if (gameptr)
143                 return *gameptr;
144
145         return NULL;
146 }
147
148
149 void* SCA_LogicManager::FindBlendObjByGameObj(CValue* gameobject) 
150 {
151         void **obp= m_map_gameobj_to_blendobj[CHashedPtr(gameobject)];
152         return obp?*obp:NULL;
153 }
154
155
156
157 void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshname) 
158 {
159         STR_HashedString mn = gamemeshname;
160         void **obp= m_map_gamemeshname_to_blendobj[mn];
161         return obp?*obp:NULL;
162 }
163
164
165
166 void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
167 {
168     m_sensorcontrollermapje.erase(sensor);
169         
170         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
171         !(ie==m_eventmanagers.end());ie++)
172         {
173                 (*ie)->RemoveSensor(sensor);
174         }
175 }
176
177 void SCA_LogicManager::RemoveController(SCA_IController* controller)
178 {
179         std::map<SCA_ISensor*,controllerlist>::iterator sit;
180         for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
181         {
182                 (*sit).second.remove(controller);
183         }
184 }
185
186
187 void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator)
188 {
189         m_removedActuators.push_back(SmartActuatorPtr(actuator,0));
190         // take care that no controller can use this actuator again !
191
192         std::map<SCA_ISensor*,controllerlist>::const_iterator sit;
193         for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
194         {
195                 controllerlist contlist = (*sit).second;
196                 for (list<SCA_IController*>::const_iterator c= contlist.begin();!(c==contlist.end());c++)
197                 {
198                         (*c)->UnlinkActuator(actuator);
199                 }
200         }
201 }
202
203
204
205 void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor)
206 {
207     m_sensorcontrollermapje[sensor].push_back(controller);
208         controller->LinkToSensor(sensor);
209 }
210
211
212
213 void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua)
214 {
215         controller->LinkToActuator(actua);
216 }
217
218
219
220 void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
221 {
222         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
223                 (*ie)->NextFrame(curtime, fixedtime);
224
225         // for this frame, look up for activated sensors, and build the collection of triggered controllers
226         // int numsensors = this->m_activatedsensors.size(); /*unused*/
227
228         set<SmartControllerPtr> triggeredControllerSet;
229
230         for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
231         !(is==m_activatedsensors.end());is++)
232         {
233                 SCA_ISensor* sensor = *is;
234                 controllerlist contlist = m_sensorcontrollermapje[sensor];
235                 for (list<SCA_IController*>::const_iterator c= contlist.begin();
236                         !(c==contlist.end());c++)
237                 {
238                                 SCA_IController* contr = *c;//controllerarray->at(c);
239                                 triggeredControllerSet.insert(SmartControllerPtr(contr,0));
240                 }
241                 //sensor->SetActive(false);
242         }
243
244         
245         // int numtriggered = triggeredControllerSet.size(); /*unused*/
246         for (set<SmartControllerPtr>::iterator tit=triggeredControllerSet.begin();
247         !(tit==triggeredControllerSet.end());tit++)
248         {
249                 (*tit)->Trigger(this);
250         }
251         triggeredControllerSet.clear();
252 }
253
254
255
256 void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
257 {
258         vector<SmartActuatorPtr>::iterator ra;
259         for (ra = m_removedActuators.begin(); !(ra == m_removedActuators.end()); ra++)
260         {
261                 m_activeActuators.erase(*ra);
262                 (*ra)->SetActive(false);
263         }
264         m_removedActuators.clear();
265         
266         for (set<SmartActuatorPtr>::iterator ia = m_activeActuators.begin();!(ia==m_activeActuators.end());ia++)
267         {
268                 //SCA_IActuator* actua = *ia;
269                 if (!(*ia)->Update(curtime, frame))
270                 {
271                         //*ia = m_activeactuators.back();
272                         m_removedActuators.push_back(*ia);
273                         
274                         (*ia)->SetActive(false);
275                         //m_activeactuators.pop_back();
276                 }
277         }
278         
279         for ( ra = m_removedActuators.begin(); !(ra == m_removedActuators.end()); ra++)
280         {
281                 m_activeActuators.erase(*ra);
282                 (*ra)->SetActive(false);
283         }
284         m_removedActuators.clear();
285 }
286
287
288
289 void* SCA_LogicManager::GetActionByName (const STR_String& actname)
290 {
291         STR_HashedString an = "AC"+actname;
292         void** actptr = m_mapStringToActions[an];
293
294         if (actptr)
295                 return *actptr;
296
297         return NULL;
298 }
299
300
301
302 void* SCA_LogicManager::GetMeshByName(const STR_String& meshname)
303 {
304         STR_HashedString mn = "ME"+meshname;
305         void** meshptr = m_mapStringToMeshes[mn];
306
307         if (meshptr)
308                 return *meshptr;
309
310         return NULL;
311 }
312
313
314
315 void SCA_LogicManager::RegisterMeshName(const STR_String& meshname,void* mesh)
316 {
317         STR_HashedString mn = meshname;
318         m_mapStringToMeshes.insert(mn,mesh);
319 }
320
321
322
323 void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action)
324 {
325         STR_HashedString an = actname;
326         m_mapStringToActions.insert(an, action);
327 }
328
329
330
331 void SCA_LogicManager::EndFrame()
332 {
333         for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
334         !(is==m_activatedsensors.end());is++)
335         {
336                 SCA_ISensor* sensor = *is;
337                 sensor->SetActive(false);
338         }
339         m_activatedsensors.clear();
340
341         for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
342         !(ie==m_eventmanagers.end());ie++)
343         {
344                 (*ie)->EndFrame();
345         }
346
347
348 }
349
350
351
352 void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor)
353 {
354         // each frame, only add sensor once, and to avoid a seek, or bloated container
355         // hold a flag in each sensor, with the 'framenr'
356         if (!sensor->IsActive())
357         {
358                 sensor->SetActive(true);
359                 m_activatedsensors.push_back(sensor);
360         }
361 }
362
363
364
365 void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event)
366 {
367         if (!actua->IsActive())
368         {
369                 actua->SetActive(true);
370                 m_activeActuators.insert(SmartActuatorPtr(actua,0));
371         }
372         actua->AddEvent(event->AddRef());
373 }
374
375
376
377 SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
378 {
379         // find an eventmanager of a certain type
380         SCA_EventManager* eventmgr = NULL;
381
382         for (vector<SCA_EventManager*>::const_iterator i=
383         m_eventmanagers.begin();!(i==m_eventmanagers.end());i++)
384         {
385                 SCA_EventManager* emgr = *i;
386                 if (emgr->GetType() == eventmgrtype)
387                 {
388                         eventmgr = emgr;
389                         break;
390                 }
391         }
392         return eventmgr;
393 }
394
395
396
397 SmartActuatorPtr::SmartActuatorPtr(const SmartActuatorPtr& other)
398 {
399         this->m_actuator = other.m_actuator;
400         this->m_actuator->AddRef();
401 }
402
403
404
405 SmartActuatorPtr::SmartActuatorPtr(SCA_IActuator* actua,int dummy)
406 : m_actuator(actua)
407 {
408         actua->AddRef();
409 }
410
411
412
413 SmartActuatorPtr::~SmartActuatorPtr()
414 {
415         m_actuator->Release();
416 }
417
418
419
420 bool SmartActuatorPtr::operator <(const SmartActuatorPtr& other) const
421 {
422         
423         return m_actuator->LessComparedTo(*other);
424 }
425
426
427
428 bool SmartActuatorPtr::operator ==(const SmartActuatorPtr& other) const
429 {
430         bool result2 = other->LessComparedTo(m_actuator);
431         return (m_actuator->LessComparedTo(*other) && result2);
432 }
433
434
435
436 SCA_IActuator*  SmartActuatorPtr::operator->() const
437 {
438         return m_actuator;
439 }
440
441
442
443 SCA_IActuator*   SmartActuatorPtr::operator*() const
444 {
445         return m_actuator;
446 }
447
448
449
450 SmartControllerPtr::SmartControllerPtr(const SmartControllerPtr& copy)
451 {
452         this->m_controller = copy.m_controller;
453         this->m_controller->AddRef();
454 }
455
456
457
458 SmartControllerPtr::SmartControllerPtr(SCA_IController* contr,int dummy)
459 : m_controller(contr)
460 {
461         m_controller->AddRef();
462 }
463
464
465
466 SmartControllerPtr::~SmartControllerPtr()
467 {
468         m_controller->Release();
469 }
470
471
472
473 bool    SmartControllerPtr::operator <(const SmartControllerPtr& other) const
474 {
475         return m_controller->LessComparedTo(*other);
476 }
477
478
479
480 bool    SmartControllerPtr::operator ==(const SmartControllerPtr& other) const
481 {
482         return (m_controller->LessComparedTo(*other) && other->LessComparedTo(m_controller));
483 }
484
485
486
487 SCA_IController*        SmartControllerPtr::operator->() const
488 {
489         return m_controller;
490 }
491
492
493
494 SCA_IController*        SmartControllerPtr::operator*() const
495 {
496         return m_controller;
497 }
498
499