Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
python_class.h
Go to the documentation of this file.
1 #ifndef __PYTHON_CLASS_H__
2 #define __PYTHON_CLASS_H__
3 //#define BOOST_PYTHON_NO_PY_SIGNATURES
4 #include "config.h"
5 //This takes care of the fact that several systems use the _POSIX_C_SOURCES
6 //variable and don't set them to the same thing.
7 //Python.h sets and uses it
8 #ifdef _POSIX_C_SOURCE
9 #undef _POSIX_C_SOURCE
10 #endif
11 #include "cs_python.h"
12 /*namespace boost{namespace python{
13 template <class T> struct type;
14 }}
15 #define DEC_FROM_PYTHON_SMART_POINTER(Pointer) \
16 class Pointer *from_python(PyObject *p,boost::python::type<class Pointer *>);
17 class Unit *from_python(PyObject *p,boost::python::type<class Unit *>);
18 //DEC_FROM_PYTHON_SMART_POINTER(Unit)
19 */
20 #include <boost/version.hpp>
21 #if BOOST_VERSION != 102800
22 #if defined (_MSC_VER) && _MSC_VER<=1200
23 #define Vector Vactor
24 #endif
25 #include "boost/python/object.hpp"
26 #include "boost/python/class.hpp"
27 #include "boost/python/call_method.hpp"
28 #include "cs_boostpython.h"
29 #if defined (_MSC_VER) && _MSC_VER<=1200
30 #undef Vector
31 #endif
32 #define class_builder class_
33 #else
34 #include "boost/python/objects.hpp"
35 #include "boost/python/class_builder.hpp"
36 #include "boost/python/detail/extension_class.hpp"
37 #endif
38 
39 #include "init.h"
41 #include <compile.h>
42 #include <eval.h>
43 #include "python/python_compile.h"
44 #include "cmd/ai/fire.h"
45 #include <memory>
46 #include "init.h"
47 #if BOOST_VERSION == 102800
48 #define PYTHONCALLBACK(rtype, ptr, str) \
49  boost::python::callback<rtype>::call_method(ptr, str)
50 #define PYTHONCALLBACK2(rtype, ptr, str, str2) \
51  boost::python::callback<rtype>::call_method(ptr, str, str2)
52 #else
53 #define PYTHONCALLBACK(rtype, ptr, str) \
54  boost::python::call_method<rtype>(ptr, str)
55 #define PYTHONCALLBACK2(rtype, ptr, str, str2) \
56  boost::python::call_method<rtype>(ptr, str, str2)
57 #endif
58 /*
59 These following #defines will create a module for python
60 call them with:
61 
62 PYTHON_BEGIN_MODULE(VS)
63  PYTHON_BEGIN_INHERIT_CLASS(VS,FireAt,"PythonFire") //begins an inherited class with a virtual Execute function...
64  //You can call any other virtual functions by defining:
65  // void callFunction(std::string name){}
66  //in your base class... To use it, use:
67  // MyClass->callFunction("Execute").
68  //That will do the same thing as:
69  // "MyClass->Execute()"
70  //
71  PYTHON_END_CLASS(VS,FireAt)
72  PYTHON_BEGIN_INHERIT_CLASS(VS,BaseClass,"PythonVirtualClassName")
73  PYTHON_END_CLASS(VS,BaseClass)
74  PYTHON_BASE_BEGIN_CLASS(VS,MyClass,"PythonClassName")
75  Class.def(boost::python::constructor<int,float,string>); //this will define a constructor that takes an int, float and a string.
76  Class.def(&MyClass::MyFunc,"FunctionName");
77  PYTHON_END_CLASS(VS,MyClass)
78  PYTHON_BEGIN_CLASS(VS,MyOtherClass,"DefaultConstructorPythonClassName") //this will automaticly define a default constructor
79  Class.def(&MyOtherClass::MyOtherFunc,"FunctionName");
80  PYTHON_END_CLASS(VS,MyOtherClass)
81  VS.def(&MyGlobalFunction,"GlobalFunc") //the global functions are easiest; you can call these in python with VS.globalfunc
82 PYTHON_END_MODULE(VS)
83 ...
84 int main (int argc,char *argv[]) {
85  ...
86  PYTHON_INIT_MODULE(VS);
87  ...
88  return 0;
89 }
90 
91 */
92 #define TO_PYTHON_SMART_POINTER(Pointer) \
93 BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE \
94 inline PyObject* to_python(class Pointer* x) {return boost::python::python_extension_class_converters<Pointer>::smart_ptr_to_python(x);} \
95 inline PyObject* to_python(const class Pointer* p) {return to_python(const_cast<class Pointer*>(p));} \
96 BOOST_PYTHON_END_CONVERSION_NAMESPACE
97 
98 // return from_python(p,boost::python::type<SuperClass &>());
99 // namespace boost{namespace python{
100 // }}
101 #define ADD_FROM_PYTHON_FUNCTION(SuperClass) \
102 BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE \
103  SuperClass & from_python(PyObject *obj,boost::python::type<SuperClass &>) { \
104  boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); \
105  typedef std::vector<boost::python::detail::instance_holder_base*>::const_iterator iterator; \
106  for (iterator p = self->wrapped_objects().begin(); \
107  p != self->wrapped_objects().end(); ++p) \
108  { \
109  boost::python::detail::instance_holder<SuperClass>* held = dynamic_cast<boost::python::detail::instance_holder<SuperClass>*>(*p); \
110  if (held != 0) \
111  return *held->target(); \
112  void* target = boost::python::detail::class_registry<SuperClass>::class_object()->try_class_conversions(*p); \
113  if(target) \
114  return *boost::python::detail::check_non_null(static_cast<SuperClass*>(target)); \
115  } \
116  boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry<SuperClass>::class_object(), typeid(SuperClass)); \
117  boost::python::throw_argument_error(); \
118  return *((SuperClass*)0); \
119  }BOOST_PYTHON_END_CONVERSION_NAMESPACE
120 
121 //non_null_from_python
122 #ifdef FROM_PYTHON_ERRORS
123 #define PYTHON_INIT_INHERIT_GLOBALS(name,SuperClass) template <> PythonClass <SuperClass> *PythonClass< SuperClass >::last_instance = NULL; \
124  ADD_FROM_PYTHON_FUNCTION(SuperClass)
125 #define PYTHON_INIT_GLOBALS(name,Class) ADD_FROM_PYTHON_FUNCTION(Class)
126 #else
127 #define PYTHON_INIT_INHERIT_GLOBALS(name,SuperClass) template <> PythonClass <SuperClass> *PythonClass< SuperClass >::last_instance = NULL;
128 #define PYTHON_INIT_GLOBALS(name,Class)
129 #endif
130 //These two functions purposely have opening/closing braces that don't match up
131 #if BOOST_VERSION != 102800
132 #define PYTHON_BEGIN_MODULE(name) BOOST_PYTHON_MODULE(name) {
133 #define PYTHON_DEFINE_GLOBAL(modul,fun,funname) boost::python::def (funname,fun)
134 #define VS_BOOST_MAKE_TUPLE(a,b,c) boost::python::make_tuple(a,b,c)
135 #define VS_BOOST_MAKE_TUPLE_2(a,b) boost::python::make_tuple(a,b)
136 #define VS_BOOST_MAKE_TUPLE_4(a,b,c,d) boost::python::make_tuple(a,b,c,d)
137 #else
138 #define PYTHON_BEGIN_MODULE(name) BOOST_PYTHON_MODULE_INIT(name) {boost::python::module_builder name(#name);
139 #define PYTHON_DEFINE_GLOBAL(modul,fun,funname) modul.def (fun,funname)
140 #define VS_BOOST_MAKE_TUPLE(a,b,c) boost::python::tuple(a,b,c)
141 #define VS_BOOST_MAKE_TUPLE_2(a,b) boost::python::tuple(a,b)
142 #define VS_BOOST_MAKE_TUPLE_4(a,b,c,d) boost::python::tuple(a,b,c,d)
143 #endif
144 #define PYTHON_END_MODULE(name) }
145 #define PYTHON_INIT_MODULE(name) init##name()
146 #if BOOST_VERSION != 102800
147 
148 #define PYTHON_BASE_BEGIN_INHERIT_CLASS(name,NewClass,SuperClass,myclass) { \
149 boost::python::class_builder <SuperClass, NewClass, boost::noncopyable > Class (myclass
150 #define PYTHON_BEGIN_INHERIT_CLASS(name,NewClass,SuperClass,myclass) PYTHON_BASE_BEGIN_INHERIT_CLASS(name,NewClass,SuperClass,myclass) \
151 );
152 
153 #define PYTHON_BASE_BEGIN_CLASS(name,CLASS,myclass) { \
154  boost::python::class_builder <CLASS> Class (myclass
155 #define PYTHON_BEGIN_CLASS(name,CLASS,myclass) PYTHON_BASE_BEGIN_CLASS(name,CLASS,myclass) \
156 );
157 #define PYTHON_DEFINE_METHOD(modul,fun,funname) modul.def (funname,fun)
158 #define PYTHON_DEFINE_METHOD_DEFAULT(modul,fun,funname,deflt) modul.def (funname,deflt)
159 #else
160 
161 #define PYTHON_BASE_BEGIN_INHERIT_CLASS(name,NewClass,SuperClass,myclass) { \
162  boost::python::class_builder <SuperClass ,NewClass> Class (name,myclass);
163 #define PYTHON_BEGIN_INHERIT_CLASS(name,NewClass,SuperClass,myclass) PYTHON_BASE_BEGIN_INHERIT_CLASS(name,NewClass,SuperClass,myclass) \
164  Class.def (boost::python::constructor<>());
165 
166 #define PYTHON_BASE_BEGIN_CLASS(name,CLASS,myclass) { \
167  boost::python::class_builder <CLASS> Class (name,myclass);
168 #define PYTHON_BEGIN_CLASS(name,CLASS,myclass) PYTHON_BASE_BEGIN_CLASS(name,CLASS,myclass) \
169  Class.def (boost::python::constructor<>());
170 #define PYTHON_DEFINE_METHOD(modul,fun,funname) modul.def (fun,funname)
171 #define PYTHON_DEFINE_METHOD_DEFAULT(modul,fun,funname,defaultfun) modul.def (fun,funname,defaultfun)
172 #endif
173 #define PYTHON_END_CLASS(name,SuperClass) }
174 /* BaseClass.def (&PythonClass<SuperClass>::IncRef,"IncRef"); \
175  boost::python::class_builder <SuperClass> TempClass (name,"SuperClass"); */
176 
177 
178 template <class SuperClass>
179 class PythonClass:public SuperClass
180 {
181  protected:
182  PyObject * self;
183  virtual void Destructor()
184  {
185  Py_XDECREF(self);
186  }
187  public:
189  PythonClass (PyObject * self_):SuperClass()
190  {
191  self = self_;
192  Py_XINCREF(self);
193  last_instance=this;
194  }
196  {
197  PythonClass * myclass = last_instance;
198  last_instance=NULL;
199  return myclass;
200  }
201  virtual void callFunction (std::string str)
202  {
203  PYTHONCALLBACK(void, self, str.c_str());
204  }
205  static PythonClass * Factory(const std::string &file)
206  {
207  CompileRunPython (file);
208  return LastPythonClass();
209  }
210  static PythonClass * FactoryString(char * code)
211  {
212  Python::reseterrors();
213  PyRun_SimpleString (code); //For some reason, PyRun_SimpleString() takes in a char *, not a const char *
214  Python::reseterrors();
215  return LastPythonClass();
216  }
217  virtual ~PythonClass()
218  {
219  fprintf (stderr,"Destruct called. If called from C++ this is death %ld (0x%lx)",(unsigned long)this,(unsigned long)this);
220  }
221 };
222 
223 template <class SuperClass>
224 class PythonAI: public PythonClass <SuperClass>
225 {
226 public:
227  PythonAI (PyObject * self_):PythonClass<SuperClass>(self_)
228  {
229  }
230  virtual void Execute ()
231  {
232  PYTHONCALLBACK(void, this->self, "Execute");
233  }
234  virtual void ChooseTarget ()
235  {
236  PYTHONCALLBACK(void, this->self, "ChooseTarget");
237  }
238  virtual void SetParent (Unit * parent)
239  {
240  SuperClass::SetParent (parent);
241  PYTHONCALLBACK2(void, this->self, "init", parent);
242  }
243  static void default_Execute(SuperClass & self_)
244  {
245  (self_).SuperClass::Execute();
246  }
247  static void default_ChooseTarget(SuperClass & self_)
248  {
249  (self_).SuperClass::ChooseTarget();
250  }
251  static void default_SetParent (SuperClass &self_, Unit * parent)
252  {
253  }
255  {
257  }
258  static PythonClass<SuperClass> * Factory (const std::string &file)
259  {
261  }
262  static PythonClass<SuperClass> * FactoryString (char *code)
263  {
265  }
266 };
267 
268 class pythonMission: public PythonClass <PythonMissionBaseClass>
269 {
270 public:
272  {
273  }
274  virtual void Execute ()
275  {
276  PYTHONCALLBACK(void, self, "Execute");
277  Python::reseterrors();
278  }
279  virtual std::string Pickle()
280  {
281  Python::reseterrors();
282  std::string ret=PYTHONCALLBACK(std::string, self, "Pickle");
283  Python::reseterrors();
284  return ret;
285  }
286  virtual void UnPickle(std::string s)
287  {
288  Python::reseterrors();
289  PYTHONCALLBACK2(void, self, "UnPickle",s);
290  Python::reseterrors();
291  }
293  {
295  }
296  static std::string default_Pickle(PythonMissionBaseClass & self_)
297  {
298  return (self_).PythonMissionBaseClass::Pickle();
299  }
300  static void default_UnPickle(PythonMissionBaseClass & self_, std::string str)
301  {
303  }
304  static PythonClass<PythonMissionBaseClass> * Factory (const std::string &file)
305  {
307  }
309  {
311  }
312 };
313 
314 #endif
315