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(NULL)
230                 0,
231                 "KX_SceneActuator",
232                 sizeof(PyObjectPlus_Proxy),
233                 0,
234                 py_base_dealloc,
235                 0,
236                 0,
237                 0,
238                 0,
239                 py_base_repr,
240                 0,0,0,0,0,0,
241                 py_base_getattro,
242                 py_base_setattro,
243                 0,0,0,0,0,0,0,0,0,
244                 Methods
245 };
246
247
248
249 PyParentObject KX_SceneActuator::Parents[] =
250 {
251         &KX_SceneActuator::Type,
252                 &SCA_IActuator::Type,
253                 &SCA_ILogicBrick::Type,
254                 &CValue::Type,
255                 NULL
256 };
257
258
259
260 PyMethodDef KX_SceneActuator::Methods[] =
261 {
262         //Deprecated functions ------>
263         {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, (PY_METHODCHAR)SetUseRestart_doc},
264         {"setScene",      (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, (PY_METHODCHAR)SetScene_doc},
265         {"setCamera",     (PyCFunction) KX_SceneActuator::sPySetCamera, METH_VARARGS, (PY_METHODCHAR)SetCamera_doc},
266         {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_NOARGS, (PY_METHODCHAR)GetUseRestart_doc},
267         {"getScene",      (PyCFunction) KX_SceneActuator::sPyGetScene, METH_NOARGS, (PY_METHODCHAR)GetScene_doc},
268         {"getCamera",     (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_NOARGS, (PY_METHODCHAR)GetCamera_doc},
269         //<----- Deprecated
270         {NULL,NULL} //Sentinel
271 };
272
273 PyAttributeDef KX_SceneActuator::Attributes[] = {
274         KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName),
275         KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera),
276         { NULL }        //Sentinel
277 };
278
279 PyObject* KX_SceneActuator::py_getattro(PyObject *attr)
280 {
281         py_getattro_up(SCA_IActuator);
282 }
283
284 PyObject* KX_SceneActuator::py_getattro_dict() {
285         py_getattro_dict_up(SCA_IActuator);
286 }
287
288 int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value)
289 {
290         py_setattro_up(SCA_IActuator);
291 }
292
293 PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
294 {
295         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
296         if (!actuator->m_camera)
297                 Py_RETURN_NONE;
298         
299         return actuator->m_camera->GetProxy();
300 }
301
302 int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
303 {
304         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
305         KX_Camera *camOb;
306         
307         if(value==Py_None)
308         {
309                 if (actuator->m_camera)
310                         actuator->m_camera->UnregisterActuator(actuator);
311                 
312                 actuator->m_camera= NULL;
313                 return 0;
314         }
315         
316         if (PyObject_TypeCheck(value, &KX_Camera::Type)) 
317         {
318                 KX_Camera *camOb= static_cast<KX_Camera*>BGE_PROXY_REF(value);
319                 
320                 if(camOb==NULL)
321                 {
322                         PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
323                         return 1;
324                 }
325                 
326                 if (actuator->m_camera)
327                         actuator->m_camera->UnregisterActuator(actuator);
328                 
329                 actuator->m_camera = camOb;
330                 actuator->m_camera->RegisterActuator(actuator);
331                 return 0;
332         }
333
334         if (PyString_Check(value))
335         {
336                 char *camName = PyString_AsString(value);
337
338                 camOb = actuator->FindCamera(camName);
339                 if (camOb) 
340                 {
341                         if (actuator->m_camera)
342                                 actuator->m_camera->UnregisterActuator(actuator);
343                         actuator->m_camera = camOb;
344                         actuator->m_camera->RegisterActuator(actuator);
345                         return 0;
346                 }
347                 PyErr_SetString(PyExc_TypeError, "not a valid camera name");
348                 return 1;
349         }
350         PyErr_SetString(PyExc_TypeError, "expected a string or a camera object reference");
351         return 1;
352 }
353
354
355 /* 2. setUseRestart--------------------------------------------------------- */
356 const char KX_SceneActuator::SetUseRestart_doc[] = 
357 "setUseRestart(flag)\n"
358 "\t- flag: 0 or 1.\n"
359 "\tSet flag to 1 to restart the scene.\n" ;
360 PyObject* KX_SceneActuator::PySetUseRestart(PyObject* args)
361 {
362         ShowDeprecationWarning("setUseRestart()", "(no replacement)");
363         int boolArg;
364         
365         if (!PyArg_ParseTuple(args, "i:setUseRestart", &boolArg))
366         {
367                 return NULL;
368         }
369         
370         m_restart = boolArg != 0;
371         
372         Py_RETURN_NONE;
373 }
374
375
376
377 /* 3. getUseRestart:                                                         */
378 const char KX_SceneActuator::GetUseRestart_doc[] = 
379 "getUseRestart()\n"
380 "\tReturn whether the scene will be restarted.\n" ;
381 PyObject* KX_SceneActuator::PyGetUseRestart()
382 {
383         ShowDeprecationWarning("getUseRestart()", "(no replacement)");
384         return PyInt_FromLong(!(m_restart == 0));
385 }
386
387
388
389 /* 4. set scene------------------------------------------------------------- */
390 const char KX_SceneActuator::SetScene_doc[] = 
391 "setScene(scene)\n"
392 "\t- scene: string\n"
393 "\tSet the name of scene the actuator will switch to.\n" ;
394 PyObject* KX_SceneActuator::PySetScene(PyObject* args)
395 {
396         ShowDeprecationWarning("setScene()", "the scene property");
397         /* one argument: a scene, ignore the rest */
398         char *scene_name;
399
400         if(!PyArg_ParseTuple(args, "s:setScene", &scene_name))
401         {
402                 return NULL;
403         }
404
405         /* Scene switch is done by name. */
406         m_nextSceneName = scene_name;
407
408         Py_RETURN_NONE;
409 }
410
411
412
413 /* 5. getScene:                                                              */
414 const char KX_SceneActuator::GetScene_doc[] = 
415 "getScene()\n"
416 "\tReturn the name of the scene the actuator wants to switch to.\n" ;
417 PyObject* KX_SceneActuator::PyGetScene()
418 {
419         ShowDeprecationWarning("getScene()", "the scene property");
420         return PyString_FromString(m_nextSceneName);
421 }
422
423
424
425 /* 6. set camera------------------------------------------------------------ */
426 const char KX_SceneActuator::SetCamera_doc[] = 
427 "setCamera(camera)\n"
428 "\t- camera: string\n"
429 "\tSet the camera to switch to.\n" ;
430 PyObject* KX_SceneActuator::PySetCamera(PyObject* args)
431 {
432         ShowDeprecationWarning("setCamera()", "the camera property");
433         PyObject *cam;
434         if (PyArg_ParseTuple(args, "O!:setCamera", &KX_Camera::Type, &cam))
435         {
436                 KX_Camera *new_camera;
437                 
438                 new_camera = static_cast<KX_Camera*>BGE_PROXY_REF(cam);
439                 if(new_camera==NULL)
440                 {
441                         PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
442                         return NULL;
443                 }
444                 
445                 if (m_camera)
446                         m_camera->UnregisterActuator(this);
447                 
448                 m_camera= new_camera;
449                 
450                 m_camera->RegisterActuator(this);
451                 Py_RETURN_NONE;
452         }
453         PyErr_Clear();
454
455         /* one argument: a scene, ignore the rest */
456         char *camName;
457         if(!PyArg_ParseTuple(args, "s:setCamera", &camName))
458         {
459                 return NULL;
460         }
461
462         KX_Camera *camOb = FindCamera(camName);
463         if (camOb) 
464         {
465                 if (m_camera)
466                         m_camera->UnregisterActuator(this);
467                 m_camera = camOb;
468                 m_camera->RegisterActuator(this);
469         }
470
471         Py_RETURN_NONE;
472 }
473
474
475
476 /* 7. getCamera:                                                             */
477 const char KX_SceneActuator::GetCamera_doc[] = 
478 "getCamera()\n"
479 "\tReturn the name of the camera to switch to.\n" ;
480 PyObject* KX_SceneActuator::PyGetCamera()
481 {
482         ShowDeprecationWarning("getCamera()", "the camera property");
483         if (m_camera) {
484                 return PyString_FromString(m_camera->GetName());
485         }
486         else {
487                 Py_RETURN_NONE;
488         }
489 }
490 /* eof */