Adonthell 0.4
|
00001 /* 00002 $Id: python_class.cc,v 1.12 2005/04/17 11:35:12 ksterker Exp $ 00003 00004 Copyright (C) 2001 Kai Sterker <kaisterker@linuxgames.com> 00005 Part of the Adonthell Project http://adonthell.linuxgames.com 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License. 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY. 00011 00012 See the COPYING file for more details. 00013 */ 00014 00015 00016 /** 00017 * @file python_class.cc 00018 * @author Kai Sterker <kaisterker@linuxgames.com> 00019 * 00020 * @brief Declares the python class. 00021 * 00022 * 00023 */ 00024 00025 #include "python_class.h" 00026 #include "game.h" 00027 #include <iostream> 00028 00029 PyObject *data::globals; 00030 PyObject *python::module; 00031 00032 // defined in py_adonthell_wrap.cc 00033 PyObject *get_py_obj (void *instance, const char* class_name); 00034 00035 using namespace std; 00036 00037 /* 00038 * Start Python 00039 */ 00040 void python::init () 00041 { 00042 Py_Initialize (); 00043 } 00044 00045 /** 00046 * Stop Python 00047 */ 00048 void python::cleanup () 00049 { 00050 // Cleanup the global namespace of python interpreter 00051 // Note that we don't have to DECREF data::globals, because they're a 00052 // borrowed reference of py_module. 00053 Py_XDECREF (module); 00054 Py_Finalize (); 00055 } 00056 00057 /* 00058 * Insert a string into the module search path. 00059 */ 00060 void python::insert_path( char *name ) 00061 { 00062 char buf[256]; 00063 00064 sprintf ( buf, "import sys ; sys.path.insert(0, \"%s\")", name ); 00065 PyRun_SimpleString ( buf ); 00066 } 00067 00068 /* 00069 * Some convenience functions 00070 */ 00071 00072 /* 00073 * Executes the Python statements in the string 00074 */ 00075 void python::exec_string(char * s) 00076 { 00077 PyRun_SimpleString(s); 00078 } 00079 00080 /* 00081 * Execute the file given by 'filename' 00082 */ 00083 bool python::exec_file (string filename) 00084 { 00085 PyObject *mod = python::import_module (filename); 00086 00087 if (!mod) 00088 { 00089 cerr << "exec_file: " << filename << " load failed: " << endl; 00090 show_traceback (); 00091 00092 return false; 00093 } 00094 00095 Py_DECREF (mod); 00096 00097 return true; 00098 } 00099 00100 /* 00101 * Dump any error information to stderr 00102 */ 00103 void python::show_traceback(void) 00104 { 00105 if ( PyErr_Occurred() ) 00106 { 00107 PyErr_Print(); 00108 fflush (stderr); 00109 } 00110 } 00111 00112 /* Import a module, return module ptr */ 00113 PyObject *python::import_module (string filename) 00114 { 00115 PyObject *result = PyImport_ImportModule ((char *) filename.c_str ()); 00116 00117 #ifdef PY_DEBUG 00118 show_traceback (); 00119 #endif 00120 return result; 00121 } 00122 00123 // Make a C++ instance available to Python 00124 PyObject *python::pass_instance (void *instance, const char *class_name) 00125 { 00126 string class_ptr = string(class_name) + "*"; 00127 return get_py_obj (instance, class_ptr.c_str()); 00128 } 00129 00130 PyObject * python::get_tuple (igzstream & file) 00131 { 00132 PyObject * tuple; 00133 u_int32 l; 00134 l << file; 00135 00136 tuple = PyTuple_New (l); 00137 00138 for (u_int32 i = 0; i < l; i++) 00139 { 00140 string ms; 00141 u_int32 j; 00142 char c; 00143 00144 c << file; 00145 switch (c) 00146 { 00147 case 's': 00148 ms << file; 00149 // Stolen reference 00150 PyTuple_SetItem (tuple, i, PyString_FromString (ms.c_str ())); 00151 break; 00152 00153 case 'i': 00154 j << file; 00155 // Stolen reference 00156 PyTuple_SetItem (tuple, i, PyInt_FromLong (j)); 00157 break; 00158 } 00159 } 00160 return tuple; 00161 } 00162 00163 void python::put_tuple (PyObject * tuple, ogzstream & file) 00164 { 00165 u_int32 l = PyTuple_Size (tuple); 00166 l >> file; 00167 for (u_int32 i = 0; i < l; i++) 00168 { 00169 // Borrowed reference 00170 PyObject * item = PyTuple_GetItem (tuple, i); 00171 00172 // Check for the type of this object 00173 // String? 00174 if (PyString_Check (item)) 00175 { 00176 's' >> file; 00177 char * s = PyString_AsString (item); 00178 string (s) >> file; 00179 } 00180 00181 // Integer? 00182 else if (PyInt_Check (item)) 00183 { 00184 'i' >> file; 00185 u_int32 li = PyInt_AsLong (item); 00186 li >> file; 00187 } 00188 } 00189 }