Adonthell  0.4
python_class.cc
Go to the documentation of this file.
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 }