Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / source / gameengine / GameLogic / SCA_IObject.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28 #include <iostream>
29 #include <algorithm>
30
31 #include "SCA_IObject.h"
32 #include "SCA_ISensor.h"
33 #include "SCA_IController.h"
34 #include "SCA_IActuator.h"
35 #include "MT_Point3.h"
36 #include "ListValue.h"
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
43 SG_QList SCA_IObject::m_activeBookmarkedControllers;
44
45 SCA_IObject::SCA_IObject():
46         CValue(),
47         m_initState(0),
48         m_state(0),
49         m_firstState(NULL)
50 {
51         m_suspended = false;
52 }
53
54 SCA_IObject::~SCA_IObject()
55 {
56         SCA_SensorList::iterator its;
57         for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its)
58         {
59                 //Use Delete for sensor to ensure proper cleaning
60                 (*its)->Delete();
61                 //((CValue*)(*its))->Release();
62         }
63         SCA_ControllerList::iterator itc; 
64         for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
65         {
66                 //Use Delete for controller to ensure proper cleaning (expression controller)
67                 (*itc)->Delete();
68                 //((CValue*)(*itc))->Release();
69         }
70         SCA_ActuatorList::iterator ita;
71         for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita)
72         {
73                 (*ita)->UnlinkObject(this);
74         }
75         for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
76         {
77                 (*ita)->Delete();
78         }
79
80         SCA_ObjectList::iterator ito;
81         for (ito = m_registeredObjects.begin(); !(ito==m_registeredObjects.end()); ++ito)
82         {
83                 (*ito)->UnlinkObject(this);
84         }
85
86         //T_InterpolatorList::iterator i;
87         //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
88         //      delete *i;
89         //}
90 }
91
92 void SCA_IObject::AddSensor(SCA_ISensor* act)
93 {
94         act->AddRef();
95         m_sensors.push_back(act);
96 }
97
98
99
100 void SCA_IObject::AddController(SCA_IController* act)
101 {
102         act->AddRef();
103         m_controllers.push_back(act);
104 }
105
106
107
108 void SCA_IObject::AddActuator(SCA_IActuator* act)
109 {
110         act->AddRef();
111         m_actuators.push_back(act);
112 }
113
114 void SCA_IObject::RegisterActuator(SCA_IActuator* act)
115 {
116         // don't increase ref count, it would create dead lock
117         m_registeredActuators.push_back(act);
118 }
119
120 void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
121 {
122         SCA_ActuatorList::iterator ita;
123         for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ++ita)
124         {
125                 if ((*ita) == act) {
126                         (*ita) = m_registeredActuators.back();
127                         m_registeredActuators.pop_back();
128                         break;
129                 }
130         }
131 }
132
133 void SCA_IObject::RegisterObject(SCA_IObject* obj)
134 {
135         // one object may be registered multiple times via constraint target
136         // store multiple reference, this will serve as registration counter
137         m_registeredObjects.push_back(obj);
138 }
139
140 void SCA_IObject::UnregisterObject(SCA_IObject* obj)
141 {
142         SCA_ObjectList::iterator ito;
143         for (ito = m_registeredObjects.begin(); ito != m_registeredObjects.end(); ++ito)
144         {
145                 if ((*ito) == obj) {
146                         (*ito) = m_registeredObjects.back();
147                         m_registeredObjects.pop_back();
148                         break;
149                 }
150         }
151 }
152
153 void SCA_IObject::ReParentLogic()
154 {
155         SCA_ActuatorList& oldactuators  = GetActuators();
156         int act = 0;
157         SCA_ActuatorList::iterator ita;
158         for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
159         {
160                 SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
161                 newactuator->ReParent(this);
162                 // actuators are initially not connected to any controller
163                 newactuator->SetActive(false);
164                 newactuator->ClrLink();
165                 oldactuators[act++] = newactuator;
166         }
167
168         SCA_ControllerList& oldcontrollers = GetControllers();
169         int con = 0;
170         SCA_ControllerList::iterator itc;
171         for (itc = oldcontrollers.begin(); !(itc==oldcontrollers.end()); ++itc)
172         {
173                 SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
174                 newcontroller->ReParent(this);
175                 newcontroller->SetActive(false);
176                 oldcontrollers[con++]=newcontroller;
177
178         }
179         // convert sensors last so that actuators are already available for Actuator sensor
180         SCA_SensorList& oldsensors = GetSensors();
181         int sen = 0;
182         SCA_SensorList::iterator its;
183         for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
184         {
185                 SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
186                 newsensor->ReParent(this);
187                 newsensor->SetActive(false);
188                 // sensors are initially not connected to any controller
189                 newsensor->ClrLink();
190                 oldsensors[sen++] = newsensor;
191         }
192
193         // a new object cannot be client of any actuator
194         m_registeredActuators.clear();
195         m_registeredObjects.clear();
196 }
197
198
199
200 SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname)
201 {
202         SCA_ISensor* foundsensor = NULL;
203
204         for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());++its)
205         {
206                 if ((*its)->GetName() == sensorname)
207                 {
208                         foundsensor = (*its);
209                         break;
210                 }
211         }
212         return foundsensor;
213 }
214
215
216
217 SCA_IController* SCA_IObject::FindController(const STR_String& controllername)
218 {
219         SCA_IController* foundcontroller = NULL;
220
221         for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());++itc)
222         {
223                 if ((*itc)->GetName() == controllername)
224                 {
225                         foundcontroller = (*itc);
226                         break;
227                 }       
228         }
229         return foundcontroller;
230 }
231
232
233
234 SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
235 {
236         SCA_IActuator* foundactuator = NULL;
237
238         for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());++ita)
239         {
240                 if ((*ita)->GetName() == actuatorname)
241                 {
242                         foundactuator = (*ita);
243                         break;
244                 }
245         }
246
247         return foundactuator;
248 }
249
250
251 void SCA_IObject::Suspend()
252 {
253         if ((!m_ignore_activity_culling) 
254                 && (!m_suspended))  {
255                 m_suspended = true;
256                 /* flag suspend for all sensors */
257                 SCA_SensorList::iterator i = m_sensors.begin();
258                 while (i != m_sensors.end()) {
259                         (*i)->Suspend();
260                         ++i;
261                 }
262         }
263 }
264
265
266
267 void SCA_IObject::Resume(void)
268 {
269         if (m_suspended) {
270                 m_suspended = false;
271                 /* unflag suspend for all sensors */
272                 SCA_SensorList::iterator i = m_sensors.begin();
273                 while (i != m_sensors.end()) {
274                         (*i)->Resume();
275                         ++i;
276                 }
277         }
278 }
279
280 void SCA_IObject::SetState(unsigned int state)
281 {
282         unsigned int tmpstate;
283         SCA_ControllerList::iterator contit;
284
285         // we will update the state in two steps:
286         // 1) set the new state bits that are 1
287         // 2) clr the new state bits that are 0
288         // This to ensure continuity if a sensor is attached to two states
289         // that are switching state: no need to deactive and reactive the sensor 
290         
291         tmpstate = m_state | state;
292         if (tmpstate != m_state)
293         {
294                 // update the status of the controllers
295                 for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
296                 {
297                         (*contit)->ApplyState(tmpstate);
298                 }
299         }
300         m_state = state;
301         if (m_state != tmpstate)
302         {
303                 for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
304                 {
305                         (*contit)->ApplyState(m_state);
306                 }
307         }
308 }
309
310
311
312 /* ------------------------------------------------------------------------- */
313 /* Python functions                                                          */
314 /* ------------------------------------------------------------------------- */
315
316 /* Integration hooks ------------------------------------------------------- */
317 PyTypeObject SCA_IObject::Type = {
318         PyVarObject_HEAD_INIT(NULL, 0)
319         "SCA_IObject",
320         sizeof(PyObjectPlus_Proxy),
321         0,
322         py_base_dealloc,
323         0,
324         0,
325         0,
326         0,
327         py_base_repr,
328         0,0,0,0,0,0,0,0,0,
329         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
330         0,0,0,0,0,0,0,
331         Methods,
332         0,
333         0,
334         &CValue::Type,
335         0,0,0,0,0,0,
336         py_base_new
337 };
338
339 PyMethodDef SCA_IObject::Methods[] = {
340         //{"setOrientation", (PyCFunction) SCA_IObject::sPySetOrientation, METH_VARARGS},
341         //{"getOrientation", (PyCFunction) SCA_IObject::sPyGetOrientation, METH_VARARGS},
342         {NULL,NULL} //Sentinel
343 };
344
345 PyAttributeDef SCA_IObject::Attributes[] = {
346         { NULL }        //Sentinel
347 };