svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r21899:21908
[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
30 #include "SCA_IObject.h"
31 #include "SCA_ISensor.h"
32 #include "SCA_IController.h"
33 #include "SCA_IActuator.h"
34 #include "MT_Point3.h"
35 #include "ListValue.h"
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
42 SG_QList SCA_IObject::m_activeBookmarkedControllers;
43
44 SCA_IObject::SCA_IObject():
45         CValue(),
46         m_initState(0),
47         m_state(0),
48         m_firstState(NULL)
49 {
50         m_suspended = false;
51 }
52
53 SCA_IObject::~SCA_IObject()
54 {
55         SCA_SensorList::iterator its;
56         for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its)
57         {
58                 //Use Delete for sensor to ensure proper cleaning
59                 (*its)->Delete();
60                 //((CValue*)(*its))->Release();
61         }
62         SCA_ControllerList::iterator itc; 
63         for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
64         {
65                 //Use Delete for controller to ensure proper cleaning (expression controller)
66                 (*itc)->Delete();
67                 //((CValue*)(*itc))->Release();
68         }
69         SCA_ActuatorList::iterator ita;
70         for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita)
71         {
72                 (*ita)->UnlinkObject(this);
73         }
74         for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
75         {
76                 (*ita)->Delete();
77         }
78
79         //T_InterpolatorList::iterator i;
80         //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
81         //      delete *i;
82         //}
83 }
84
85 void SCA_IObject::AddSensor(SCA_ISensor* act)
86 {
87         act->AddRef();
88         m_sensors.push_back(act);
89 }
90
91
92
93 void SCA_IObject::AddController(SCA_IController* act)
94 {
95         act->AddRef();
96         m_controllers.push_back(act);
97 }
98
99
100
101 void SCA_IObject::AddActuator(SCA_IActuator* act)
102 {
103         act->AddRef();
104         m_actuators.push_back(act);
105 }
106
107 void SCA_IObject::RegisterActuator(SCA_IActuator* act)
108 {
109         // don't increase ref count, it would create dead lock
110         m_registeredActuators.push_back(act);
111 }
112
113 void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
114 {
115         SCA_ActuatorList::iterator ita;
116         for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ++ita)
117         {
118                 if ((*ita) == act) {
119                         (*ita) = m_registeredActuators.back();
120                         m_registeredActuators.pop_back();
121                         break;
122                 }
123         }
124 }
125
126 void SCA_IObject::ReParentLogic()
127 {
128         SCA_ActuatorList& oldactuators  = GetActuators();
129         int act = 0;
130         SCA_ActuatorList::iterator ita;
131         for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
132         {
133                 SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
134                 newactuator->ReParent(this);
135                 // actuators are initially not connected to any controller
136                 newactuator->SetActive(false);
137                 newactuator->ClrLink();
138                 oldactuators[act++] = newactuator;
139         }
140
141         SCA_ControllerList& oldcontrollers = GetControllers();
142         int con = 0;
143         SCA_ControllerList::iterator itc;
144         for (itc = oldcontrollers.begin(); !(itc==oldcontrollers.end()); ++itc)
145         {
146                 SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
147                 newcontroller->ReParent(this);
148                 newcontroller->SetActive(false);
149                 oldcontrollers[con++]=newcontroller;
150
151         }
152         // convert sensors last so that actuators are already available for Actuator sensor
153         SCA_SensorList& oldsensors = GetSensors();
154         int sen = 0;
155         SCA_SensorList::iterator its;
156         for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
157         {
158                 SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
159                 newsensor->ReParent(this);
160                 newsensor->SetActive(false);
161                 // sensors are initially not connected to any controller
162                 newsensor->ClrLink();
163                 oldsensors[sen++] = newsensor;
164         }
165
166         // a new object cannot be client of any actuator
167         m_registeredActuators.clear();
168                 
169 }
170
171
172
173 SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname)
174 {
175         SCA_ISensor* foundsensor = NULL;
176
177         for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());++its)
178         {
179                 if ((*its)->GetName() == sensorname)
180                 {
181                         foundsensor = (*its);
182                         break;
183                 }
184         }
185         return foundsensor;
186 }
187
188
189
190 SCA_IController* SCA_IObject::FindController(const STR_String& controllername)
191 {
192         SCA_IController* foundcontroller = NULL;
193
194         for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());++itc)
195         {
196                 if ((*itc)->GetName() == controllername)
197                 {
198                         foundcontroller = (*itc);
199                         break;
200                 }       
201         }
202         return foundcontroller;
203 }
204
205
206
207 SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
208 {
209         SCA_IActuator* foundactuator = NULL;
210
211         for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());++ita)
212         {
213                 if ((*ita)->GetName() == actuatorname)
214                 {
215                         foundactuator = (*ita);
216                         break;
217                 }
218         }
219
220         return foundactuator;
221 }
222
223
224 void SCA_IObject::Suspend()
225 {
226         if ((!m_ignore_activity_culling) 
227                 && (!m_suspended))  {
228                 m_suspended = true;
229                 /* flag suspend for all sensors */
230                 SCA_SensorList::iterator i = m_sensors.begin();
231                 while (i != m_sensors.end()) {
232                         (*i)->Suspend();
233                         ++i;
234                 }
235         }
236 }
237
238
239
240 void SCA_IObject::Resume(void)
241 {
242         if (m_suspended) {
243                 m_suspended = false;
244                 /* unflag suspend for all sensors */
245                 SCA_SensorList::iterator i = m_sensors.begin();
246                 while (i != m_sensors.end()) {
247                         (*i)->Resume();
248                         ++i;
249                 }
250         }
251 }
252
253 void SCA_IObject::SetState(unsigned int state)
254 {
255         unsigned int tmpstate;
256         SCA_ControllerList::iterator contit;
257
258         // we will update the state in two steps:
259         // 1) set the new state bits that are 1
260         // 2) clr the new state bits that are 0
261         // This to ensure continuity if a sensor is attached to two states
262         // that are switching state: no need to deactive and reactive the sensor 
263         
264         tmpstate = m_state | state;
265         if (tmpstate != m_state)
266         {
267                 // update the status of the controllers
268                 for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
269                 {
270                         (*contit)->ApplyState(tmpstate);
271                 }
272         }
273         m_state = state;
274         if (m_state != tmpstate)
275         {
276                 for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
277                 {
278                         (*contit)->ApplyState(m_state);
279                 }
280         }
281 }
282
283
284
285 /* ------------------------------------------------------------------------- */
286 /* Python functions                                                          */
287 /* ------------------------------------------------------------------------- */
288
289 /* Integration hooks ------------------------------------------------------- */
290 PyTypeObject SCA_IObject::Type = {
291 #if (PY_VERSION_HEX >= 0x02060000)
292         PyVarObject_HEAD_INIT(NULL, 0)
293 #else
294         /* python 2.5 and below */
295         PyObject_HEAD_INIT( NULL )  /* required py macro */
296         0,                          /* ob_size */
297 #endif
298         "SCA_IObject",
299         sizeof(PyObjectPlus_Proxy),
300         0,
301         py_base_dealloc,
302         0,
303         0,
304         0,
305         0,
306         py_base_repr,
307         0,0,0,0,0,0,0,0,0,
308         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
309         0,0,0,0,0,0,0,
310         Methods,
311         0,
312         0,
313         &CValue::Type,
314         0,0,0,0,0,0,
315         py_base_new
316 };
317
318 PyMethodDef SCA_IObject::Methods[] = {
319         //{"setOrientation", (PyCFunction) SCA_IObject::sPySetOrientation, METH_VARARGS},
320         //{"getOrientation", (PyCFunction) SCA_IObject::sPyGetOrientation, METH_VARARGS},
321         {NULL,NULL} //Sentinel
322 };
323
324 PyAttributeDef SCA_IObject::Attributes[] = {
325         { NULL }        //Sentinel
326 };