BGE: bookmark option on controller to make them run before all other controllers.
[blender.git] / source / gameengine / GameLogic / SCA_PythonController.cpp
1 /**
2  * Execute Python scripts
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_PythonController.h"
33 #include "SCA_LogicManager.h"
34 #include "SCA_ISensor.h"
35 #include "SCA_IActuator.h"
36 #include "PyObjectPlus.h"
37 #include "compile.h"
38 #include "eval.h"
39 #include <algorithm>
40
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 // initialize static member variables
47 SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL;
48
49
50 SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj,
51                                                                                    int mode,
52                                                                                    PyTypeObject* T)
53         : SCA_IController(gameobj, T),
54         m_bytecode(NULL),
55         m_function(NULL),
56         m_function_argc(0),
57         m_bModified(true),
58         m_debug(false),
59         m_mode(mode),
60         m_pythondictionary(NULL)
61 {
62         
63 }
64
65 /*
66 //debugging
67 CValue*         SCA_PythonController::AddRef()
68 {
69         //printf("AddRef refcount = %i\n",GetRefCount());
70         return CValue::AddRef();
71 }
72 int                     SCA_PythonController::Release()
73 {
74         //printf("Release refcount = %i\n",GetRefCount());
75         return CValue::Release();
76 }
77 */
78
79
80
81 SCA_PythonController::~SCA_PythonController()
82 {
83         //printf("released python byte script\n");
84         
85         Py_XDECREF(m_bytecode);
86         Py_XDECREF(m_function);
87         
88         if (m_pythondictionary) {
89                 // break any circular references in the dictionary
90                 PyDict_Clear(m_pythondictionary);
91                 Py_DECREF(m_pythondictionary);
92         }
93 }
94
95
96
97 CValue* SCA_PythonController::GetReplica()
98 {
99         SCA_PythonController* replica = new SCA_PythonController(*this);
100         
101         /* why is this needed at all??? - m_bytecode is NULL'd below so this doesnt make sense
102          * but removing it crashes blender (with YoFrankie). so leave in for now - Campbell */
103         Py_XINCREF(replica->m_bytecode);
104         
105         Py_XINCREF(replica->m_function); // this is ok since its not set to NULL
106         replica->m_bModified = replica->m_bytecode == NULL;
107         
108         // The replica->m_pythondictionary is stolen - replace with a copy.
109         if (m_pythondictionary)
110                 replica->m_pythondictionary = PyDict_Copy(m_pythondictionary);
111                 
112         /*
113         // The other option is to incref the replica->m_pythondictionary -
114         // the replica objects can then share data.
115         if (m_pythondictionary)
116                 Py_INCREF(replica->m_pythondictionary);
117         */
118         
119         // this will copy properties and so on...
120         replica->ProcessReplica();
121
122         return replica;
123 }
124
125
126
127 void SCA_PythonController::SetScriptText(const STR_String& text)
128
129         m_scriptText = text;
130         m_bModified = true;
131 }
132
133
134
135 void SCA_PythonController::SetScriptName(const STR_String& name)
136 {
137         m_scriptName = name;
138 }
139
140
141
142 void SCA_PythonController::SetDictionary(PyObject*      pythondictionary)
143 {
144         if (m_pythondictionary)
145         {
146                 PyDict_Clear(m_pythondictionary);
147                 Py_DECREF(m_pythondictionary);
148         }
149         m_pythondictionary = PyDict_Copy(pythondictionary); /* new reference */
150 }
151
152 int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
153 {
154         if (std::find(m_triggeredSensors.begin(), m_triggeredSensors.end(), sensor) != 
155                 m_triggeredSensors.end())
156                 return 1;
157         return 0;
158 }
159
160 /* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */
161 PyObject* SCA_PythonController::sPyGetCurrentController(PyObject *self)
162 {
163         if(m_sCurrentController==NULL)
164         {
165                 PyErr_SetString(PyExc_SystemError, "GameLogic.getCurrentController(), this function is being run outside the python controllers context, or blenders internal state is corrupt.");
166                 return NULL;
167         }
168         return m_sCurrentController->GetProxy();
169 }
170
171 SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
172 {
173         // for safety, todo: only allow for registered actuators (pointertable)
174         // we don't want to crash gameengine/blender by python scripts
175         std::vector<SCA_IActuator*> lacts =  m_sCurrentController->GetLinkedActuators();
176         std::vector<SCA_IActuator*>::iterator it;
177         
178         if (PyString_Check(value)) {
179                 /* get the actuator from the name */
180                 char *name= PyString_AsString(value);
181                 for(it = lacts.begin(); it!= lacts.end(); ++it) {
182                         if( name == (*it)->GetName() ) {
183                                 return *it;
184                         }
185                 }
186         }
187         else if (BGE_PROXY_CHECK_TYPE(value)) {
188                 PyObjectPlus *value_plus= BGE_PROXY_REF(value);
189                 for(it = lacts.begin(); it!= lacts.end(); ++it) {
190                         if( static_cast<SCA_IActuator*>(value_plus) == (*it) ) {
191                                 return *it;
192                         }
193                 }
194         }
195         
196         /* set the exception */
197         PyObject *value_str = PyObject_Repr(value); /* new ref */
198         PyErr_Format(PyExc_ValueError, "'%s' not in this python controllers actuator list", PyString_AsString(value_str));
199         Py_DECREF(value_str);
200         
201         return false;
202 }
203
204 /* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */
205 PyObject* SCA_PythonController::sPyAddActiveActuator(PyObject* self, PyObject* args)
206 {
207         ShowDeprecationWarning("GameLogic.addActiveActuator(act, bool)", "controller.activate(act) or controller.deactivate(act)");
208         
209         PyObject* ob1;
210         int activate;
211         if (!PyArg_ParseTuple(args, "Oi:addActiveActuator", &ob1,&activate))
212                 return NULL;
213         
214         SCA_IActuator* actu = LinkedActuatorFromPy(ob1);
215         if(actu==NULL)
216                 return NULL;
217         
218         bool boolval = (activate!=0);
219         m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu,boolval);
220         Py_RETURN_NONE;
221 }
222
223 const char* SCA_PythonController::sPyGetCurrentController__doc__ = "getCurrentController()";
224 const char* SCA_PythonController::sPyAddActiveActuator__doc__= "addActiveActuator(actuator,bool)";
225
226 PyTypeObject SCA_PythonController::Type = {
227 #if (PY_VERSION_HEX >= 0x02060000)
228         PyVarObject_HEAD_INIT(NULL, 0)
229 #else
230         /* python 2.5 and below */
231         PyObject_HEAD_INIT( NULL )  /* required py macro */
232         0,                          /* ob_size */
233 #endif
234                 "SCA_PythonController",
235                 sizeof(PyObjectPlus_Proxy),
236                 0,
237                 py_base_dealloc,
238                 0,
239                 0,
240                 0,
241                 0,
242                 py_base_repr,
243                 0,0,0,0,0,0,
244                 py_base_getattro,
245                 py_base_setattro,
246                 0,0,0,0,0,0,0,0,0,
247                 Methods
248 };
249
250 PyParentObject SCA_PythonController::Parents[] = {
251         &SCA_PythonController::Type,
252         &SCA_IController::Type,
253         &CValue::Type,
254         NULL
255 };
256 PyMethodDef SCA_PythonController::Methods[] = {
257         {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O},
258         {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O},
259         
260         //Deprecated functions ------>
261         {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O},
262         {"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_NOARGS},
263         //<----- Deprecated
264         {NULL,NULL} //Sentinel
265 };
266
267 PyAttributeDef SCA_PythonController::Attributes[] = {
268         KX_PYATTRIBUTE_RW_FUNCTION("script", SCA_PythonController, pyattr_get_script, pyattr_set_script),
269         { NULL }        //Sentinel
270 };
271
272 void SCA_PythonController::ErrorPrint(const char *error_msg)
273 {
274         // didn't compile, so instead of compile, complain
275         // something is wrong, tell the user what went wrong
276         printf("%s - controller \"%s\":\n", error_msg, GetName().Ptr());
277         //PyRun_SimpleString(m_scriptText.Ptr());
278         PyErr_Print();
279         
280         /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
281          * their user count. Not to mention holding references to wrapped data.
282          * This is especially bad when the PyObject for the wrapped data is free'd, after blender 
283          * has alredy dealocated the pointer */
284         PySys_SetObject( (char *)"last_traceback", NULL);
285         PyErr_Clear(); /* just to be sure */
286 }
287
288 bool SCA_PythonController::Compile()
289 {       
290         //printf("py script modified '%s'\n", m_scriptName.Ptr());
291         m_bModified= false;
292         
293         // if a script already exists, decref it before replace the pointer to a new script
294         if (m_bytecode) {
295                 Py_DECREF(m_bytecode);
296                 m_bytecode=NULL;
297         }
298         
299         // recompile the scripttext into bytecode
300         m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input);
301         
302         if (m_bytecode) {
303                 return true;
304         } else {
305                 ErrorPrint("Python error compiling script");
306                 return false;
307         }
308 }
309
310 bool SCA_PythonController::Import()
311 {
312         //printf("py module modified '%s'\n", m_scriptName.Ptr());
313         m_bModified= false;
314         
315         /* incase we re-import */
316         Py_XDECREF(m_function);
317         m_function= NULL;
318         
319         vector<STR_String> py_function_path = m_scriptText.Explode('.');
320         
321         if(py_function_path.size() < 2) {
322                 printf("Python module name formatting error \"%s\":\n\texpected \"SomeModule.Func\", got \"%s\"\n", GetName().Ptr(), m_scriptText.Ptr());
323                 return false;
324         }
325         
326         PyObject *mod = PyImport_ImportModule((char *)py_function_path[0].Ptr());
327         if(mod && m_debug) {
328                 Py_DECREF(mod); /* getting a new one so dont hold a ref to the old one */
329                 mod= PyImport_ReloadModule(mod);
330         }
331         
332         if(mod==NULL) {
333                 ErrorPrint("Python module not found");
334                 return false;
335         }
336         /* 'mod' will be DECREF'd as 'base' 
337          * 'm_function' will be left holding a reference that the controller owns */
338         
339         PyObject *base= mod;
340         
341         for(unsigned int i=1; i < py_function_path.size(); i++) {
342                 m_function = PyObject_GetAttrString(base, py_function_path[i].Ptr());
343                 Py_DECREF(base);
344                 base = m_function; /* for the next loop if there is on */
345                 
346                 if(m_function==NULL) {
347                         PyErr_Clear(); /* print our own error below */
348                         break;
349                 }
350         }
351         
352         if(m_function==NULL) {
353                 printf("Python module error \"%s\":\n \"%s\" module found but function missing\n", GetName().Ptr(), m_scriptText.Ptr());
354                 return false;
355         }
356         
357         if(!PyCallable_Check(m_function)) {
358                 Py_DECREF(m_function);
359                 printf("Python module function error \"%s\":\n \"%s\" not callable\n", GetName().Ptr(), m_scriptText.Ptr());
360                 return false;
361         }
362         
363         m_function_argc = 0; /* rare cases this could be a function that isnt defined in python, assume zero args */
364         if (PyFunction_Check(m_function)) {
365                 PyObject *py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(m_function), "co_argcount");
366                 if(py_arg_count) {
367                         m_function_argc = PyLong_AsLong(py_arg_count);
368                         Py_DECREF(py_arg_count);
369                 }
370                 else {
371                         PyErr_Clear(); /* unlikely to fail but just incase */
372                 }
373         }
374         
375         if(m_function_argc > 1) {
376                 Py_DECREF(m_function);
377                 printf("Python module function has \"%s\":\n \"%s\" takes %d args, should be zero or 1 controller arg\n", GetName().Ptr(), m_scriptText.Ptr(), m_function_argc);
378                 return false;
379         }
380         
381         return true;
382 }
383
384 void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
385 {
386         m_sCurrentController = this;
387         m_sCurrentLogicManager = logicmgr;
388         
389         PyObject *excdict=              NULL;
390         PyObject* resultobj=    NULL;
391         
392         switch(m_mode) {
393         case SCA_PYEXEC_SCRIPT:
394         {
395                 if (m_bModified)
396                         if (Compile()==false) // sets m_bModified to false
397                                 return;
398                 if (!m_bytecode)
399                         return;
400                 
401                 /*
402                  * This part here with excdict is a temporary patch
403                  * to avoid python/gameengine crashes when python
404                  * inadvertently holds references to game objects
405                  * in global variables.
406                  * 
407                  * The idea is always make a fresh dictionary, and
408                  * destroy it right after it is used to make sure
409                  * python won't hold any gameobject references.
410                  * 
411                  * Note that the PyDict_Clear _is_ necessary before
412                  * the Py_DECREF() because it is possible for the
413                  * variables inside the dictionary to hold references
414                  * to the dictionary (ie. generate a cycle), so we
415                  * break it by hand, then DECREF (which in this case
416                  * should always ensure excdict is cleared).
417                  */
418
419                 excdict= PyDict_Copy(m_pythondictionary);
420                 resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode, excdict, excdict);
421                 /* PyRun_SimpleString(m_scriptText.Ptr()); */
422                 break;
423         }
424         case SCA_PYEXEC_MODULE:
425         {
426                 if (m_bModified || m_debug)
427                         if (Import()==false) // sets m_bModified to false
428                                 return;
429                 if (!m_function)
430                         return;
431                 
432                 PyObject *args= NULL;
433                 
434                 if(m_function_argc==1) {
435                         args = PyTuple_New(1);
436                         PyTuple_SET_ITEM(args, 0, GetProxy());
437                 }
438                 
439                 resultobj = PyObject_CallObject(m_function, args);
440                 Py_XDECREF(args);
441                 break;
442         }
443         
444         } /* end switch */
445         
446         
447         
448         /* Free the return value and print the error */
449         if (resultobj)
450         {
451                 Py_DECREF(resultobj);
452         }
453         else
454         {
455                 // something is wrong, tell the user what went wrong
456                 printf("Python script error from controller \"%s\":\n", GetName().Ptr());
457                 PyErr_Print();
458                 
459                 /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
460                  * their user count. Not to mention holding references to wrapped data.
461                  * This is especially bad when the PyObject for the wrapped data is free'd, after blender 
462                  * has alredy dealocated the pointer */
463                 PySys_SetObject( (char *)"last_traceback", NULL);
464                 PyErr_Clear(); /* just to be sure */
465         }
466         
467         if(excdict) /* Only for SCA_PYEXEC_SCRIPT types */
468         {
469                 /* clear after PyErrPrint - seems it can be using
470                  * something in this dictionary and crash? */
471                 PyDict_Clear(excdict);
472                 Py_DECREF(excdict);
473         }       
474         
475         m_triggeredSensors.clear();
476         m_sCurrentController = NULL;
477 }
478
479
480
481 PyObject* SCA_PythonController::py_getattro(PyObject *attr)
482 {
483         py_getattro_up(SCA_IController);
484 }
485
486 PyObject* SCA_PythonController::py_getattro_dict() {
487         py_getattro_dict_up(SCA_IController);
488 }
489
490 int SCA_PythonController::py_setattro(PyObject *attr, PyObject *value)
491 {
492         py_setattro_up(SCA_IController);
493 }
494
495 PyObject* SCA_PythonController::PyActivate(PyObject *value)
496 {
497         if(m_sCurrentController != this) {
498                 PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller");
499                 return NULL;
500         }
501         
502         SCA_IActuator* actu = LinkedActuatorFromPy(value);
503         if(actu==NULL)
504                 return NULL;
505         
506         m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, true);
507         Py_RETURN_NONE;
508 }
509
510 PyObject* SCA_PythonController::PyDeActivate(PyObject *value)
511 {
512         if(m_sCurrentController != this) {
513                 PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller");
514                 return NULL;
515         }
516         
517         SCA_IActuator* actu = LinkedActuatorFromPy(value);
518         if(actu==NULL)
519                 return NULL;
520         
521         m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, false);
522         Py_RETURN_NONE;
523 }
524
525 /* 1. getScript */
526 PyObject* SCA_PythonController::PyGetScript()
527 {
528         ShowDeprecationWarning("getScript()", "the script property");
529         return PyString_FromString(m_scriptText);
530 }
531
532 /* 2. setScript */
533 PyObject* SCA_PythonController::PySetScript(PyObject* value)
534 {
535         char *scriptArg = PyString_AsString(value);
536         
537         ShowDeprecationWarning("setScript()", "the script property");
538         
539         if (scriptArg==NULL) {
540                 PyErr_SetString(PyExc_TypeError, "expected a string (script name)");
541                 return NULL;
542         }
543         
544         /* set scripttext sets m_bModified to true, 
545                 so next time the script is needed, a reparse into byte code is done */
546
547         this->SetScriptText(scriptArg);
548         
549         Py_RETURN_NONE;
550 }
551
552 PyObject* SCA_PythonController::pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
553 {
554         SCA_PythonController* self= static_cast<SCA_PythonController*>(self_v);
555         return PyString_FromString(self->m_scriptText);
556 }
557
558 int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
559 {
560         SCA_PythonController* self= static_cast<SCA_PythonController*>(self_v);
561         
562         char *scriptArg = PyString_AsString(value);
563         
564         if (scriptArg==NULL) {
565                 PyErr_SetString(PyExc_TypeError, "controller.script = string: Python Controller, expected a string script text");
566                 return -1;
567         }
568
569         /* set scripttext sets m_bModified to true, 
570                 so next time the script is needed, a reparse into byte code is done */
571         self->SetScriptText(scriptArg);
572                 
573         return 0;
574 }
575
576
577 /* eof */