optionally use guarded alloc for tiles compositor, also replace allocation functions...
[blender.git] / source / gameengine / GameLogic / SCA_PythonController.cpp
1 /*
2  * Execute Python scripts
3  *
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 /** \file gameengine/GameLogic/SCA_PythonController.cpp
32  *  \ingroup gamelogic
33  */
34
35
36 #include <stddef.h>
37
38 #include "SCA_PythonController.h"
39 #include "SCA_LogicManager.h"
40 #include "SCA_ISensor.h"
41 #include "SCA_IActuator.h"
42 #include "PyObjectPlus.h"
43
44 #ifdef WITH_PYTHON
45 #include "compile.h"
46 #include "eval.h"
47 #endif // WITH_PYTHON
48
49 #include <algorithm>
50
51
52 // initialize static member variables
53 SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL;
54
55
56 SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, int mode)
57         : SCA_IController(gameobj),
58 #ifdef WITH_PYTHON
59         m_bytecode(NULL),
60         m_function(NULL),
61 #endif
62         m_function_argc(0),
63         m_bModified(true),
64         m_debug(false),
65         m_mode(mode)
66 #ifdef WITH_PYTHON
67         , m_pythondictionary(NULL)
68 #endif
69
70 {
71         
72 }
73
74 /*
75 //debugging
76 CValue*         SCA_PythonController::AddRef()
77 {
78         //printf("AddRef refcount = %i\n",GetRefCount());
79         return CValue::AddRef();
80 }
81 int                     SCA_PythonController::Release()
82 {
83         //printf("Release refcount = %i\n",GetRefCount());
84         return CValue::Release();
85 }
86 */
87
88
89
90 SCA_PythonController::~SCA_PythonController()
91 {
92
93 #ifdef WITH_PYTHON
94         //printf("released python byte script\n");
95         
96         Py_XDECREF(m_bytecode);
97         Py_XDECREF(m_function);
98         
99         if (m_pythondictionary) {
100                 // break any circular references in the dictionary
101                 PyDict_Clear(m_pythondictionary);
102                 Py_DECREF(m_pythondictionary);
103         }
104 #endif
105 }
106
107
108
109 CValue* SCA_PythonController::GetReplica()
110 {
111         SCA_PythonController* replica = new SCA_PythonController(*this);
112
113 #ifdef WITH_PYTHON
114         /* why is this needed at all??? - m_bytecode is NULL'd below so this doesnt make sense
115          * but removing it crashes blender (with YoFrankie). so leave in for now - Campbell */
116         Py_XINCREF(replica->m_bytecode);
117         
118         Py_XINCREF(replica->m_function); // this is ok since its not set to NULL
119         replica->m_bModified = replica->m_bytecode == NULL;
120         
121         // The replica->m_pythondictionary is stolen - replace with a copy.
122         if (m_pythondictionary)
123                 replica->m_pythondictionary = PyDict_Copy(m_pythondictionary);
124                 
125         /*
126         // The other option is to incref the replica->m_pythondictionary -
127         // the replica objects can then share data.
128         if (m_pythondictionary)
129                 Py_INCREF(replica->m_pythondictionary);
130         */
131 #endif
132         
133         // this will copy properties and so on...
134         replica->ProcessReplica();
135
136         return replica;
137 }
138
139
140
141 void SCA_PythonController::SetScriptText(const STR_String& text)
142
143         m_scriptText = text;
144         m_bModified = true;
145 }
146
147
148
149 void SCA_PythonController::SetScriptName(const STR_String& name)
150 {
151         m_scriptName = name;
152 }
153
154
155 #ifdef WITH_PYTHON
156 void SCA_PythonController::SetNamespace(PyObject*       pythondictionary)
157 {
158         if (m_pythondictionary)
159         {
160                 PyDict_Clear(m_pythondictionary);
161                 Py_DECREF(m_pythondictionary);
162         }
163         m_pythondictionary = PyDict_Copy(pythondictionary); /* new reference */
164         
165         /* Without __file__ set the sys.argv[0] is used for the filename
166          * which ends up with lines from the blender binary being printed in the console */
167         PyDict_SetItemString(m_pythondictionary, "__file__", PyUnicode_From_STR_String(m_scriptName));
168         
169 }
170 #endif
171
172 int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
173 {
174         if (std::find(m_triggeredSensors.begin(), m_triggeredSensors.end(), sensor) != 
175                 m_triggeredSensors.end())
176                 return 1;
177         return 0;
178 }
179
180 #ifdef WITH_PYTHON
181
182 /* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */
183 PyObject* SCA_PythonController::sPyGetCurrentController(PyObject *self)
184 {
185         if (m_sCurrentController==NULL)
186         {
187                 PyErr_SetString(PyExc_SystemError, "bge.logic.getCurrentController(), this function is being run outside the python controllers context, or blenders internal state is corrupt.");
188                 return NULL;
189         }
190         return m_sCurrentController->GetProxy();
191 }
192
193 SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
194 {
195         // for safety, todo: only allow for registered actuators (pointertable)
196         // we don't want to crash gameengine/blender by python scripts
197         std::vector<SCA_IActuator*> lacts =  m_sCurrentController->GetLinkedActuators();
198         std::vector<SCA_IActuator*>::iterator it;
199         
200         if (PyUnicode_Check(value)) {
201                 /* get the actuator from the name */
202                 const char *name= _PyUnicode_AsString(value);
203                 for (it = lacts.begin(); it!= lacts.end(); ++it) {
204                         if ( name == (*it)->GetName() ) {
205                                 return *it;
206                         }
207                 }
208         }
209         else if (PyObject_TypeCheck(value, &SCA_IActuator::Type)) {
210                 PyObjectPlus *value_plus= BGE_PROXY_REF(value);
211                 for (it = lacts.begin(); it!= lacts.end(); ++it) {
212                         if (static_cast<SCA_IActuator*>(value_plus) == (*it)) {
213                                 return *it;
214                         }
215                 }
216         }
217
218         /* set the exception */
219         PyErr_Format(PyExc_ValueError,
220                      "%R not in this python controllers actuator list", value);
221
222         return NULL;
223 }
224
225 const char* SCA_PythonController::sPyGetCurrentController__doc__ = "getCurrentController()";
226
227 PyTypeObject SCA_PythonController::Type = {
228         PyVarObject_HEAD_INIT(NULL, 0)
229         "SCA_PythonController",
230         sizeof(PyObjectPlus_Proxy),
231         0,
232         py_base_dealloc,
233         0,
234         0,
235         0,
236         0,
237         py_base_repr,
238         0,0,0,0,0,0,0,0,0,
239         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
240         0,0,0,0,0,0,0,
241         Methods,
242         0,
243         0,
244         &SCA_IController::Type,
245         0,0,0,0,0,0,
246         py_base_new
247 };
248
249 PyMethodDef SCA_PythonController::Methods[] = {
250         {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O},
251         {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O},
252         {NULL,NULL} //Sentinel
253 };
254
255 PyAttributeDef SCA_PythonController::Attributes[] = {
256         KX_PYATTRIBUTE_RW_FUNCTION("script", SCA_PythonController, pyattr_get_script, pyattr_set_script),
257         KX_PYATTRIBUTE_INT_RO("mode", SCA_PythonController, m_mode),
258         { NULL }        //Sentinel
259 };
260
261 void SCA_PythonController::ErrorPrint(const char *error_msg)
262 {
263         printf("%s - object '%s', controller '%s':\n", error_msg, GetParent()->GetName().Ptr(), GetName().Ptr());
264         PyErr_Print();
265         
266         /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
267          * their user count. Not to mention holding references to wrapped data.
268          * This is especially bad when the PyObject for the wrapped data is freed, after blender
269          * has already dealocated the pointer */
270         PySys_SetObject( (char *)"last_traceback", NULL);
271         PyErr_Clear(); /* just to be sure */
272 }
273
274 bool SCA_PythonController::Compile()
275 {       
276         //printf("py script modified '%s'\n", m_scriptName.Ptr());
277         m_bModified= false;
278         
279         // if a script already exists, decref it before replace the pointer to a new script
280         if (m_bytecode) {
281                 Py_DECREF(m_bytecode);
282                 m_bytecode=NULL;
283         }
284         
285         // recompile the scripttext into bytecode
286         m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input);
287         
288         if (m_bytecode) {
289                 return true;
290         } else {
291                 ErrorPrint("Python error compiling script");
292                 return false;
293         }
294 }
295
296 bool SCA_PythonController::Import()
297 {
298         //printf("py module modified '%s'\n", m_scriptName.Ptr());
299         m_bModified= false;
300
301         /* in case we re-import */
302         Py_XDECREF(m_function);
303         m_function= NULL;
304         
305         STR_String mod_path_str= m_scriptText; /* just for storage, use C style string access */
306         char *mod_path= mod_path_str.Ptr();
307         char *function_string;
308
309         function_string= strrchr(mod_path, '.');
310
311         if (function_string == NULL) {
312                 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());
313                 return false;
314         }
315
316         *function_string= '\0';
317         function_string++;
318
319         // Import the module and print an error if it's not found
320         PyObject *mod = PyImport_ImportModule(mod_path);
321
322         if (mod == NULL) {
323                 ErrorPrint("Python module can't be imported");
324                 return false;
325         }
326
327         if (m_debug)
328                 mod = PyImport_ReloadModule(mod);
329
330         if (mod == NULL) {
331                 ErrorPrint("Python module can't be reloaded");
332                 return false;
333         }
334
335         // Get the function object
336         m_function = PyObject_GetAttrString(mod, function_string);
337
338         // DECREF the module as we don't need it anymore
339         Py_DECREF(mod);
340
341         if (m_function==NULL) {
342                 if (PyErr_Occurred())
343                         ErrorPrint("Python controller found the module but could not access the function");
344                 else
345                         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());
346                 return false;
347         }
348         
349         if (!PyCallable_Check(m_function)) {
350                 Py_DECREF(m_function);
351                 m_function = NULL;
352                 printf("Python module function error in object '%s', controller '%s':\n '%s' not callable\n", GetParent()->GetName().Ptr(), GetName().Ptr(), m_scriptText.Ptr());
353                 return false;
354         }
355         
356         m_function_argc = 0; /* rare cases this could be a function that isn't defined in python, assume zero args */
357         if (PyFunction_Check(m_function)) {
358                 m_function_argc= ((PyCodeObject *)PyFunction_GET_CODE(m_function))->co_argcount;
359         }
360         
361         if (m_function_argc > 1) {
362                 Py_DECREF(m_function);
363                 m_function = NULL;
364                 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);
365                 return false;
366         }
367         
368         return true;
369 }
370
371
372 void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
373 {
374         m_sCurrentController = this;
375         m_sCurrentLogicManager = logicmgr;
376         
377         PyObject *excdict=              NULL;
378         PyObject* resultobj=    NULL;
379         
380         switch(m_mode) {
381         case SCA_PYEXEC_SCRIPT:
382         {
383                 if (m_bModified)
384                         if (Compile()==false) // sets m_bModified to false
385                                 return;
386                 if (!m_bytecode)
387                         return;
388                 
389                 /*
390                  * This part here with excdict is a temporary patch
391                  * to avoid python/gameengine crashes when python
392                  * inadvertently holds references to game objects
393                  * in global variables.
394                  * 
395                  * The idea is always make a fresh dictionary, and
396                  * destroy it right after it is used to make sure
397                  * python won't hold any gameobject references.
398                  * 
399                  * Note that the PyDict_Clear _is_ necessary before
400                  * the Py_DECREF() because it is possible for the
401                  * variables inside the dictionary to hold references
402                  * to the dictionary (ie. generate a cycle), so we
403                  * break it by hand, then DECREF (which in this case
404                  * should always ensure excdict is cleared).
405                  */
406
407                 excdict= PyDict_Copy(m_pythondictionary);
408
409                 resultobj = PyEval_EvalCode((PyObject *)m_bytecode, excdict, excdict);
410
411                 /* PyRun_SimpleString(m_scriptText.Ptr()); */
412                 break;
413         }
414         case SCA_PYEXEC_MODULE:
415         {
416                 if (m_bModified || m_debug)
417                         if (Import()==false) // sets m_bModified to false
418                                 return;
419                 if (!m_function)
420                         return;
421                 
422                 PyObject *args= NULL;
423                 
424                 if (m_function_argc==1) {
425                         args = PyTuple_New(1);
426                         PyTuple_SET_ITEM(args, 0, GetProxy());
427                 }
428                 
429                 resultobj = PyObject_CallObject(m_function, args);
430                 Py_XDECREF(args);
431                 break;
432         }
433         
434         } /* end switch */
435         
436         
437         
438         /* Free the return value and print the error */
439         if (resultobj)
440                 Py_DECREF(resultobj);
441         else
442                 ErrorPrint("Python script error");
443         
444         if (excdict) /* Only for SCA_PYEXEC_SCRIPT types */
445         {
446                 /* clear after PyErrPrint - seems it can be using
447                  * something in this dictionary and crash? */
448                 // This doesn't appear to be needed anymore
449                 //PyDict_Clear(excdict);
450                 Py_DECREF(excdict);
451         }       
452         
453         m_triggeredSensors.clear();
454         m_sCurrentController = NULL;
455 }
456
457 PyObject* SCA_PythonController::PyActivate(PyObject *value)
458 {
459         if (m_sCurrentController != this) {
460                 PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller");
461                 return NULL;
462         }
463         
464         SCA_IActuator* actu = LinkedActuatorFromPy(value);
465         if (actu==NULL)
466                 return NULL;
467         
468         m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, true);
469         Py_RETURN_NONE;
470 }
471
472 PyObject* SCA_PythonController::PyDeActivate(PyObject *value)
473 {
474         if (m_sCurrentController != this) {
475                 PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller");
476                 return NULL;
477         }
478         
479         SCA_IActuator* actu = LinkedActuatorFromPy(value);
480         if (actu==NULL)
481                 return NULL;
482         
483         m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, false);
484         Py_RETURN_NONE;
485 }
486
487 PyObject* SCA_PythonController::pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
488 {
489         //SCA_PythonController* self= static_cast<SCA_PythonController*>(static_cast<SCA_IController*>(static_cast<SCA_ILogicBrick*>(static_cast<CValue*>(static_cast<PyObjectPlus*>(self_v)))));
490         // static_cast<void *>(dynamic_cast<Derived *>(obj)) - static_cast<void *>(obj)
491
492         SCA_PythonController* self= static_cast<SCA_PythonController*>(self_v);
493         return PyUnicode_From_STR_String(self->m_scriptText);
494 }
495
496
497
498 int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
499 {
500         SCA_PythonController* self= static_cast<SCA_PythonController*>(self_v);
501         
502         const char *scriptArg = _PyUnicode_AsString(value);
503         
504         if (scriptArg==NULL) {
505                 PyErr_SetString(PyExc_TypeError, "controller.script = string: Python Controller, expected a string script text");
506                 return PY_SET_ATTR_FAIL;
507         }
508
509         /* set scripttext sets m_bModified to true, 
510          * so next time the script is needed, a reparse into byte code is done */
511         self->SetScriptText(scriptArg);
512                 
513         return PY_SET_ATTR_SUCCESS;
514 }
515
516 #else // WITH_PYTHON
517
518 void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
519 {
520         /* intentionally blank */
521 }
522
523 #endif // WITH_PYTHON
524
525 /* eof */