2.5 Python api
[blender.git] / source / blender / python / intern / bpy_interface.c
1
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include <Python.h>
6 #include "compile.h"            /* for the PyCodeObject */
7 #include "eval.h"               /* for PyEval_EvalCode */
8
9 #include "BKE_context.h"
10
11 #include "bpy_compat.h"
12
13 #include "bpy_rna.h"
14 #include "bpy_operator.h"
15 #include "bpy_ui.h"
16
17 #include "DNA_space_types.h"
18
19 #include "BKE_text.h"
20 #include "DNA_text_types.h"
21 #include "MEM_guardedalloc.h"
22
23 void BPY_free_compiled_text( struct Text *text )
24 {
25         if( text->compiled ) {
26                 Py_DECREF( ( PyObject * ) text->compiled );
27                 text->compiled = NULL;
28         }
29 }
30
31 /*****************************************************************************
32 * Description: This function creates a new Python dictionary object.
33 *****************************************************************************/
34
35 static PyObject *CreateGlobalDictionary( bContext *C )
36 {
37         PyObject *mod;
38         PyObject *dict = PyDict_New(  );
39         PyObject *item = PyUnicode_FromString( "__main__" );
40         PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
41         PyDict_SetItemString( dict, "__name__", item );
42         Py_DECREF(item);
43         
44         /* add bpy to global namespace */
45         mod = PyModule_New("bpy");
46         PyDict_SetItemString( dict, "bpy", mod );
47         Py_DECREF(mod);
48         
49         PyModule_AddObject( mod, "data", BPY_rna_module() );
50         /* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
51         PyModule_AddObject( mod, "types", BPY_rna_types() );
52         PyModule_AddObject( mod, "ops", BPY_operator_module(C) );
53         PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
54         
55         // XXX - evil, need to access context
56         item = PyCObject_FromVoidPtr( C, NULL );
57         PyDict_SetItemString( dict, "__bpy_context__", item );
58         Py_DECREF(item);
59         
60         return dict;
61 }
62
63 void BPY_start_python( void )
64 {
65         PyThreadState *py_tstate = NULL;
66
67         Py_Initialize(  );
68         
69         //PySys_SetArgv( argc_copy, argv_copy );
70         
71         /* Initialize thread support (also acquires lock) */
72         PyEval_InitThreads();
73         
74         // todo - sys paths - our own imports
75         
76         py_tstate = PyGILState_GetThisThreadState();
77         PyEval_ReleaseThread(py_tstate);
78         
79 }
80
81 void BPY_end_python( void )
82 {
83         PyGILState_Ensure(); /* finalizing, no need to grab the state */
84         
85         // free other python data.
86         //BPY_rna_free_types();
87         
88         Py_Finalize(  );
89         
90         return;
91 }
92
93 /* Can run a file or text block */
94 int BPY_run_python_script( bContext *C, const char *fn, struct Text *text )
95 {
96         PyObject *py_dict, *py_result;
97         PyGILState_STATE gilstate;
98         
99         if (fn==NULL && text==NULL) {
100                 return 0;
101         }
102         
103         //BPY_start_python();
104         
105         gilstate = PyGILState_Ensure();
106
107         py_dict = CreateGlobalDictionary(C);
108
109         if (text) {
110                 
111                 if( !text->compiled ) { /* if it wasn't already compiled, do it now */
112                         char *buf = txt_to_buf( text );
113
114                         text->compiled =
115                                 Py_CompileString( buf, text->id.name+2, Py_file_input );
116
117                         MEM_freeN( buf );
118
119                         if( PyErr_Occurred(  ) ) {
120                                 BPY_free_compiled_text( text );
121                                 return 0;
122                         }
123                 }
124                 py_result =  PyEval_EvalCode( text->compiled, py_dict, py_dict );
125                 
126         } else {
127                 char pystring[512];
128                 /* TODO - look into a better way to run a file */
129                 sprintf(pystring, "exec(open(r'%s').read())", fn);      
130                 py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );                  
131         }
132         
133         if (!py_result) {
134                 PyErr_Print();
135         } else {
136                 Py_DECREF( py_result );
137         }
138         PyGILState_Release(gilstate);
139         
140         //BPY_end_python();
141         return py_result ? 1:0;
142 }
143
144
145 /* TODO - move into bpy_space.c ? */
146 /* GUI interface routines */
147
148 /* Copied from Draw.c */
149 static void exit_pydraw( SpaceScript * sc, short err )
150 {
151         Script *script = NULL;
152
153         if( !sc || !sc->script )
154                 return;
155
156         script = sc->script;
157
158         if( err ) {
159                 PyErr_Print(  );
160                 script->flags = 0;      /* mark script struct for deletion */
161                 SCRIPT_SET_NULL(script);
162                 script->scriptname[0] = '\0';
163                 script->scriptarg[0] = '\0';
164 // XXX 2.5              error_pyscript();
165 // XXX 2.5              scrarea_queue_redraw( sc->area );
166         }
167
168 #if 0 // XXX 2.5
169         BPy_Set_DrawButtonsList(sc->but_refs);
170         BPy_Free_DrawButtonsList(); /*clear all temp button references*/
171 #endif
172
173         sc->but_refs = NULL;
174         
175         Py_XDECREF( ( PyObject * ) script->py_draw );
176         Py_XDECREF( ( PyObject * ) script->py_event );
177         Py_XDECREF( ( PyObject * ) script->py_button );
178
179         script->py_draw = script->py_event = script->py_button = NULL;
180 }
181
182 static int bpy_run_script_init(bContext *C, SpaceScript * sc)
183 {
184         if (sc->script==NULL) 
185                 return 0;
186         
187         if (sc->script->py_draw==NULL && sc->script->scriptname[0] != '\0')
188                 BPY_run_python_script(C, sc->script->scriptname, NULL);
189                 
190         if (sc->script->py_draw==NULL)
191                 return 0;
192         
193         return 1;
194 }
195
196 int BPY_run_script_space_draw(bContext *C, SpaceScript * sc)
197 {
198         if (bpy_run_script_init(C, sc)) {
199                 PyGILState_STATE gilstate = PyGILState_Ensure();
200                 PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
201                 
202                 if (result==NULL)
203                         exit_pydraw(sc, 1);
204                         
205                 PyGILState_Release(gilstate);
206         }
207         return 1;
208 }
209
210 // XXX - not used yet, listeners dont get a context
211 int BPY_run_script_space_listener(bContext *C, SpaceScript * sc)
212 {
213         if (bpy_run_script_init(C, sc)) {
214                 PyGILState_STATE gilstate = PyGILState_Ensure();
215                 
216                 PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
217                 
218                 if (result==NULL)
219                         exit_pydraw(sc, 1);
220                         
221                 PyGILState_Release(gilstate);
222         }
223         return 1;
224 }
225
226 #if 0
227 /* called from the the scripts window, assume context is ok */
228 int BPY_run_python_script_space(const char *modulename, const char *func)
229 {
230         PyObject *py_dict, *py_result= NULL;
231         char pystring[512];
232         PyGILState_STATE gilstate;
233         
234         /* for calling the module function */
235         PyObject *py_func, 
236         
237         gilstate = PyGILState_Ensure();
238         
239         py_dict = CreateGlobalDictionary(C);
240         
241         PyObject *module = PyImport_ImportModule(scpt->script.filename);
242         if (module==NULL) {
243                 PyErr_SetFormat(PyExc_SystemError, "could not import '%s'", scpt->script.filename);
244         }
245         else {
246                 py_func = PyObject_GetAttrString(modulename, func);
247                 if (py_func==NULL) {
248                         PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func);
249                 }
250                 else {
251                         if (!PyCallable_Check(py_func)) {
252                                 PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func);
253                         }
254                         else {
255                                 py_result= PyObject_CallObject(py_func, NULL); // XXX will need args eventually
256                         }
257                 }
258         }
259         
260         if (!py_result)
261                 PyErr_Print();
262         else
263                 Py_DECREF( py_result );
264         
265         Py_XDECREF(module);
266         
267         
268         PyGILState_Release(gilstate);
269         return 1;
270 }
271 #endif