patch from Mitchell Stokes, comments only - KX_PYATTRIBUTE_TODO for missing attributes
[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         return replica;
80 }
81
82 void KX_SceneActuator::ProcessReplica()
83 {
84         if (m_camera)
85                 m_camera->RegisterActuator(this);
86         SCA_IActuator::ProcessReplica();
87 }
88
89 bool KX_SceneActuator::UnlinkObject(SCA_IObject* clientobj)
90 {
91         if (clientobj == (SCA_IObject*)m_camera)
92         {
93                 // this object is being deleted, we cannot continue to track it.
94                 m_camera = NULL;
95                 return true;
96         }
97         return false;
98 }
99
100 void KX_SceneActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
101 {
102         void **h_obj = (*obj_map)[m_camera];
103         if (h_obj) {
104                 if (m_camera)
105                         m_camera->UnregisterActuator(this);
106                 m_camera = (KX_Camera*)(*h_obj);
107                 m_camera->RegisterActuator(this);
108         }
109 }
110
111
112 bool KX_SceneActuator::Update()
113 {
114         // bool result = false; /*unused*/
115         bool bNegativeEvent = IsNegativeEvent();
116         RemoveAllEvents();
117
118         if (bNegativeEvent)
119                 return false; // do nothing on negative events
120
121         switch (m_mode)
122         {
123         case KX_SCENE_RESTART:
124                 {
125                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_scene->GetName());
126                         break;
127                 }
128         case KX_SCENE_SET_CAMERA:
129                 if (m_camera)
130                 {
131                         m_scene->SetActiveCamera(m_camera);
132                 }
133                 else
134                 {
135                         // if no camera is set and the parent object is a camera, use it as the camera
136                         SCA_IObject* parent = GetParent();
137                         if (parent->isA(&KX_Camera::Type))
138                         {
139                                 m_scene->SetActiveCamera((KX_Camera*)parent);
140                         }
141                 }
142                 break;
143         default:
144                 break;
145         }
146         
147         if (!m_nextSceneName.Length())
148                 return false;
149         
150         switch (m_mode)
151         {
152         case KX_SCENE_SET_SCENE:
153                 {
154                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_nextSceneName);
155                         break;
156                 }
157         case KX_SCENE_ADD_FRONT_SCENE:
158                 {
159                         bool overlay=true;
160                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
161                         break;
162                 }
163         case KX_SCENE_ADD_BACK_SCENE:
164                 {
165                         bool overlay=false;
166                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
167                         break;
168                 }
169         case KX_SCENE_REMOVE_SCENE:
170                 {
171                         m_KetsjiEngine->RemoveScene(m_nextSceneName);
172                         break;
173                 }
174         case KX_SCENE_SUSPEND:
175                 {
176                         m_KetsjiEngine->SuspendScene(m_nextSceneName);
177                         break;
178                 }
179         case KX_SCENE_RESUME:
180                 {
181                         m_KetsjiEngine->ResumeScene(m_nextSceneName);
182                         break;
183                 }
184         default:
185                 ; /* do nothing? this is an internal error !!! */
186         }
187         
188         return false;
189 }
190
191
192
193 /*  returns a camera if the name is valid */
194 KX_Camera* KX_SceneActuator::FindCamera(char *camName)
195 {
196         KX_SceneList* sl = m_KetsjiEngine->CurrentScenes();
197         STR_String name = STR_String(camName);
198         KX_SceneList::iterator it = sl->begin();
199         KX_Camera* cam = NULL;
200
201         while ((it != sl->end()) && (!cam))
202         {
203                 cam = (*it)->FindCamera(name);
204                 it++;
205         }
206
207         return cam;
208 }
209
210
211
212 KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
213 {
214         return m_KetsjiEngine->FindScene(sceneName);
215 }
216
217
218
219
220 /* ------------------------------------------------------------------------- */
221 /* Python functions                                                          */
222 /* ------------------------------------------------------------------------- */
223
224 /* Integration hooks ------------------------------------------------------- */
225 PyTypeObject KX_SceneActuator::Type = {
226         PyObject_HEAD_INIT(NULL)
227                 0,
228                 "KX_SceneActuator",
229                 sizeof(PyObjectPlus_Proxy),
230                 0,
231                 py_base_dealloc,
232                 0,
233                 0,
234                 0,
235                 0,
236                 py_base_repr,
237                 0,0,0,0,0,0,
238                 py_base_getattro,
239                 py_base_setattro,
240                 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_NOARGS, (PY_METHODCHAR)GetUseRestart_doc},
264         {"getScene",      (PyCFunction) KX_SceneActuator::sPyGetScene, METH_NOARGS, (PY_METHODCHAR)GetScene_doc},
265         {"getCamera",     (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_NOARGS, (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         //KX_PYATTRIBUTE_TODO("useRestart"),
274         //KX_PYATTRIBUTE_TODO("mode"),
275         { NULL }        //Sentinel
276 };
277
278 PyObject* KX_SceneActuator::py_getattro(PyObject *attr)
279 {
280         py_getattro_up(SCA_IActuator);
281 }
282
283 PyObject* KX_SceneActuator::py_getattro_dict() {
284         py_getattro_dict_up(SCA_IActuator);
285 }
286
287 int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value)
288 {
289         py_setattro_up(SCA_IActuator);
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         
298         return actuator->m_camera->GetProxy();
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(value==Py_None)
307         {
308                 if (actuator->m_camera)
309                         actuator->m_camera->UnregisterActuator(actuator);
310                 
311                 actuator->m_camera= NULL;
312                 return 0;
313         }
314         
315         if (PyObject_TypeCheck(value, &KX_Camera::Type)) 
316         {
317                 KX_Camera *camOb= static_cast<KX_Camera*>BGE_PROXY_REF(value);
318                 
319                 if(camOb==NULL)
320                 {
321                         PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
322                         return 1;
323                 }
324                 
325                 if (actuator->m_camera)
326                         actuator->m_camera->UnregisterActuator(actuator);
327                 
328                 actuator->m_camera = camOb;
329                 actuator->m_camera->RegisterActuator(actuator);
330                 return 0;
331         }
332
333         if (PyString_Check(value))
334         {
335                 char *camName = PyString_AsString(value);
336
337                 camOb = actuator->FindCamera(camName);
338                 if (camOb) 
339                 {
340                         if (actuator->m_camera)
341                                 actuator->m_camera->UnregisterActuator(actuator);
342                         actuator->m_camera = camOb;
343                         actuator->m_camera->RegisterActuator(actuator);
344                         return 0;
345                 }
346                 PyErr_SetString(PyExc_TypeError, "not a valid camera name");
347                 return 1;
348         }
349         PyErr_SetString(PyExc_TypeError, "expected a string or a camera object reference");
350         return 1;
351 }
352
353
354 /* 2. setUseRestart--------------------------------------------------------- */
355 const char KX_SceneActuator::SetUseRestart_doc[] = 
356 "setUseRestart(flag)\n"
357 "\t- flag: 0 or 1.\n"
358 "\tSet flag to 1 to restart the scene.\n" ;
359 PyObject* KX_SceneActuator::PySetUseRestart(PyObject* args)
360 {
361         ShowDeprecationWarning("setUseRestart()", "(no replacement)");
362         int boolArg;
363         
364         if (!PyArg_ParseTuple(args, "i:setUseRestart", &boolArg))
365         {
366                 return NULL;
367         }
368         
369         m_restart = boolArg != 0;
370         
371         Py_RETURN_NONE;
372 }
373
374
375
376 /* 3. getUseRestart:                                                         */
377 const char KX_SceneActuator::GetUseRestart_doc[] = 
378 "getUseRestart()\n"
379 "\tReturn whether the scene will be restarted.\n" ;
380 PyObject* KX_SceneActuator::PyGetUseRestart()
381 {
382         ShowDeprecationWarning("getUseRestart()", "(no replacement)");
383         return PyInt_FromLong(!(m_restart == 0));
384 }
385
386
387
388 /* 4. set scene------------------------------------------------------------- */
389 const char KX_SceneActuator::SetScene_doc[] = 
390 "setScene(scene)\n"
391 "\t- scene: string\n"
392 "\tSet the name of scene the actuator will switch to.\n" ;
393 PyObject* KX_SceneActuator::PySetScene(PyObject* args)
394 {
395         ShowDeprecationWarning("setScene()", "the scene property");
396         /* one argument: a scene, ignore the rest */
397         char *scene_name;
398
399         if(!PyArg_ParseTuple(args, "s:setScene", &scene_name))
400         {
401                 return NULL;
402         }
403
404         /* Scene switch is done by name. */
405         m_nextSceneName = scene_name;
406
407         Py_RETURN_NONE;
408 }
409
410
411
412 /* 5. getScene:                                                              */
413 const char KX_SceneActuator::GetScene_doc[] = 
414 "getScene()\n"
415 "\tReturn the name of the scene the actuator wants to switch to.\n" ;
416 PyObject* KX_SceneActuator::PyGetScene()
417 {
418         ShowDeprecationWarning("getScene()", "the scene property");
419         return PyString_FromString(m_nextSceneName);
420 }
421
422
423
424 /* 6. set camera------------------------------------------------------------ */
425 const char KX_SceneActuator::SetCamera_doc[] = 
426 "setCamera(camera)\n"
427 "\t- camera: string\n"
428 "\tSet the camera to switch to.\n" ;
429 PyObject* KX_SceneActuator::PySetCamera(PyObject* args)
430 {
431         ShowDeprecationWarning("setCamera()", "the camera property");
432         PyObject *cam;
433         if (PyArg_ParseTuple(args, "O!:setCamera", &KX_Camera::Type, &cam))
434         {
435                 KX_Camera *new_camera;
436                 
437                 new_camera = static_cast<KX_Camera*>BGE_PROXY_REF(cam);
438                 if(new_camera==NULL)
439                 {
440                         PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
441                         return NULL;
442                 }
443                 
444                 if (m_camera)
445                         m_camera->UnregisterActuator(this);
446                 
447                 m_camera= new_camera;
448                 
449                 m_camera->RegisterActuator(this);
450                 Py_RETURN_NONE;
451         }
452         PyErr_Clear();
453
454         /* one argument: a scene, ignore the rest */
455         char *camName;
456         if(!PyArg_ParseTuple(args, "s:setCamera", &camName))
457         {
458                 return NULL;
459         }
460
461         KX_Camera *camOb = FindCamera(camName);
462         if (camOb) 
463         {
464                 if (m_camera)
465                         m_camera->UnregisterActuator(this);
466                 m_camera = camOb;
467                 m_camera->RegisterActuator(this);
468         }
469
470         Py_RETURN_NONE;
471 }
472
473
474
475 /* 7. getCamera:                                                             */
476 const char KX_SceneActuator::GetCamera_doc[] = 
477 "getCamera()\n"
478 "\tReturn the name of the camera to switch to.\n" ;
479 PyObject* KX_SceneActuator::PyGetCamera()
480 {
481         ShowDeprecationWarning("getCamera()", "the camera property");
482         if (m_camera) {
483                 return PyString_FromString(m_camera->GetName());
484         }
485         else {
486                 Py_RETURN_NONE;
487         }
488 }
489 /* eof */