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