[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / interfaces / python / swig.h
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include <Python.h>
23 #include <string>
24 #include <stdint.h>
25
26 #include "utils/StdString.h"
27 #include "interfaces/legacy/Exception.h"
28 #include "interfaces/legacy/AddonClass.h"
29 #include "interfaces/legacy/Window.h"
30
31 namespace PythonBindings
32 {
33   void PyXBMCGetUnicodeString(std::string& buf, PyObject* pObject, bool coerceToString = false,
34                               const char* pos = "unknown", 
35                               const char* methodname = "unknown") throw (XBMCAddon::WrongTypeException);
36
37   // This is for casting from child class to base class
38   struct TypeConverterBase
39   {
40     virtual void* convert(void* from) = 0;
41   };
42
43   /**
44    * Template to allow the instantiation of a particular type conversion
45    */
46   template<class T, class F> struct TypeConverter : public TypeConverterBase
47   {
48     inline virtual void* convert(void* from) { return static_cast<T*>((F*)from); }
49   };
50
51   struct TypeInfo
52   {
53     const char* swigType;
54     TypeInfo* parentType;
55     TypeConverterBase* converter;
56   };
57
58   // This will hold the pointer to the api type, whether known or unknown
59   struct PyHolder
60   { 
61     PyObject_HEAD
62     int32_t magicNumber;
63     const TypeInfo* typeInfo;
64     void* pSelf;
65   };
66
67 #define XBMC_PYTHON_TYPE_MAGIC_NUMBER 0x58626D63
68
69   void PyXBMCInitializeTypeObject(PyTypeObject* type_object, TypeInfo* typeInfo);
70
71   /**
72    * This method retrieves the pointer from the PyHolder. The return value should
73    * be case to the appropriate type.
74    *
75    * Since the calls to this are generated there's no NULL pointer checks
76    */
77   inline void* retrieveApiInstance(PyObject* pythonType, PyTypeObject* typeToCheck, 
78                                    const char* methodNameForErrorString, 
79                                    const char* typenameForErrorString) throw (XBMCAddon::WrongTypeException)
80   {
81     if (pythonType == NULL || ((PyHolder*)pythonType)->magicNumber != XBMC_PYTHON_TYPE_MAGIC_NUMBER)
82       return NULL;
83     if (!PyObject_TypeCheck(pythonType, typeToCheck))
84       throw XBMCAddon::WrongTypeException("Incorrect type passed to \"%s\", was expecting a \"%s\".",methodNameForErrorString,typenameForErrorString);
85     return ((PyHolder*)pythonType)->pSelf;
86   }
87
88   bool isParameterRightType(const char* passedType, const char* expectedType, const char* methodNamespacePrefix, bool tryReverse = true);
89
90   void* doretrieveApiInstance(const PyHolder* pythonType, const TypeInfo* typeInfo, const char* expectedType, 
91                               const char* methodNamespacePrefix, const char* methodNameForErrorString) throw (XBMCAddon::WrongTypeException);
92
93   /**
94    * This method retrieves the pointer from the PyHolder. The return value should
95    * be case to the appropriate type.
96    *
97    * Since the calls to this are generated there's no NULL pointer checks
98    */
99   inline void* retrieveApiInstance(const PyObject* pythonType, const char* expectedType, const char* methodNamespacePrefix,
100                                    const char* methodNameForErrorString) throw (XBMCAddon::WrongTypeException)
101   {
102     return (pythonType == NULL) ? NULL :
103       doretrieveApiInstance(((PyHolder*)pythonType),((PyHolder*)pythonType)->typeInfo, expectedType, methodNamespacePrefix, methodNameForErrorString);
104   }
105
106   /**
107    * This method is a helper for the generated API. It's called prior to any API
108    * class constructor being returned from the generated code to Python
109    */
110   void prepareForReturn(XBMCAddon::AddonClass* c);
111
112   /**
113    * This method is a helper for the generated API. It's called prior to any API
114    * class destructor being dealloc-ed from the generated code from Python
115    */
116   void cleanForDealloc(XBMCAddon::AddonClass* c);
117
118   /**
119    * This method is a helper for the generated API. It's called prior to any API
120    * class destructor being dealloc-ed from the generated code from Python
121    *
122    * There is a Catch-22 in the destruction of a Window. 'dispose' needs to be
123    * called on destruction but cannot be called from the destructor.
124    * This overrides the default cleanForDealloc to resolve that.
125    */
126   void cleanForDealloc(XBMCAddon::xbmcgui::Window* c);
127
128   /**
129    * This method allows for conversion of the native api Type to the Python type
130    *
131    * NOTE: swigTypeString must be in the data segment. That is, it should be an explicit string since
132    * the const char* is stored in a PyHolder struct and never deleted.
133    */
134   PyObject* makePythonInstance(void* api, PyTypeObject* typeObj, TypeInfo* typeInfo, bool incrementRefCount);
135
136   class Director
137   {
138   protected:
139     PyObject* self;
140   public:
141     inline Director() : self(NULL) {}
142     inline void setPyObjectForDirector(PyObject* pyargself) { self = pyargself; }
143   };
144
145   /**
146    * This exception is thrown from Director calls that call into python when the 
147    * Python error is 
148    */
149   class PythonToCppException : public XbmcCommons::UncheckedException
150   {
151   public:
152     /**
153      * Assuming a PyErr_Occurred, this will fill the exception message with all
154      *  of the appropriate information including the traceback if it can be
155      *  obtained. It will also clear the python message.
156      */
157     PythonToCppException();
158   };
159
160   template<class T> struct PythonCompare
161   {
162     static inline int compare(PyObject* obj1, PyObject* obj2, const char* swigType, const char* methodNamespacePrefix, const char* methodNameForErrorString)
163       throw(XBMCAddon::WrongTypeException)
164     {
165       TRACE;
166       try
167       {
168         T* o1 = (T*)retrieveApiInstance(obj1, swigType, methodNamespacePrefix, methodNameForErrorString);
169         T* o2 = (T*)retrieveApiInstance(obj2, swigType, methodNamespacePrefix, methodNameForErrorString);
170
171         return ((*o1) < (*o2) ? -1 : 
172                 ((*o1) > (*o2) ? 1 : 0));
173       }
174       catch (const XBMCAddon::WrongTypeException& e)
175       {
176         CLog::Log(LOGERROR,"EXCEPTION: %s",e.GetMessage());
177         PyErr_SetString(PyExc_RuntimeError, e.GetMessage());
178       }
179       return -1;
180     }
181   };
182 }