BGE Python api
[blender.git] / source / gameengine / Ketsji / KX_SceneActuator.cpp
1 /**
2 * Set scene/camera stuff
3 *
4 * $Id$
5 *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30 */
31
32 #include "SCA_IActuator.h"
33 #include "KX_SceneActuator.h"
34 #include <iostream>
35 #include "KX_Scene.h"
36 #include "KX_Camera.h"
37 #include "KX_KetsjiEngine.h"
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 /* ------------------------------------------------------------------------- */
44 /* Native functions                                                          */
45 /* ------------------------------------------------------------------------- */
46
47 KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj, 
48                                                                    int mode,
49                                                                    KX_Scene *scene,
50                                                                    KX_KetsjiEngine* ketsjiEngine,
51                                                                    const STR_String& nextSceneName,
52                                                                    KX_Camera* camera,
53                                                                    PyTypeObject* T)
54                                                                    : SCA_IActuator(gameobj, T)
55 {
56         m_mode = mode;
57         m_scene  = scene;
58         m_KetsjiEngine=ketsjiEngine;
59         m_camera = camera;
60         m_nextSceneName = nextSceneName;
61         if (m_camera)
62                 m_camera->RegisterActuator(this);
63 } /* End of constructor */
64
65
66
67 KX_SceneActuator::~KX_SceneActuator()
68
69         if (m_camera)
70                 m_camera->UnregisterActuator(this);
71 } /* end of destructor */
72
73
74
75 CValue* KX_SceneActuator::GetReplica()
76 {
77         KX_SceneActuator* replica = new KX_SceneActuator(*this);
78         replica->ProcessReplica();
79         // this will copy properties and so on...
80         CValue::AddDataToReplica(replica);
81         
82         return replica;
83 }
84
85 void KX_SceneActuator::ProcessReplica()
86 {
87         if (m_camera)
88                 m_camera->RegisterActuator(this);
89         SCA_IActuator::ProcessReplica();
90 }
91
92 bool KX_SceneActuator::UnlinkObject(SCA_IObject* clientobj)
93 {
94         if (clientobj == (SCA_IObject*)m_camera)
95         {
96                 // this object is being deleted, we cannot continue to track it.
97                 m_camera = NULL;
98                 return true;
99         }
100         return false;
101 }
102
103 void KX_SceneActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
104 {
105         void **h_obj = (*obj_map)[m_camera];
106         if (h_obj) {
107                 if (m_camera)
108                         m_camera->UnregisterActuator(this);
109                 m_camera = (KX_Camera*)(*h_obj);
110                 m_camera->RegisterActuator(this);
111         }
112 }
113
114
115 bool KX_SceneActuator::Update()
116 {
117         // bool result = false; /*unused*/
118         bool bNegativeEvent = IsNegativeEvent();
119         RemoveAllEvents();
120
121         if (bNegativeEvent)
122                 return false; // do nothing on negative events
123
124         switch (m_mode)
125         {
126         case KX_SCENE_RESTART:
127                 {
128                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_scene->GetName());
129                         break;
130                 }
131         case KX_SCENE_SET_CAMERA:
132                 if (m_camera)
133                 {
134                         m_scene->SetActiveCamera(m_camera);
135                 }
136                 else
137                 {
138                         // if no camera is set and the parent object is a camera, use it as the camera
139                         SCA_IObject* parent = GetParent();
140                         if (parent->isA(&KX_Camera::Type))
141                         {
142                                 m_scene->SetActiveCamera((KX_Camera*)parent);
143                         }
144                 }
145                 break;
146         default:
147                 break;
148         }
149         
150         if (!m_nextSceneName.Length())
151                 return false;
152         
153         switch (m_mode)
154         {
155         case KX_SCENE_SET_SCENE:
156                 {
157                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_nextSceneName);
158                         break;
159                 }
160         case KX_SCENE_ADD_FRONT_SCENE:
161                 {
162                         bool overlay=true;
163                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
164                         break;
165                 }
166         case KX_SCENE_ADD_BACK_SCENE:
167                 {
168                         bool overlay=false;
169                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
170                         break;
171                 }
172         case KX_SCENE_REMOVE_SCENE:
173                 {
174                         m_KetsjiEngine->RemoveScene(m_nextSceneName);
175                         break;
176                 }
177         case KX_SCENE_SUSPEND:
178                 {
179                         m_KetsjiEngine->SuspendScene(m_nextSceneName);
180                         break;
181                 }
182         case KX_SCENE_RESUME:
183                 {
184                         m_KetsjiEngine->ResumeScene(m_nextSceneName);
185                         break;
186                 }
187         default:
188                 ; /* do nothing? this is an internal error !!! */
189         }
190         
191         return false;
192 }
193
194
195
196 /*  returns a camera if the name is valid */
197 KX_Camera* KX_SceneActuator::FindCamera(char *camName)
198 {
199         KX_SceneList* sl = m_KetsjiEngine->CurrentScenes();
200         STR_String name = STR_String(camName);
201         KX_SceneList::iterator it = sl->begin();
202         KX_Camera* cam = NULL;
203
204         while ((it != sl->end()) && (!cam))
205         {
206                 cam = (*it)->FindCamera(name);
207                 it++;
208         }
209
210         return cam;
211 }
212
213
214
215 KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
216 {
217         return m_KetsjiEngine->FindScene(sceneName);
218 }
219
220
221
222
223 /* ------------------------------------------------------------------------- */
224 /* Python functions                                                          */
225 /* ------------------------------------------------------------------------- */
226
227 /* Integration hooks ------------------------------------------------------- */
228 PyTypeObject KX_SceneActuator::Type = {
229         PyObject_HEAD_INIT(&PyType_Type)
230                 0,
231                 "KX_SceneActuator",
232                 sizeof(KX_SceneActuator),
233                 0,
234                 PyDestructor,
235                 0,
236                 __getattr,
237                 __setattr,
238                 0,
239                 __repr,
240                 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
241                 Methods
242 };
243
244
245
246 PyParentObject KX_SceneActuator::Parents[] =
247 {
248         &KX_SceneActuator::Type,
249                 &SCA_IActuator::Type,
250                 &SCA_ILogicBrick::Type,
251                 &CValue::Type,
252                 NULL
253 };
254
255
256
257 PyMethodDef KX_SceneActuator::Methods[] =
258 {
259         //Deprecated functions ------>
260         {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, (PY_METHODCHAR)SetUseRestart_doc},
261         {"setScene",      (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, (PY_METHODCHAR)SetScene_doc},
262         {"setCamera",     (PyCFunction) KX_SceneActuator::sPySetCamera, METH_VARARGS, (PY_METHODCHAR)SetCamera_doc},
263         {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_VARARGS, (PY_METHODCHAR)GetUseRestart_doc},
264         {"getScene",      (PyCFunction) KX_SceneActuator::sPyGetScene, METH_VARARGS, (PY_METHODCHAR)GetScene_doc},
265         {"getCamera",     (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_VARARGS, (PY_METHODCHAR)GetCamera_doc},
266         //<----- Deprecated
267         {NULL,NULL} //Sentinel
268 };
269
270 PyAttributeDef KX_SceneActuator::Attributes[] = {
271         KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName),
272         KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera),
273         { NULL }        //Sentinel
274 };
275
276 PyObject* KX_SceneActuator::_getattr(const char *attr)
277 {
278         PyObject* object = _getattr_self(Attributes, this, attr);
279         if (object != NULL)
280                 return object;
281         _getattr_up(SCA_IActuator);
282 }
283
284 int KX_SceneActuator::_setattr(const char *attr, PyObject *value)
285 {
286         int ret = _setattr_self(Attributes, this, attr, value);
287         if (ret >= 0)
288                 return ret;
289         return SCA_IActuator::_setattr(attr, value);
290 }
291
292 PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
293 {
294         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
295         if (!actuator->m_camera)
296                 Py_RETURN_NONE;
297         actuator->m_camera->AddRef();
298         return actuator->m_camera;
299 }
300
301 int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
302 {
303         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
304         KX_Camera *camOb;
305
306         if (PyObject_TypeCheck(value, &KX_Camera::Type)) 
307         {
308                 camOb = static_cast<KX_Camera*>(value);
309                 if (actuator->m_camera)
310                         actuator->m_camera->UnregisterActuator(actuator);
311                 actuator->m_camera = camOb;
312                 if (actuator->m_camera)
313                         actuator->m_camera->RegisterActuator(actuator);
314                 return 0;
315         }
316
317         if (PyString_Check(value))
318         {
319                 char *camName = PyString_AsString(value);
320
321                 camOb = actuator->FindCamera(camName);
322                 if (camOb) 
323                 {
324                         if (actuator->m_camera)
325                                 actuator->m_camera->UnregisterActuator(actuator);
326                         actuator->m_camera = camOb;
327                         actuator->m_camera->RegisterActuator(actuator);
328                         return 0;
329                 }
330                 PyErr_SetString(PyExc_TypeError, "not a valid camera name");
331                 return 1;
332         }
333         PyErr_SetString(PyExc_TypeError, "expected a string or a camera object reference");
334         return 1;
335 }
336
337
338 /* 2. setUseRestart--------------------------------------------------------- */
339 const char KX_SceneActuator::SetUseRestart_doc[] = 
340 "setUseRestart(flag)\n"
341 "\t- flag: 0 or 1.\n"
342 "\tSet flag to 1 to restart the scene.\n" ;
343 PyObject* KX_SceneActuator::PySetUseRestart(PyObject* self, 
344                                                                                         PyObject* args, 
345                                                                                         PyObject* kwds)
346 {
347         ShowDeprecationWarning("setUseRestart()", "(no replacement)");
348         int boolArg;
349         
350         if (!PyArg_ParseTuple(args, "i", &boolArg))
351         {
352                 return NULL;
353         }
354         
355         m_restart = boolArg != 0;
356         
357         Py_RETURN_NONE;
358 }
359
360
361
362 /* 3. getUseRestart:                                                         */
363 const char KX_SceneActuator::GetUseRestart_doc[] = 
364 "getUseRestart()\n"
365 "\tReturn whether the scene will be restarted.\n" ;
366 PyObject* KX_SceneActuator::PyGetUseRestart(PyObject* self, 
367                                                                                         PyObject* args, 
368                                                                                         PyObject* kwds)
369 {
370         ShowDeprecationWarning("getUseRestart()", "(no replacement)");
371         return PyInt_FromLong(!(m_restart == 0));
372 }
373
374
375
376 /* 4. set scene------------------------------------------------------------- */
377 const char KX_SceneActuator::SetScene_doc[] = 
378 "setScene(scene)\n"
379 "\t- scene: string\n"
380 "\tSet the name of scene the actuator will switch to.\n" ;
381 PyObject* KX_SceneActuator::PySetScene(PyObject* self, 
382                                                                            PyObject* args, 
383                                                                            PyObject* kwds)
384 {
385         ShowDeprecationWarning("setScene()", "the scene property");
386         /* one argument: a scene, ignore the rest */
387         char *scene_name;
388
389         if(!PyArg_ParseTuple(args, "s", &scene_name))
390         {
391                 return NULL;
392         }
393
394         /* Scene switch is done by name. */
395         m_nextSceneName = scene_name;
396
397         Py_RETURN_NONE;
398 }
399
400
401
402 /* 5. getScene:                                                              */
403 const char KX_SceneActuator::GetScene_doc[] = 
404 "getScene()\n"
405 "\tReturn the name of the scene the actuator wants to switch to.\n" ;
406 PyObject* KX_SceneActuator::PyGetScene(PyObject* self, 
407                                                                            PyObject* args, 
408                                                                            PyObject* kwds)
409 {
410         ShowDeprecationWarning("getScene()", "the scene property");
411         return PyString_FromString(m_nextSceneName);
412 }
413
414
415
416 /* 6. set camera------------------------------------------------------------ */
417 const char KX_SceneActuator::SetCamera_doc[] = 
418 "setCamera(camera)\n"
419 "\t- camera: string\n"
420 "\tSet the camera to switch to.\n" ;
421 PyObject* KX_SceneActuator::PySetCamera(PyObject* self, 
422                                                                                 PyObject* args, 
423                                                                                 PyObject* kwds)
424 {
425         ShowDeprecationWarning("setCamera()", "the camera property");
426         PyObject *cam;
427         if (PyArg_ParseTuple(args, "O!", &KX_Camera::Type, &cam))
428         {
429                 if (m_camera)
430                         m_camera->UnregisterActuator(this);
431                 m_camera = (KX_Camera*) cam;
432                 if (m_camera)
433                         m_camera->RegisterActuator(this);
434                 Py_RETURN_NONE;
435         }
436         PyErr_Clear();
437
438         /* one argument: a scene, ignore the rest */
439         char *camName;
440         if(!PyArg_ParseTuple(args, "s", &camName))
441         {
442                 return NULL;
443         }
444
445         KX_Camera *camOb = FindCamera(camName);
446         if (camOb) 
447         {
448                 if (m_camera)
449                         m_camera->UnregisterActuator(this);
450                 m_camera = camOb;
451                 m_camera->RegisterActuator(this);
452         }
453
454         Py_RETURN_NONE;
455 }
456
457
458
459 /* 7. getCamera:                                                             */
460 const char KX_SceneActuator::GetCamera_doc[] = 
461 "getCamera()\n"
462 "\tReturn the name of the camera to switch to.\n" ;
463 PyObject* KX_SceneActuator::PyGetCamera(PyObject* self, 
464                                                                                 PyObject* args, 
465                                                                                 PyObject* kwds)
466 {
467         ShowDeprecationWarning("getCamera()", "the camera property");
468         return PyString_FromString(m_camera->GetName());
469 }
470 /* eof */