be138db620efcd1b53cf8c5b304581a236c52927
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 /** \file gameengine/GameLogic/SCA_PythonController.cpp
33  *  \ingroup gamelogic
34  */
35
36
37 #include <stddef.h>
38
39 #include "SCA_PythonController.h"
40 #include "SCA_LogicManager.h"
41 #include "SCA_ISensor.h"
42 #include "SCA_IActuator.h"
43 #include "PyObjectPlus.h"
44
45 #ifdef WITH_PYTHON
46 #include "compile.h"
47 #include "eval.h"
48 #endif // WITH_PYTHON
49
50 #include <algorithm>
51
52
53 // initialize static member variables
54 SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL;
55
56
57 SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, int mode)
58         : SCA_IController(gameobj),
59 #ifdef WITH_PYTHON
60         m_bytecode(NULL),
61         m_function(NULL),
62 #endif
63         m_function_argc(0),
64         m_bModified(true),
65         m_debug(false),
66         m_mode(mode)
67 #ifdef WITH_PYTHON
68         , m_pythondictionary(NULL)
69 #endif
70
71 {
72         
73 }
74
75 /*
76 //debugging
77 CValue*         SCA_PythonController::AddRef()
78 {
79         //printf("AddRef refcount = %i\n",GetRefCount());
80         return CValue::AddRef();
81 }
82 int                     SCA_PythonController::Release()
83 {
84         //printf("Release refcount = %i\n",GetRefCount());
85         return CValue::Release();
86 }
87 */
88
89
90
91 SCA_PythonController::~SCA_PythonController()
92 {
93
94 #ifdef WITH_PYTHON
95         //printf("released python byte script\n");
96         
97         Py_XDECREF(m_bytecode);
98         Py_XDECREF(m_function);
99         
100         if (m_pythondictionary) {
101                 // break any circular references in the dictionary
102                 PyDict_Clear(m_pythondictionary);
103                 Py_DECREF(m_pythondictionary);
104         }
105 #endif
106 }
107
108
109
110 CValue* SCA_PythonController::GetReplica()
111 {
112         SCA_PythonController* replica = new SCA_PythonController(*this);
113
114 #ifdef WITH_PYTHON
115         /* why is this needed at all??? - m_bytecode is NULL'd below so this doesnt make sense
116          * but removing it crashes blender (with YoFrankie). so leave in for now - Campbell */
117         Py_XINCREF(replica->m_bytecode);
118         
119         Py_XINCREF(replica->m_function); // this is ok since its not set to NULL
120         replica->m_bModified = replica->m_bytecode == NULL;
121         
122         // The replica->m_pythondictionary is stolen - replace with a copy.
123         if (m_pythondictionary)
124                 replica->m_pythondictionary = PyDict_Copy(m_pythondictionary);
125                 
126         /*
127         // The other option is to incref the replica->m_pythondictionary -
128         // the replica objects can then share data.
129         if (m_pythondictionary)
130                 Py_INCREF(replica->m_pythondictionary);
131         */
132 #endif
133         
134         // this will copy properties and so on...
135         replica->ProcessReplica();
136
137         return replica;
138 }
139
140
141
142 void SCA_PythonController::SetScriptText(const STR_String& text)
143
144         m_scriptText = text;
145         m_bModified = true;
146 }
147
148
149
150 void SCA_PythonController::SetScriptName(const STR_String& name)
151 {
152         m_scriptName = name;
153 }
154
155
156 #ifdef WITH_PYTHON
157 void SCA_PythonController::SetNamespace(PyObject*       pythondictionary)
158 {
159         if (m_pythondictionary)
160         {
161                 PyDict_Clear(m_pythondictionary);
162                 Py_DECREF(m_pythondictionary);
163         }
164         m_pythondictionary = PyDict_Copy(pythondictionary); /* new reference */
165         
166         /* Without __file__ set the sys.argv[0] is used for the filename
167          * which ends up with lines from the blender binary being printed in the console */
168         PyDict_SetItemString(m_pythondictionary, "__file__", PyUnicode_FromString(m_scriptName.Ptr()));
169         
170 }
171 #endif
172
173 int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
174 {
175         if (std::find(m_triggeredSensors.begin(), m_triggeredSensors.end(), sensor) != 
176                 m_triggeredSensors.end())
177                 return 1;
178         return 0;
179 }
180
181 #ifdef WITH_PYTHON
182
183 /* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */
184 PyObject* SCA_PythonController::sPyGetCurrentController(PyObject *self)
185 {
186         if(m_sCurrentController==NULL)
187         {
188                 PyErr_SetString(PyExc_SystemError, "bge.logic.getCurrentController(), this function is being run outside the python controllers context, or blenders internal state is corrupt.");
189                 return NULL;
190         }
191         return m_sCurrentController->GetProxy();
192 }
193
194 SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
195 {
196         // for safety, todo: only allow for registered actuators (pointertable)
197         // we don't want to crash gameengine/blender by python scripts
198         std::vector<SCA_IActuator*> lacts =  m_sCurrentController->GetLinkedActuators();
199         std::vector<SCA_IActuator*>::iterator it;
200         
201         if (PyUnicode_Check(value)) {
202                 /* get the actuator from the name */
203                 char *name= _PyUnicode_AsString(value);
204                 for(it = lacts.begin(); it!= lacts.end(); ++it) {
205                         if( name == (*it)->GetName() ) {
206                                 return *it;
207                         }
208                 }
209         }
210         else if (PyObject_TypeCheck(value, &SCA_IActuator::Type)) {
211                 PyObjectPlus *value_plus= BGE_PROXY_REF(value);
212                 for(it = lacts.begin(); it!= lacts.end(); ++it) {
213                         if( static_cast<SCA_IActuator*>(value_plus) == (*it) ) {
214                                 return *it;
215                         }
216                 }
217         }
218         
219         /* set the exception */
220         PyObject *value_str = PyObject_Repr(value); /* new ref */
221         PyErr_Format(PyExc_ValueError, "'%s' not in this python controllers actuator list", _PyUnicode_AsString(value_str));
222         Py_DECREF(value_str);
223         
224         return NULL;
225 }
226
227 const char* SCA_PythonController::sPyGetCurrentController__doc__ = "getCurrentController()";
228
229 PyTypeObject SCA_PythonController::Type = {
230         PyVarObject_HEAD_INIT(NULL, 0)
231         "SCA_PythonController",
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,0,0,0,
241         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
242         0,0,0,0,0,0,0,
243         Methods,
244         0,
245         0,
246         &SCA_IController::Type,
247         0,0,0,0,0,0,
248         py_base_new
249 };
250
251 PyMethodDef SCA_PythonController::Methods[] = {
252         {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O},
253         {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O},
254         {NULL,NULL} //Sentinel
255 };
256
257 PyAttributeDef SCA_PythonController::Attributes[] = {
258         KX_PYATTRIBUTE_RW_FUNCTION("script", SCA_PythonController, pyattr_get_script, pyattr_set_script),
259         KX_PYATTRIBUTE_INT_RO("mode", SCA_PythonController, m_mode),
260         { NULL }        //Sentinel
261 };
262
263 void SCA_PythonController::ErrorPrint(const char *error_msg)
264 {
265         printf("%s - object '%s', controller '%s':\n", error_msg, GetParent()->GetName().Ptr(), GetName().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 already 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         STR_String mod_path_str= m_scriptText; /* just for storage, use C style string access */
308         char *mod_path= mod_path_str.Ptr();
309         char *function_string;
310
311         function_string= strrchr(mod_path, '.');
312
313         if(function_string == NULL) {
314                 printf("Python module name formatting error in object '%s', controller '%s':\n\texpected 'SomeModule.Func', got '%s'\n", GetParent()->GetName().Ptr(), GetName().Ptr(), m_scriptText.Ptr());
315                 return false;
316         }
317
318         *function_string= '\0';
319         function_string++;
320
321         // Import the module and print an error if it's not found
322         PyObject *mod = PyImport_ImportModule(mod_path);
323
324         if (mod == NULL) {
325                 ErrorPrint("Python module can't be imported");
326                 return false;
327         }
328
329         if(m_debug)
330                 mod = PyImport_ReloadModule(mod);
331
332         if (mod == NULL) {
333                 ErrorPrint("Python module can't be reloaded");
334                 return false;
335         }
336
337         // Get the function object
338         m_function = PyObject_GetAttrString(mod, function_string);
339
340         // DECREF the module as we don't need it anymore
341         Py_DECREF(mod);
342
343         if(m_function==NULL) {
344                 if(PyErr_Occurred())
345                         ErrorPrint("Python controller found the module but could not access the function");
346                 else
347                         printf("Python module error in object '%s', controller '%s':\n '%s' module found but function missing\n", GetParent()->GetName().Ptr(), GetName().Ptr(), m_scriptText.Ptr());
348                 return false;
349         }
350         
351         if(!PyCallable_Check(m_function)) {
352                 Py_DECREF(m_function);
353                 m_function = NULL;
354                 printf("Python module function error in object '%s', controller '%s':\n '%s' not callable\n", GetParent()->GetName().Ptr(), GetName().Ptr(), m_scriptText.Ptr());
355                 return false;
356         }
357         
358         m_function_argc = 0; /* rare cases this could be a function that isnt defined in python, assume zero args */
359         if (PyFunction_Check(m_function)) {
360                 PyObject *py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(m_function), "co_argcount");
361                 if(py_arg_count) {
362                         m_function_argc = PyLong_AsLong(py_arg_count);
363                         Py_DECREF(py_arg_count);
364                 }
365                 else {
366                         PyErr_Clear(); /* unlikely to fail but just incase */
367                 }
368         }
369         
370         if(m_function_argc > 1) {
371                 Py_DECREF(m_function);
372                 m_function = NULL;
373                 printf("Python module function in object '%s', controller '%s':\n '%s' takes %d args, should be zero or 1 controller arg\n", GetParent()->GetName().Ptr(), 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
418 #if PY_VERSION_HEX >=  0x03020000
419                 resultobj = PyEval_EvalCode((PyObject *)m_bytecode, excdict, excdict);
420 #else
421                 resultobj = PyEval_EvalCode((PyCodeObject *)m_bytecode, excdict, excdict);
422 #endif
423
424                 /* PyRun_SimpleString(m_scriptText.Ptr()); */
425                 break;
426         }
427         case SCA_PYEXEC_MODULE:
428         {
429                 if (m_bModified || m_debug)
430                         if (Import()==false) // sets m_bModified to false
431                                 return;
432                 if (!m_function)
433                         return;
434                 
435                 PyObject *args= NULL;
436                 
437                 if(m_function_argc==1) {
438                         args = PyTuple_New(1);
439                         PyTuple_SET_ITEM(args, 0, GetProxy());
440                 }
441                 
442                 resultobj = PyObject_CallObject(m_function, args);
443                 Py_XDECREF(args);
444                 break;
445         }
446         
447         } /* end switch */
448         
449         
450         
451         /* Free the return value and print the error */
452         if (resultobj)
453                 Py_DECREF(resultobj);
454         else
455                 ErrorPrint("Python script error");
456         
457         if(excdict) /* Only for SCA_PYEXEC_SCRIPT types */
458         {
459                 /* clear after PyErrPrint - seems it can be using
460                  * something in this dictionary and crash? */
461                 // This doesn't appear to be needed anymore
462                 //PyDict_Clear(excdict);
463                 Py_DECREF(excdict);
464         }       
465         
466         m_triggeredSensors.clear();
467         m_sCurrentController = NULL;
468 }
469
470 PyObject* SCA_PythonController::PyActivate(PyObject *value)
471 {
472         if(m_sCurrentController != this) {
473                 PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller");
474                 return NULL;
475         }
476         
477         SCA_IActuator* actu = LinkedActuatorFromPy(value);
478         if(actu==NULL)
479                 return NULL;
480         
481         m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, true);
482         Py_RETURN_NONE;
483 }
484
485 PyObject* SCA_PythonController::PyDeActivate(PyObject *value)
486 {
487         if(m_sCurrentController != this) {
488                 PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller");
489                 return NULL;
490         }
491         
492         SCA_IActuator* actu = LinkedActuatorFromPy(value);
493         if(actu==NULL)
494                 return NULL;
495         
496         m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, false);
497         Py_RETURN_NONE;
498 }
499
500 PyObject* SCA_PythonController::pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
501 {
502         //SCA_PythonController* self= static_cast<SCA_PythonController*>(static_cast<SCA_IController*>(static_cast<SCA_ILogicBrick*>(static_cast<CValue*>(static_cast<PyObjectPlus*>(self_v)))));
503         // static_cast<void *>(dynamic_cast<Derived *>(obj)) - static_cast<void *>(obj)
504
505         SCA_PythonController* self= static_cast<SCA_PythonController*>(self_v);
506         return PyUnicode_FromString(self->m_scriptText);
507 }
508
509
510
511 int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
512 {
513         SCA_PythonController* self= static_cast<SCA_PythonController*>(self_v);
514         
515         char *scriptArg = _PyUnicode_AsString(value);
516         
517         if (scriptArg==NULL) {
518                 PyErr_SetString(PyExc_TypeError, "controller.script = string: Python Controller, expected a string script text");
519                 return PY_SET_ATTR_FAIL;
520         }
521
522         /* set scripttext sets m_bModified to true, 
523                 so next time the script is needed, a reparse into byte code is done */
524         self->SetScriptText(scriptArg);
525                 
526         return PY_SET_ATTR_SUCCESS;
527 }
528
529 #else // WITH_PYTHON
530
531 void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
532 {
533         /* intentionally blank */
534 }
535
536 #endif // WITH_PYTHON
537
538 /* eof */