BGE logic patch: fix another incompatibility with YF.
[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(PyTypeObject* T): CValue(T), m_initState(0), m_state(0), m_firstState(NULL)
45
46 {
47         m_suspended = false;
48 }
49
50 SCA_IObject::~SCA_IObject()
51 {
52         SCA_SensorList::iterator its;
53         for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its)
54         {
55                 //Use Delete for sensor to ensure proper cleaning
56                 (*its)->Delete();
57                 //((CValue*)(*its))->Release();
58         }
59         SCA_ControllerList::iterator itc; 
60         for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
61         {
62                 //Use Delete for controller to ensure proper cleaning (expression controller)
63                 (*itc)->Delete();
64                 //((CValue*)(*itc))->Release();
65         }
66         SCA_ActuatorList::iterator ita;
67         for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita)
68         {
69                 (*ita)->UnlinkObject(this);
70         }
71         for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
72         {
73                 (*ita)->Delete();
74         }
75
76         //T_InterpolatorList::iterator i;
77         //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
78         //      delete *i;
79         //}
80 }
81
82 void SCA_IObject::AddSensor(SCA_ISensor* act)
83 {
84         act->AddRef();
85         m_sensors.push_back(act);
86 }
87
88
89
90 void SCA_IObject::AddController(SCA_IController* act)
91 {
92         act->AddRef();
93         m_controllers.push_back(act);
94 }
95
96
97
98 void SCA_IObject::AddActuator(SCA_IActuator* act)
99 {
100         act->AddRef();
101         m_actuators.push_back(act);
102 }
103
104 void SCA_IObject::RegisterActuator(SCA_IActuator* act)
105 {
106         // don't increase ref count, it would create dead lock
107         m_registeredActuators.push_back(act);
108 }
109
110 void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
111 {
112         SCA_ActuatorList::iterator ita;
113         for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ++ita)
114         {
115                 if ((*ita) == act) {
116                         (*ita) = m_registeredActuators.back();
117                         m_registeredActuators.pop_back();
118                         break;
119                 }
120         }
121 }
122
123 void SCA_IObject::ReParentLogic()
124 {
125         SCA_ActuatorList& oldactuators  = GetActuators();
126         int act = 0;
127         SCA_ActuatorList::iterator ita;
128         for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
129         {
130                 SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
131                 newactuator->ReParent(this);
132                 // actuators are initially not connected to any controller
133                 newactuator->SetActive(false);
134                 newactuator->ClrLink();
135                 oldactuators[act++] = newactuator;
136         }
137
138         SCA_ControllerList& oldcontrollers = GetControllers();
139         int con = 0;
140         SCA_ControllerList::iterator itc;
141         for (itc = oldcontrollers.begin(); !(itc==oldcontrollers.end()); ++itc)
142         {
143                 SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
144                 newcontroller->ReParent(this);
145                 newcontroller->SetActive(false);
146                 oldcontrollers[con++]=newcontroller;
147
148         }
149         // convert sensors last so that actuators are already available for Actuator sensor
150         SCA_SensorList& oldsensors = GetSensors();
151         int sen = 0;
152         SCA_SensorList::iterator its;
153         for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
154         {
155                 SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
156                 newsensor->ReParent(this);
157                 newsensor->SetActive(false);
158                 // sensors are initially not connected to any controller
159                 newsensor->ClrLink();
160                 oldsensors[sen++] = newsensor;
161         }
162
163         // a new object cannot be client of any actuator
164         m_registeredActuators.clear();
165                 
166 }
167
168
169
170 SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname)
171 {
172         SCA_ISensor* foundsensor = NULL;
173
174         for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());++its)
175         {
176                 if ((*its)->GetName() == sensorname)
177                 {
178                         foundsensor = (*its);
179                         break;
180                 }
181         }
182         return foundsensor;
183 }
184
185
186
187 SCA_IController* SCA_IObject::FindController(const STR_String& controllername)
188 {
189         SCA_IController* foundcontroller = NULL;
190
191         for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());++itc)
192         {
193                 if ((*itc)->GetName() == controllername)
194                 {
195                         foundcontroller = (*itc);
196                         break;
197                 }       
198         }
199         return foundcontroller;
200 }
201
202
203
204 SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
205 {
206         SCA_IActuator* foundactuator = NULL;
207
208         for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());++ita)
209         {
210                 if ((*ita)->GetName() == actuatorname)
211                 {
212                         foundactuator = (*ita);
213                         break;
214                 }
215         }
216
217         return foundactuator;
218 }
219
220
221
222 #if 0
223 const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist)
224 {
225         bool error = false;
226         m_sDummy = MT_Vector3(0,0,0);
227         if (pylist->ob_type == &CListValue::Type)
228         {
229                 CListValue* listval = (CListValue*) pylist;
230                 int numelem = listval->GetCount();
231                 if ( numelem <= 3)
232                 {
233                         int index;
234                         for (index = 0;index<numelem;index++)
235                         {
236                                 m_sDummy[index] = listval->GetValue(index)->GetNumber();
237                         }
238                 }       else
239                 {
240                         error = true;
241                 }
242                 
243         } else
244         {
245                 
246                 // assert the list is long enough...
247                 int numitems = PyList_Size(pylist);
248                 if (numitems <= 3)
249                 {
250                         int index;
251                         for (index=0;index<numitems;index++)
252                         {
253                                 m_sDummy[index] = PyFloat_AsDouble(PyList_GetItem(pylist,index));
254                         }
255                 }
256                 else
257                 {
258                         error = true;
259                 }
260
261         }
262         return m_sDummy;
263 }
264 #endif
265
266 void SCA_IObject::Suspend()
267 {
268         if ((!m_ignore_activity_culling) 
269                 && (!m_suspended))  {
270                 m_suspended = true;
271                 /* flag suspend for all sensors */
272                 SCA_SensorList::iterator i = m_sensors.begin();
273                 while (i != m_sensors.end()) {
274                         (*i)->Suspend();
275                         ++i;
276                 }
277         }
278 }
279
280
281
282 void SCA_IObject::Resume(void)
283 {
284         if (m_suspended) {
285                 m_suspended = false;
286                 /* unflag suspend for all sensors */
287                 SCA_SensorList::iterator i = m_sensors.begin();
288                 while (i != m_sensors.end()) {
289                         (*i)->Resume();
290                         ++i;
291                 }
292         }
293 }
294
295 void SCA_IObject::SetState(unsigned int state)
296 {
297         unsigned int tmpstate;
298         SCA_ControllerList::iterator contit;
299
300         // we will update the state in two steps:
301         // 1) set the new state bits that are 1
302         // 2) clr the new state bits that are 0
303         // This to ensure continuity if a sensor is attached to two states
304         // that are switching state: no need to deactive and reactive the sensor 
305         
306         tmpstate = m_state | state;
307         if (tmpstate != m_state)
308         {
309                 // update the status of the controllers
310                 for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
311                 {
312                         (*contit)->ApplyState(tmpstate);
313                 }
314         }
315         m_state = state;
316         if (m_state != tmpstate)
317         {
318                 for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
319                 {
320                         (*contit)->ApplyState(m_state);
321                 }
322         }
323 }
324
325
326
327 /* ------------------------------------------------------------------------- */
328 /* Python functions                                                          */
329 /* ------------------------------------------------------------------------- */
330
331 /* Integration hooks ------------------------------------------------------- */
332 PyTypeObject SCA_IObject::Type = {
333 #if (PY_VERSION_HEX >= 0x02060000)
334         PyVarObject_HEAD_INIT(NULL, 0)
335 #else
336         /* python 2.5 and below */
337         PyObject_HEAD_INIT( NULL )  /* required py macro */
338         0,                          /* ob_size */
339 #endif
340         "SCA_IObject",
341         sizeof(PyObjectPlus_Proxy),
342         0,
343         py_base_dealloc,
344         0,
345         0,
346         0,
347         0,
348         py_base_repr,
349         0,0,0,0,0,0,
350         py_base_getattro,
351         py_base_setattro,
352         0,0,0,0,0,0,0,0,0,
353         Methods
354 };
355
356
357
358 PyParentObject SCA_IObject::Parents[] = {
359         &SCA_IObject::Type,
360         &CValue::Type,
361         NULL
362 };
363
364
365
366 PyMethodDef SCA_IObject::Methods[] = {
367         //{"setOrientation", (PyCFunction) SCA_IObject::sPySetOrientation, METH_VARARGS},
368         //{"getOrientation", (PyCFunction) SCA_IObject::sPyGetOrientation, METH_VARARGS},
369         {NULL,NULL} //Sentinel
370 };
371
372 PyAttributeDef SCA_IObject::Attributes[] = {
373         { NULL }        //Sentinel
374 };
375
376
377 PyObject* SCA_IObject::py_getattro(PyObject *attr) {
378         py_getattro_up(CValue);
379 }
380
381 PyObject* SCA_IObject::py_getattro_dict() {
382         py_getattro_dict_up(CValue);
383 }